Jedi Outcast Release v1.0

This commit is contained in:
James Monroe 2013-04-04 13:24:26 -05:00
parent b2f9cf6f08
commit a8c260f9e4
570 changed files with 99684 additions and 12936 deletions

3
CODE-mp/Default.SUP Normal file
View file

@ -0,0 +1,3 @@
//SUPPRESSIONPROJ:Default
//VERSION:5.00
//ENABLE:Yes

Binary file not shown.

Binary file not shown.

156
CODE-mp/Splines/Splines.dsp Normal file
View file

@ -0,0 +1,156 @@
# Microsoft Developer Studio Project File - Name="Splines" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=Splines - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Splines.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Splines.mak" CFG="Splines - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Splines - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "Splines - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/General/code/Splines", GAAAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Splines - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Splines - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "Splines - Win32 Release"
# Name "Splines - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\math_angles.cpp
# End Source File
# Begin Source File
SOURCE=.\math_matrix.cpp
# End Source File
# Begin Source File
SOURCE=.\math_quaternion.cpp
# End Source File
# Begin Source File
SOURCE=.\math_vector.cpp
# End Source File
# Begin Source File
SOURCE=.\q_parse.cpp
# End Source File
# Begin Source File
SOURCE=.\q_shared.cpp
# End Source File
# Begin Source File
SOURCE=.\splines.cpp
# End Source File
# Begin Source File
SOURCE=.\util_str.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\math_angles.h
# End Source File
# Begin Source File
SOURCE=.\math_matrix.h
# End Source File
# Begin Source File
SOURCE=.\math_quaternion.h
# End Source File
# Begin Source File
SOURCE=.\math_vector.h
# End Source File
# Begin Source File
SOURCE=.\q_shared.h
# End Source File
# Begin Source File
SOURCE=.\splines.h
# End Source File
# Begin Source File
SOURCE=.\util_list.h
# End Source File
# Begin Source File
SOURCE=.\util_str.h
# End Source File
# End Group
# End Target
# End Project

View file

@ -0,0 +1,129 @@
#include "q_shared.h"
#include <float.h>
angles_t ang_zero( 0.0f, 0.0f, 0.0f );
void toAngles( mat3_t &src, angles_t &dst ) {
double theta;
double cp;
double sp;
sp = src[ 0 ][ 2 ];
// cap off our sin value so that we don't get any NANs
if ( sp > 1.0 ) {
sp = 1.0;
} else if ( sp < -1.0 ) {
sp = -1.0;
}
theta = -asin( sp );
cp = cos( theta );
if ( cp > 8192 * FLT_EPSILON ) {
dst.pitch = theta * 180 / M_PI;
dst.yaw = atan2( src[ 0 ][ 1 ], src[ 0 ][ 0 ] ) * 180 / M_PI;
dst.roll = atan2( src[ 1 ][ 2 ], src[ 2 ][ 2 ] ) * 180 / M_PI;
} else {
dst.pitch = theta * 180 / M_PI;
dst.yaw = -atan2( src[ 1 ][ 0 ], src[ 1 ][ 1 ] ) * 180 / M_PI;
dst.roll = 0;
}
}
void toAngles( quat_t &src, angles_t &dst ) {
mat3_t temp;
toMatrix( src, temp );
toAngles( temp, dst );
}
void toAngles( idVec3_t &src, angles_t &dst ) {
dst.pitch = src[ 0 ];
dst.yaw = src[ 1 ];
dst.roll = src[ 2 ];
}
void angles_t::toVectors( idVec3_t *forward, idVec3_t *right, idVec3_t *up ) {
float angle;
static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs
angle = yaw * ( M_PI * 2 / 360 );
sy = sin( angle );
cy = cos( angle );
angle = pitch * ( M_PI * 2 / 360 );
sp = sin( angle );
cp = cos( angle );
angle = roll * ( M_PI * 2 / 360 );
sr = sin( angle );
cr = cos( angle );
if ( forward ) {
forward->set( cp * cy, cp * sy, -sp );
}
if ( right ) {
right->set( -sr * sp * cy + cr * sy, -sr * sp * sy + -cr * cy, -sr * cp );
}
if ( up ) {
up->set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp );
}
}
idVec3_t angles_t::toForward( void ) {
float angle;
static float sp, sy, cp, cy; // static to help MS compiler fp bugs
angle = yaw * ( M_PI * 2 / 360 );
sy = sin( angle );
cy = cos( angle );
angle = pitch * ( M_PI * 2 / 360 );
sp = sin( angle );
cp = cos( angle );
return idVec3_t( cp * cy, cp * sy, -sp );
}
/*
=================
Normalize360
returns angles normalized to the range [0 <= angle < 360]
=================
*/
angles_t& angles_t::Normalize360( void ) {
pitch = (360.0 / 65536) * ( ( int )( pitch * ( 65536 / 360.0 ) ) & 65535 );
yaw = (360.0 / 65536) * ( ( int )( yaw * ( 65536 / 360.0 ) ) & 65535 );
roll = (360.0 / 65536) * ( ( int )( roll * ( 65536 / 360.0 ) ) & 65535 );
return *this;
}
/*
=================
Normalize180
returns angles normalized to the range [-180 < angle <= 180]
=================
*/
angles_t& angles_t::Normalize180( void ) {
Normalize360();
if ( pitch > 180.0 ) {
pitch -= 360.0;
}
if ( yaw > 180.0 ) {
yaw -= 360.0;
}
if ( roll > 180.0 ) {
roll -= 360.0;
}
return *this;
}

View file

@ -0,0 +1,174 @@
#ifndef __MATH_ANGLES_H__
#define __MATH_ANGLES_H__
#include <stdlib.h>
#include <assert.h>
#include "math_vector.h"
class mat3_t;
class quat_t;
class idVec3_t;
typedef idVec3_t &vec3_p;
class angles_t {
public:
float pitch;
float yaw;
float roll;
angles_t();
angles_t( float pitch, float yaw, float roll );
angles_t( const idVec3_t &vec );
friend void toAngles( idVec3_t &src, angles_t &dst );
friend void toAngles( quat_t &src, angles_t &dst );
friend void toAngles( mat3_t &src, angles_t &dst );
operator vec3_p();
float operator[]( int index ) const;
float& operator[]( int index );
void set( float pitch, float yaw, float roll );
void operator=( angles_t const &a );
void operator=( idVec3_t const &a );
friend angles_t operator+( const angles_t &a, const angles_t &b );
angles_t &operator+=( angles_t const &a );
angles_t &operator+=( idVec3_t const &a );
friend angles_t operator-( angles_t &a, angles_t &b );
angles_t &operator-=( angles_t &a );
friend angles_t operator*( const angles_t &a, float b );
friend angles_t operator*( float a, const angles_t &b );
angles_t &operator*=( float a );
friend int operator==( angles_t &a, angles_t &b );
friend int operator!=( angles_t &a, angles_t &b );
void toVectors( idVec3_t *forward, idVec3_t *right = NULL, idVec3_t *up = NULL );
idVec3_t toForward( void );
angles_t &Zero( void );
angles_t &Normalize360( void );
angles_t &Normalize180( void );
};
extern angles_t ang_zero;
inline angles_t::angles_t() {}
inline angles_t::angles_t( float pitch, float yaw, float roll ) {
this->pitch = pitch;
this->yaw = yaw;
this->roll = roll;
}
inline angles_t::angles_t( const idVec3_t &vec ) {
this->pitch = vec.x;
this->yaw = vec.y;
this->roll = vec.z;
}
inline float angles_t::operator[]( int index ) const {
assert( ( index >= 0 ) && ( index < 3 ) );
return ( &pitch )[ index ];
}
inline float& angles_t::operator[]( int index ) {
assert( ( index >= 0 ) && ( index < 3 ) );
return ( &pitch )[ index ];
}
inline angles_t::operator vec3_p( void ) {
return *( idVec3_t * )&pitch;
}
inline void angles_t::set( float pitch, float yaw, float roll ) {
this->pitch = pitch;
this->yaw = yaw;
this->roll = roll;
}
inline void angles_t::operator=( angles_t const &a ) {
pitch = a.pitch;
yaw = a.yaw;
roll = a.roll;
}
inline void angles_t::operator=( idVec3_t const &a ) {
pitch = a[ 0 ];
yaw = a[ 1 ];
roll = a[ 2 ];
}
inline angles_t operator+( const angles_t &a, const angles_t &b ) {
return angles_t( a.pitch + b.pitch, a.yaw + b.yaw, a.roll + b.roll );
}
inline angles_t& angles_t::operator+=( angles_t const &a ) {
pitch += a.pitch;
yaw += a.yaw;
roll += a.roll;
return *this;
}
inline angles_t& angles_t::operator+=( idVec3_t const &a ) {
pitch += a.x;
yaw += a.y;
roll += a.z;
return *this;
}
inline angles_t operator-( angles_t &a, angles_t &b ) {
return angles_t( a.pitch - b.pitch, a.yaw - b.yaw, a.roll - b.roll );
}
inline angles_t& angles_t::operator-=( angles_t &a ) {
pitch -= a.pitch;
yaw -= a.yaw;
roll -= a.roll;
return *this;
}
inline angles_t operator*( const angles_t &a, float b ) {
return angles_t( a.pitch * b, a.yaw * b, a.roll * b );
}
inline angles_t operator*( float a, const angles_t &b ) {
return angles_t( a * b.pitch, a * b.yaw, a * b.roll );
}
inline angles_t& angles_t::operator*=( float a ) {
pitch *= a;
yaw *= a;
roll *= a;
return *this;
}
inline int operator==( angles_t &a, angles_t &b ) {
return ( ( a.pitch == b.pitch ) && ( a.yaw == b.yaw ) && ( a.roll == b.roll ) );
}
inline int operator!=( angles_t &a, angles_t &b ) {
return ( ( a.pitch != b.pitch ) || ( a.yaw != b.yaw ) || ( a.roll != b.roll ) );
}
inline angles_t& angles_t::Zero( void ) {
pitch = 0.0f;
yaw = 0.0f;
roll = 0.0f;
return *this;
}
#endif /* !__MATH_ANGLES_H__ */

View file

@ -0,0 +1,113 @@
#include "q_shared.h"
mat3_t mat3_default( idVec3_t( 1, 0, 0 ), idVec3_t( 0, 1, 0 ), idVec3_t( 0, 0, 1 ) );
void toMatrix( quat_t const &src, mat3_t &dst ) {
float wx, wy, wz;
float xx, yy, yz;
float xy, xz, zz;
float x2, y2, z2;
x2 = src.x + src.x;
y2 = src.y + src.y;
z2 = src.z + src.z;
xx = src.x * x2;
xy = src.x * y2;
xz = src.x * z2;
yy = src.y * y2;
yz = src.y * z2;
zz = src.z * z2;
wx = src.w * x2;
wy = src.w * y2;
wz = src.w * z2;
dst[ 0 ][ 0 ] = 1.0f - ( yy + zz );
dst[ 0 ][ 1 ] = xy - wz;
dst[ 0 ][ 2 ] = xz + wy;
dst[ 1 ][ 0 ] = xy + wz;
dst[ 1 ][ 1 ] = 1.0f - ( xx + zz );
dst[ 1 ][ 2 ] = yz - wx;
dst[ 2 ][ 0 ] = xz - wy;
dst[ 2 ][ 1 ] = yz + wx;
dst[ 2 ][ 2 ] = 1.0f - ( xx + yy );
}
void toMatrix( angles_t const &src, mat3_t &dst ) {
float angle;
static float sr, sp, sy, cr, cp, cy; // static to help MS compiler fp bugs
angle = src.yaw * ( M_PI * 2.0f / 360.0f );
sy = sin( angle );
cy = cos( angle );
angle = src.pitch * ( M_PI * 2.0f / 360.0f );
sp = sin( angle );
cp = cos( angle );
angle = src.roll * ( M_PI * 2.0f / 360.0f );
sr = sin( angle );
cr = cos( angle );
dst[ 0 ].set( cp * cy, cp * sy, -sp );
dst[ 1 ].set( sr * sp * cy + cr * -sy, sr * sp * sy + cr * cy, sr * cp );
dst[ 2 ].set( cr * sp * cy + -sr * -sy, cr * sp * sy + -sr * cy, cr * cp );
}
void toMatrix( idVec3_t const &src, mat3_t &dst ) {
angles_t sup = src;
toMatrix(sup, dst);
}
void mat3_t::ProjectVector( const idVec3_t &src, idVec3_t &dst ) const {
dst.x = src * mat[ 0 ];
dst.y = src * mat[ 1 ];
dst.z = src * mat[ 2 ];
}
void mat3_t::UnprojectVector( const idVec3_t &src, idVec3_t &dst ) const {
dst = mat[ 0 ] * src.x + mat[ 1 ] * src.y + mat[ 2 ] * src.z;
}
void mat3_t::Transpose( mat3_t &matrix ) {
int i;
int j;
for( i = 0; i < 3; i++ ) {
for( j = 0; j < 3; j++ ) {
matrix[ i ][ j ] = mat[ j ][ i ];
}
}
}
void mat3_t::Transpose( void ) {
float temp;
int i;
int j;
for( i = 0; i < 3; i++ ) {
for( j = i + 1; j < 3; j++ ) {
temp = mat[ i ][ j ];
mat[ i ][ j ] = mat[ j ][ i ];
mat[ j ][ i ] = temp;
}
}
}
mat3_t mat3_t::Inverse( void ) const {
mat3_t inv( *this );
inv.Transpose();
return inv;
}
void mat3_t::Clear( void ) {
mat[0].set( 1, 0, 0 );
mat[1].set( 0, 1, 0 );
mat[2].set( 0, 0, 1 );
}

View file

@ -0,0 +1,202 @@
#ifndef __MATH_MATRIX_H__
#define __MATH_MATRIX_H__
#include <string.h>
#include "math_vector.h"
#ifndef ID_INLINE
#ifdef _WIN32
#define ID_INLINE __inline
#else
#define ID_INLINE inline
#endif
#endif
class quat_t;
class angles_t;
class mat3_t {
public:
idVec3_t mat[ 3 ];
mat3_t();
mat3_t( float src[ 3 ][ 3 ] );
mat3_t( idVec3_t const &x, idVec3_t const &y, idVec3_t const &z );
mat3_t( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz );
friend void toMatrix( quat_t const &src, mat3_t &dst );
friend void toMatrix( angles_t const &src, mat3_t &dst );
friend void toMatrix( idVec3_t const &src, mat3_t &dst );
idVec3_t operator[]( int index ) const;
idVec3_t &operator[]( int index );
idVec3_t operator*( const idVec3_t &vec ) const;
mat3_t operator*( const mat3_t &a ) const;
mat3_t operator*( float a ) const;
mat3_t operator+( mat3_t const &a ) const;
mat3_t operator-( mat3_t const &a ) const;
friend idVec3_t operator*( const idVec3_t &vec, const mat3_t &mat );
friend mat3_t operator*( float a, mat3_t const &b );
mat3_t &operator*=( float a );
mat3_t &operator+=( mat3_t const &a );
mat3_t &operator-=( mat3_t const &a );
void Clear( void );
void ProjectVector( const idVec3_t &src, idVec3_t &dst ) const;
void UnprojectVector( const idVec3_t &src, idVec3_t &dst ) const;
void OrthoNormalize( void );
void Transpose( mat3_t &matrix );
void Transpose( void );
mat3_t Inverse( void ) const;
void Identity( void );
friend void InverseMultiply( const mat3_t &inv, const mat3_t &b, mat3_t &dst );
friend mat3_t SkewSymmetric( idVec3_t const &src );
};
ID_INLINE mat3_t::mat3_t() {
}
ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
memcpy( mat, src, sizeof( src ) );
}
ID_INLINE mat3_t::mat3_t( idVec3_t const &x, idVec3_t const &y, idVec3_t const &z ) {
mat[ 0 ].x = x.x; mat[ 0 ].y = x.y; mat[ 0 ].z = x.z;
mat[ 1 ].x = y.x; mat[ 1 ].y = y.y; mat[ 1 ].z = y.z;
mat[ 2 ].x = z.x; mat[ 2 ].y = z.y; mat[ 2 ].z = z.z;
}
ID_INLINE mat3_t::mat3_t( const float xx, const float xy, const float xz, const float yx, const float yy, const float yz, const float zx, const float zy, const float zz ) {
mat[ 0 ].x = xx; mat[ 0 ].y = xy; mat[ 0 ].z = xz;
mat[ 1 ].x = yx; mat[ 1 ].y = yy; mat[ 1 ].z = yz;
mat[ 2 ].x = zx; mat[ 2 ].y = zy; mat[ 2 ].z = zz;
}
ID_INLINE idVec3_t mat3_t::operator[]( int index ) const {
assert( ( index >= 0 ) && ( index < 3 ) );
return mat[ index ];
}
ID_INLINE idVec3_t& mat3_t::operator[]( int index ) {
assert( ( index >= 0 ) && ( index < 3 ) );
return mat[ index ];
}
ID_INLINE idVec3_t mat3_t::operator*( const idVec3_t &vec ) const {
return idVec3_t(
mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z,
mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z,
mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z );
}
ID_INLINE mat3_t mat3_t::operator*( const mat3_t &a ) const {
return mat3_t(
mat[0].x * a[0].x + mat[0].y * a[1].x + mat[0].z * a[2].x,
mat[0].x * a[0].y + mat[0].y * a[1].y + mat[0].z * a[2].y,
mat[0].x * a[0].z + mat[0].y * a[1].z + mat[0].z * a[2].z,
mat[1].x * a[0].x + mat[1].y * a[1].x + mat[1].z * a[2].x,
mat[1].x * a[0].y + mat[1].y * a[1].y + mat[1].z * a[2].y,
mat[1].x * a[0].z + mat[1].y * a[1].z + mat[1].z * a[2].z,
mat[2].x * a[0].x + mat[2].y * a[1].x + mat[2].z * a[2].x,
mat[2].x * a[0].y + mat[2].y * a[1].y + mat[2].z * a[2].y,
mat[2].x * a[0].z + mat[2].y * a[1].z + mat[2].z * a[2].z );
}
ID_INLINE mat3_t mat3_t::operator*( float a ) const {
return mat3_t(
mat[0].x * a, mat[0].y * a, mat[0].z * a,
mat[1].x * a, mat[1].y * a, mat[1].z * a,
mat[2].x * a, mat[2].y * a, mat[2].z * a );
}
ID_INLINE mat3_t mat3_t::operator+( mat3_t const &a ) const {
return mat3_t(
mat[0].x + a[0].x, mat[0].y + a[0].y, mat[0].z + a[0].z,
mat[1].x + a[1].x, mat[1].y + a[1].y, mat[1].z + a[1].z,
mat[2].x + a[2].x, mat[2].y + a[2].y, mat[2].z + a[2].z );
}
ID_INLINE mat3_t mat3_t::operator-( mat3_t const &a ) const {
return mat3_t(
mat[0].x - a[0].x, mat[0].y - a[0].y, mat[0].z - a[0].z,
mat[1].x - a[1].x, mat[1].y - a[1].y, mat[1].z - a[1].z,
mat[2].x - a[2].x, mat[2].y - a[2].y, mat[2].z - a[2].z );
}
ID_INLINE idVec3_t operator*( const idVec3_t &vec, const mat3_t &mat ) {
return idVec3_t(
mat[ 0 ].x * vec.x + mat[ 1 ].x * vec.y + mat[ 2 ].x * vec.z,
mat[ 0 ].y * vec.x + mat[ 1 ].y * vec.y + mat[ 2 ].y * vec.z,
mat[ 0 ].z * vec.x + mat[ 1 ].z * vec.y + mat[ 2 ].z * vec.z );
}
ID_INLINE mat3_t operator*( float a, mat3_t const &b ) {
return mat3_t(
b[0].x * a, b[0].y * a, b[0].z * a,
b[1].x * a, b[1].y * a, b[1].z * a,
b[2].x * a, b[2].y * a, b[2].z * a );
}
ID_INLINE mat3_t &mat3_t::operator*=( float a ) {
mat[0].x *= a; mat[0].y *= a; mat[0].z *= a;
mat[1].x *= a; mat[1].y *= a; mat[1].z *= a;
mat[2].x *= a; mat[2].y *= a; mat[2].z *= a;
return *this;
}
ID_INLINE mat3_t &mat3_t::operator+=( mat3_t const &a ) {
mat[0].x += a[0].x; mat[0].y += a[0].y; mat[0].z += a[0].z;
mat[1].x += a[1].x; mat[1].y += a[1].y; mat[1].z += a[1].z;
mat[2].x += a[2].x; mat[2].y += a[2].y; mat[2].z += a[2].z;
return *this;
}
ID_INLINE mat3_t &mat3_t::operator-=( mat3_t const &a ) {
mat[0].x -= a[0].x; mat[0].y -= a[0].y; mat[0].z -= a[0].z;
mat[1].x -= a[1].x; mat[1].y -= a[1].y; mat[1].z -= a[1].z;
mat[2].x -= a[2].x; mat[2].y -= a[2].y; mat[2].z -= a[2].z;
return *this;
}
ID_INLINE void mat3_t::OrthoNormalize( void ) {
mat[ 0 ].Normalize();
mat[ 2 ].Cross( mat[ 0 ], mat[ 1 ] );
mat[ 2 ].Normalize();
mat[ 1 ].Cross( mat[ 2 ], mat[ 0 ] );
mat[ 1 ].Normalize();
}
ID_INLINE void mat3_t::Identity( void ) {
mat[ 0 ].x = 1.f; mat[ 0 ].y = 0.f; mat[ 0 ].z = 0.f;
mat[ 1 ].x = 0.f; mat[ 1 ].y = 1.f; mat[ 1 ].z = 0.f;
mat[ 2 ].x = 0.f; mat[ 2 ].y = 0.f; mat[ 2 ].z = 1.f;
}
ID_INLINE void InverseMultiply( const mat3_t &inv, const mat3_t &b, mat3_t &dst ) {
dst[0].x = inv[0].x * b[0].x + inv[1].x * b[1].x + inv[2].x * b[2].x;
dst[0].y = inv[0].x * b[0].y + inv[1].x * b[1].y + inv[2].x * b[2].y;
dst[0].z = inv[0].x * b[0].z + inv[1].x * b[1].z + inv[2].x * b[2].z;
dst[1].x = inv[0].y * b[0].x + inv[1].y * b[1].x + inv[2].y * b[2].x;
dst[1].y = inv[0].y * b[0].y + inv[1].y * b[1].y + inv[2].y * b[2].y;
dst[1].z = inv[0].y * b[0].z + inv[1].y * b[1].z + inv[2].y * b[2].z;
dst[2].x = inv[0].z * b[0].x + inv[1].z * b[1].x + inv[2].z * b[2].x;
dst[2].y = inv[0].z * b[0].y + inv[1].z * b[1].y + inv[2].z * b[2].y;
dst[2].z = inv[0].z * b[0].z + inv[1].z * b[1].z + inv[2].z * b[2].z;
}
ID_INLINE mat3_t SkewSymmetric( idVec3_t const &src ) {
return mat3_t( 0.0f, -src.z, src.y, src.z, 0.0f, -src.x, -src.y, src.x, 0.0f );
}
extern mat3_t mat3_default;
#endif /* !__MATH_MATRIX_H__ */

View file

@ -0,0 +1,57 @@
#include "math_quaternion.h"
#include "math_matrix.h"
void toQuat( idVec3_t &src, quat_t &dst ) {
dst.x = src.x;
dst.y = src.y;
dst.z = src.z;
dst.w = 0.0f;
}
void toQuat( angles_t &src, quat_t &dst ) {
mat3_t temp;
toMatrix( src, temp );
toQuat( temp, dst );
}
void toQuat( mat3_t &src, quat_t &dst ) {
float trace;
float s;
int i;
int j;
int k;
static int next[ 3 ] = { 1, 2, 0 };
trace = src[ 0 ][ 0 ] + src[ 1 ][ 1 ] + src[ 2 ][ 2 ];
if ( trace > 0.0f ) {
s = ( float )sqrt( trace + 1.0f );
dst.w = s * 0.5f;
s = 0.5f / s;
dst.x = ( src[ 2 ][ 1 ] - src[ 1 ][ 2 ] ) * s;
dst.y = ( src[ 0 ][ 2 ] - src[ 2 ][ 0 ] ) * s;
dst.z = ( src[ 1 ][ 0 ] - src[ 0 ][ 1 ] ) * s;
} else {
i = 0;
if ( src[ 1 ][ 1 ] > src[ 0 ][ 0 ] ) {
i = 1;
}
if ( src[ 2 ][ 2 ] > src[ i ][ i ] ) {
i = 2;
}
j = next[ i ];
k = next[ j ];
s = ( float )sqrt( ( src[ i ][ i ] - ( src[ j ][ j ] + src[ k ][ k ] ) ) + 1.0f );
dst[ i ] = s * 0.5f;
s = 0.5f / s;
dst.w = ( src[ k ][ j ] - src[ j ][ k ] ) * s;
dst[ j ] = ( src[ j ][ i ] + src[ i ][ j ] ) * s;
dst[ k ] = ( src[ k ][ i ] + src[ i ][ k ] ) * s;
}
}

View file

@ -0,0 +1,169 @@
#ifndef __MATH_QUATERNION_H__
#define __MATH_QUATERNION_H__
#include <assert.h>
#include <math.h>
class idVec3_t;
class angles_t;
class mat3_t;
class quat_t {
public:
float x;
float y;
float z;
float w;
quat_t();
quat_t( float x, float y, float z, float w );
friend void toQuat( idVec3_t &src, quat_t &dst );
friend void toQuat( angles_t &src, quat_t &dst );
friend void toQuat( mat3_t &src, quat_t &dst );
float *vec4( void );
float operator[]( int index ) const;
float &operator[]( int index );
void set( float x, float y, float z, float w );
void operator=( quat_t a );
friend quat_t operator+( quat_t a, quat_t b );
quat_t &operator+=( quat_t a );
friend quat_t operator-( quat_t a, quat_t b );
quat_t &operator-=( quat_t a );
friend quat_t operator*( quat_t a, float b );
friend quat_t operator*( float a, quat_t b );
quat_t &operator*=( float a );
friend int operator==( quat_t a, quat_t b );
friend int operator!=( quat_t a, quat_t b );
float Length( void );
quat_t &Normalize( void );
quat_t operator-();
};
inline quat_t::quat_t() {
}
inline quat_t::quat_t( float x, float y, float z, float w ) {
this->x = x;
this->y = y;
this->z = z;
this->w = w;
}
inline float *quat_t::vec4( void ) {
return &x;
}
inline float quat_t::operator[]( int index ) const {
assert( ( index >= 0 ) && ( index < 4 ) );
return ( &x )[ index ];
}
inline float& quat_t::operator[]( int index ) {
assert( ( index >= 0 ) && ( index < 4 ) );
return ( &x )[ index ];
}
inline void quat_t::set( float x, float y, float z, float w ) {
this->x = x;
this->y = y;
this->z = z;
this->w = w;
}
inline void quat_t::operator=( quat_t a ) {
x = a.x;
y = a.y;
z = a.z;
w = a.w;
}
inline quat_t operator+( quat_t a, quat_t b ) {
return quat_t( a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w );
}
inline quat_t& quat_t::operator+=( quat_t a ) {
x += a.x;
y += a.y;
z += a.z;
w += a.w;
return *this;
}
inline quat_t operator-( quat_t a, quat_t b ) {
return quat_t( a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w );
}
inline quat_t& quat_t::operator-=( quat_t a ) {
x -= a.x;
y -= a.y;
z -= a.z;
w -= a.w;
return *this;
}
inline quat_t operator*( quat_t a, float b ) {
return quat_t( a.x * b, a.y * b, a.z * b, a.w * b );
}
inline quat_t operator*( float a, quat_t b ) {
return b * a;
}
inline quat_t& quat_t::operator*=( float a ) {
x *= a;
y *= a;
z *= a;
w *= a;
return *this;
}
inline int operator==( quat_t a, quat_t b ) {
return ( ( a.x == b.x ) && ( a.y == b.y ) && ( a.z == b.z ) && ( a.w == b.w ) );
}
inline int operator!=( quat_t a, quat_t b ) {
return ( ( a.x != b.x ) || ( a.y != b.y ) || ( a.z != b.z ) && ( a.w != b.w ) );
}
inline float quat_t::Length( void ) {
float length;
length = x * x + y * y + z * z + w * w;
return ( float )sqrt( length );
}
inline quat_t& quat_t::Normalize( void ) {
float length;
float ilength;
length = this->Length();
if ( length ) {
ilength = 1 / length;
x *= ilength;
y *= ilength;
z *= ilength;
w *= ilength;
}
return *this;
}
inline quat_t quat_t::operator-() {
return quat_t( -x, -y, -z, -w );
}
#endif /* !__MATH_QUATERNION_H__ */

View file

@ -0,0 +1,123 @@
//#include "../game/q_shared.h"
#include "math_vector.h"
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#define LERP_DELTA 1e-6
idVec3_t vec_zero( 0.0f, 0.0f, 0.0f );
Bounds boundsZero;
float idVec3_t::toYaw( void ) {
float yaw;
if ( ( y == 0 ) && ( x == 0 ) ) {
yaw = 0;
} else {
yaw = atan2( y, x ) * 180 / M_PI;
if ( yaw < 0 ) {
yaw += 360;
}
}
return yaw;
}
float idVec3_t::toPitch( void ) {
float forward;
float pitch;
if ( ( x == 0 ) && ( y == 0 ) ) {
if ( z > 0 ) {
pitch = 90;
} else {
pitch = 270;
}
} else {
forward = ( float )idSqrt( x * x + y * y );
pitch = atan2( z, forward ) * 180 / M_PI;
if ( pitch < 0 ) {
pitch += 360;
}
}
return pitch;
}
/*
angles_t idVec3_t::toAngles( void ) {
float forward;
float yaw;
float pitch;
if ( ( x == 0 ) && ( y == 0 ) ) {
yaw = 0;
if ( z > 0 ) {
pitch = 90;
} else {
pitch = 270;
}
} else {
yaw = atan2( y, x ) * 180 / M_PI;
if ( yaw < 0 ) {
yaw += 360;
}
forward = ( float )idSqrt( x * x + y * y );
pitch = atan2( z, forward ) * 180 / M_PI;
if ( pitch < 0 ) {
pitch += 360;
}
}
return angles_t( -pitch, yaw, 0 );
}
*/
idVec3_t LerpVector( idVec3_t &w1, idVec3_t &w2, const float t ) {
float omega, cosom, sinom, scale0, scale1;
cosom = w1 * w2;
if ( ( 1.0 - cosom ) > LERP_DELTA ) {
omega = acos( cosom );
sinom = sin( omega );
scale0 = sin( ( 1.0 - t ) * omega ) / sinom;
scale1 = sin( t * omega ) / sinom;
} else {
scale0 = 1.0 - t;
scale1 = t;
}
return ( w1 * scale0 + w2 * scale1 );
}
/*
=============
idVec3_t::string
This is just a convenience function
for printing vectors
=============
*/
char *idVec3_t::string( void ) {
static int index = 0;
static char str[ 8 ][ 36 ];
char *s;
// use an array so that multiple toString's won't collide
s = str[ index ];
index = (index + 1)&7;
sprintf( s, "%.2f %.2f %.2f", x, y, z );
return s;
}

View file

@ -0,0 +1,553 @@
#ifndef __MATH_VECTOR_H__
#define __MATH_VECTOR_H__
#if defined(_WIN32)
#pragma warning(disable : 4244)
#endif
#include <math.h>
#include <assert.h>
//#define DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[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 VectorCopy(a,b) ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z])
//#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))
//#define CrossProduct(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0])
#define DotProduct4(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]+(x)[3]*(y)[3])
#define VectorSubtract4(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 VectorAdd4(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 VectorCopy4(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
#define VectorScale4(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s),(o)[3]=(v)[3]*(s))
#define VectorMA4(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),(o)[3]=(v)[3]+(b)[3]*(s))
//#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 SnapVector(v) {v[0]=(int)v[0];v[1]=(int)v[1];v[2]=(int)v[2];}
//#include "util_heap.h"
#ifndef EQUAL_EPSILON
#define EQUAL_EPSILON 0.001
#endif
float Q_fabs( float f );
#ifndef ID_INLINE
#ifdef _WIN32
#define ID_INLINE __inline
#else
#define ID_INLINE inline
#endif
#endif
// if this is defined, vec3 will take four elements, which may allow
// easier SIMD optimizations
//#define FAT_VEC3
//#ifdef __ppc__
//#pragma align(16)
//#endif
class angles_t;
#ifdef __ppc__
// Vanilla PPC code, but since PPC has a reciprocal square root estimate instruction,
// runs *much* faster than calling sqrt(). We'll use two Newton-Raphson
// refinement steps to get bunch more precision in the 1/sqrt() value for very little cost.
// We'll then multiply 1/sqrt times the original value to get the sqrt.
// This is about 12.4 times faster than sqrt() and according to my testing (not exhaustive)
// it returns fairly accurate results (error below 1.0e-5 up to 100000.0 in 0.1 increments).
static inline float idSqrt(float x) {
const float half = 0.5;
const float one = 1.0;
float B, y0, y1;
// This'll NaN if it hits frsqrte. Handle both +0.0 and -0.0
if (fabs(x) == 0.0)
return x;
B = x;
#ifdef __GNUC__
asm("frsqrte %0,%1" : "=f" (y0) : "f" (B));
#else
y0 = __frsqrte(B);
#endif
/* First refinement step */
y1 = y0 + half*y0*(one - B*y0*y0);
/* Second refinement step -- copy the output of the last step to the input of this step */
y0 = y1;
y1 = y0 + half*y0*(one - B*y0*y0);
/* Get sqrt(x) from x * 1/sqrt(x) */
return x * y1;
}
#else
static inline double idSqrt(double x) {
return sqrt(x);
}
#endif
//class idVec3_t : public idHeap<idVec3_t> {
class idVec3_t {
public:
#ifndef FAT_VEC3
float x,y,z;
#else
float x,y,z,dist;
#endif
#ifndef FAT_VEC3
idVec3_t() {};
#else
idVec3_t() {dist = 0.0f;};
#endif
idVec3_t( const float x, const float y, const float z );
operator float *();
float operator[]( const int index ) const;
float &operator[]( const int index );
void set( const float x, const float y, const float z );
idVec3_t operator-() const;
idVec3_t &operator=( const idVec3_t &a );
float operator*( const idVec3_t &a ) const;
idVec3_t operator*( const float a ) const;
friend idVec3_t operator*( float a, idVec3_t b );
idVec3_t operator+( const idVec3_t &a ) const;
idVec3_t operator-( const idVec3_t &a ) const;
idVec3_t &operator+=( const idVec3_t &a );
idVec3_t &operator-=( const idVec3_t &a );
idVec3_t &operator*=( const float a );
int operator==( const idVec3_t &a ) const;
int operator!=( const idVec3_t &a ) const;
idVec3_t Cross( const idVec3_t &a ) const;
idVec3_t &Cross( const idVec3_t &a, const idVec3_t &b );
float Length( void ) const;
float Normalize( void );
void Zero( void );
void Snap( void );
void SnapTowards( const idVec3_t &to );
float toYaw( void );
float toPitch( void );
angles_t toAngles( void );
friend idVec3_t LerpVector( const idVec3_t &w1, const idVec3_t &w2, const float t );
char *string( void );
};
extern idVec3_t vec_zero;
ID_INLINE idVec3_t::idVec3_t( const float x, const float y, const float z ) {
this->x = x;
this->y = y;
this->z = z;
#ifdef FAT_VEC3
this->dist = 0.0f;
#endif
}
ID_INLINE float idVec3_t::operator[]( const int index ) const {
return ( &x )[ index ];
}
ID_INLINE float &idVec3_t::operator[]( const int index ) {
return ( &x )[ index ];
}
ID_INLINE idVec3_t::operator float *( void ) {
return &x;
}
ID_INLINE idVec3_t idVec3_t::operator-() const {
return idVec3_t( -x, -y, -z );
}
ID_INLINE idVec3_t &idVec3_t::operator=( const idVec3_t &a ) {
x = a.x;
y = a.y;
z = a.z;
return *this;
}
ID_INLINE void idVec3_t::set( const float x, const float y, const float z ) {
this->x = x;
this->y = y;
this->z = z;
}
ID_INLINE idVec3_t idVec3_t::operator-( const idVec3_t &a ) const {
return idVec3_t( x - a.x, y - a.y, z - a.z );
}
ID_INLINE float idVec3_t::operator*( const idVec3_t &a ) const {
return x * a.x + y * a.y + z * a.z;
}
ID_INLINE idVec3_t idVec3_t::operator*( const float a ) const {
return idVec3_t( x * a, y * a, z * a );
}
ID_INLINE idVec3_t operator*( const float a, const idVec3_t b ) {
return idVec3_t( b.x * a, b.y * a, b.z * a );
}
ID_INLINE idVec3_t idVec3_t::operator+( const idVec3_t &a ) const {
return idVec3_t( x + a.x, y + a.y, z + a.z );
}
ID_INLINE idVec3_t &idVec3_t::operator+=( const idVec3_t &a ) {
x += a.x;
y += a.y;
z += a.z;
return *this;
}
ID_INLINE idVec3_t &idVec3_t::operator-=( const idVec3_t &a ) {
x -= a.x;
y -= a.y;
z -= a.z;
return *this;
}
ID_INLINE idVec3_t &idVec3_t::operator*=( const float a ) {
x *= a;
y *= a;
z *= a;
return *this;
}
ID_INLINE int idVec3_t::operator==( const idVec3_t &a ) const {
if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) {
return false;
}
if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) {
return false;
}
if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) {
return false;
}
return true;
}
ID_INLINE int idVec3_t::operator!=( const idVec3_t &a ) const {
if ( Q_fabs( x - a.x ) > EQUAL_EPSILON ) {
return true;
}
if ( Q_fabs( y - a.y ) > EQUAL_EPSILON ) {
return true;
}
if ( Q_fabs( z - a.z ) > EQUAL_EPSILON ) {
return true;
}
return false;
}
ID_INLINE idVec3_t idVec3_t::Cross( const idVec3_t &a ) const {
return idVec3_t( y * a.z - z * a.y, z * a.x - x * a.z, x * a.y - y * a.x );
}
ID_INLINE idVec3_t &idVec3_t::Cross( const idVec3_t &a, const idVec3_t &b ) {
x = a.y * b.z - a.z * b.y;
y = a.z * b.x - a.x * b.z;
z = a.x * b.y - a.y * b.x;
return *this;
}
ID_INLINE float idVec3_t::Length( void ) const {
float length;
length = x * x + y * y + z * z;
return ( float )idSqrt( length );
}
ID_INLINE float idVec3_t::Normalize( void ) {
float length;
float ilength;
length = this->Length();
if ( length ) {
ilength = 1.0f / length;
x *= ilength;
y *= ilength;
z *= ilength;
}
return length;
}
ID_INLINE void idVec3_t::Zero( void ) {
x = 0.0f;
y = 0.0f;
z = 0.0f;
}
ID_INLINE void idVec3_t::Snap( void ) {
x = float( int( x ) );
y = float( int( y ) );
z = float( int( z ) );
}
/*
======================
SnapTowards
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.
======================
*/
ID_INLINE void idVec3_t::SnapTowards( const idVec3_t &to ) {
if ( to.x <= x ) {
x = float( int( x ) );
} else {
x = float( int( x ) + 1 );
}
if ( to.y <= y ) {
y = float( int( y ) );
} else {
y = float( int( y ) + 1 );
}
if ( to.z <= z ) {
z = float( int( z ) );
} else {
z = float( int( z ) + 1 );
}
}
//===============================================================
class Bounds {
public:
idVec3_t b[2];
Bounds();
Bounds( const idVec3_t &mins, const idVec3_t &maxs );
void Clear();
void Zero();
float Radius(); // radius from origin, not from center
idVec3_t Center();
void AddPoint( const idVec3_t &v );
void AddBounds( const Bounds &bb );
bool IsCleared();
bool ContainsPoint( const idVec3_t &p );
bool IntersectsBounds( const Bounds &b2 ); // touching is NOT intersecting
};
extern Bounds boundsZero;
ID_INLINE Bounds::Bounds(){
}
ID_INLINE bool Bounds::IsCleared() {
return b[0][0] > b[1][0];
}
ID_INLINE bool Bounds::ContainsPoint( const idVec3_t &p ) {
if ( p[0] < b[0][0] || p[1] < b[0][1] || p[2] < b[0][2]
|| p[0] > b[1][0] || p[1] > b[1][1] || p[2] > b[1][2] ) {
return false;
}
return true;
}
ID_INLINE bool Bounds::IntersectsBounds( const Bounds &b2 ) {
if ( b2.b[1][0] < b[0][0] || b2.b[1][1] < b[0][1] || b2.b[1][2] < b[0][2]
|| b2.b[0][0] > b[1][0] || b2.b[0][1] > b[1][1] || b2.b[0][2] > b[1][2] ) {
return false;
}
return true;
}
ID_INLINE Bounds::Bounds( const idVec3_t &mins, const idVec3_t &maxs ) {
b[0] = mins;
b[1] = maxs;
}
ID_INLINE idVec3_t Bounds::Center() {
return idVec3_t( ( b[1][0] + b[0][0] ) * 0.5f, ( b[1][1] + b[0][1] ) * 0.5f, ( b[1][2] + b[0][2] ) * 0.5f );
}
ID_INLINE void Bounds::Clear() {
b[0][0] = b[0][1] = b[0][2] = 99999;
b[1][0] = b[1][1] = b[1][2] = -99999;
}
ID_INLINE void Bounds::Zero() {
b[0][0] = b[0][1] = b[0][2] =
b[1][0] = b[1][1] = b[1][2] = 0;
}
ID_INLINE void Bounds::AddPoint( const idVec3_t &v ) {
if ( v[0] < b[0][0]) {
b[0][0] = v[0];
}
if ( v[0] > b[1][0]) {
b[1][0] = v[0];
}
if ( v[1] < b[0][1] ) {
b[0][1] = v[1];
}
if ( v[1] > b[1][1]) {
b[1][1] = v[1];
}
if ( v[2] < b[0][2] ) {
b[0][2] = v[2];
}
if ( v[2] > b[1][2]) {
b[1][2] = v[2];
}
}
ID_INLINE void Bounds::AddBounds( const Bounds &bb ) {
if ( bb.b[0][0] < b[0][0]) {
b[0][0] = bb.b[0][0];
}
if ( bb.b[0][1] < b[0][1]) {
b[0][1] = bb.b[0][1];
}
if ( bb.b[0][2] < b[0][2]) {
b[0][2] = bb.b[0][2];
}
if ( bb.b[1][0] > b[1][0]) {
b[1][0] = bb.b[1][0];
}
if ( bb.b[1][1] > b[1][1]) {
b[1][1] = bb.b[1][1];
}
if ( bb.b[1][2] > b[1][2]) {
b[1][2] = bb.b[1][2];
}
}
ID_INLINE float Bounds::Radius( ) {
int i;
float total;
float a, aa;
total = 0;
for (i=0 ; i<3 ; i++) {
a = (float)fabs( b[0][i] );
aa = (float)fabs( b[1][i] );
if ( aa > a ) {
a = aa;
}
total += a * a;
}
return (float)idSqrt( total );
}
//===============================================================
class idVec2_t {
public:
float x;
float y;
operator float *();
float operator[]( int index ) const;
float &operator[]( int index );
};
ID_INLINE float idVec2_t::operator[]( int index ) const {
return ( &x )[ index ];
}
ID_INLINE float& idVec2_t::operator[]( int index ) {
return ( &x )[ index ];
}
ID_INLINE idVec2_t::operator float *( void ) {
return &x;
}
class vec4_t : public idVec3_t {
public:
#ifndef FAT_VEC3
float dist;
#endif
vec4_t();
~vec4_t() {};
vec4_t( float x, float y, float z, float dist );
float operator[]( int index ) const;
float &operator[]( int index );
};
ID_INLINE vec4_t::vec4_t() {}
ID_INLINE vec4_t::vec4_t( float x, float y, float z, float dist ) {
this->x = x;
this->y = y;
this->z = z;
this->dist = dist;
}
ID_INLINE float vec4_t::operator[]( int index ) const {
return ( &x )[ index ];
}
ID_INLINE float& vec4_t::operator[]( int index ) {
return ( &x )[ index ];
}
class idVec5_t : public idVec3_t {
public:
float s;
float t;
float operator[]( int index ) const;
float &operator[]( int index );
};
ID_INLINE float idVec5_t::operator[]( int index ) const {
return ( &x )[ index ];
}
ID_INLINE float& idVec5_t::operator[]( int index ) {
return ( &x )[ index ];
}
#endif /* !__MATH_VECTOR_H__ */

View file

@ -0,0 +1,5 @@
SCC = This is a Source Code Control file
[Splines.dsp]
SCC_Aux_Path = "\\ravend\vss_projects\jk2sof2MP"
SCC_Project_Name = "$/General/code/Splines", GAAAAAAA

514
CODE-mp/Splines/q_parse.cpp Normal file
View file

@ -0,0 +1,514 @@
// q_parse.c -- support for parsing text files
#include "q_shared.h"
/*
============================================================================
PARSING
============================================================================
*/
// multiple character punctuation tokens
static const char *punctuation[] = {
"+=", "-=", "*=", "/=", "&=", "|=", "++", "--",
"&&", "||", "<=", ">=", "==", "!=",
NULL
};
typedef struct {
char token[MAX_TOKEN_CHARS];
int lines;
qboolean ungetToken;
char parseFile[MAX_QPATH];
} parseInfo_t;
#define MAX_PARSE_INFO 16
static parseInfo_t parseInfo[MAX_PARSE_INFO];
static int parseInfoNum;
static parseInfo_t *pi = &parseInfo[0];
/*
===================
Com_BeginParseSession
===================
*/
void Com_BeginParseSession( const char *filename ) {
if ( parseInfoNum == MAX_PARSE_INFO - 1 ) {
Com_Error( ERR_FATAL, "Com_BeginParseSession: session overflow" );
}
parseInfoNum++;
pi = &parseInfo[parseInfoNum];
pi->lines = 1;
Q_strncpyz( pi->parseFile, filename, sizeof( pi->parseFile ) );
}
/*
===================
Com_EndParseSession
===================
*/
void Com_EndParseSession( void ) {
if ( parseInfoNum == 0 ) {
Com_Error( ERR_FATAL, "Com_EndParseSession: session underflow" );
}
parseInfoNum--;
pi = &parseInfo[parseInfoNum];
}
/*
===================
Com_GetCurrentParseLine
===================
*/
int Com_GetCurrentParseLine( void ) {
return pi->lines;
}
/*
===================
Com_ScriptError
Prints the script name and line number in the message
===================
*/
void Com_ScriptError( const char *msg, ... ) {
va_list argptr;
char string[32000];
va_start( argptr, msg );
vsprintf( string, msg,argptr );
va_end( argptr );
Com_Error( ERR_DROP, "File %s, line %i: %s", pi->parseFile, pi->lines, string );
}
void Com_ScriptWarning( const char *msg, ... ) {
va_list argptr;
char string[32000];
va_start( argptr, msg );
vsprintf( string, msg,argptr );
va_end( argptr );
Com_Printf( "File %s, line %i: %s", pi->parseFile, pi->lines, string );
}
/*
===================
Com_UngetToken
Calling this will make the next Com_Parse return
the current token instead of advancing the pointer
===================
*/
void Com_UngetToken( void ) {
if ( pi->ungetToken ) {
Com_ScriptError( "UngetToken called twice" );
}
pi->ungetToken = qtrue;
}
static const char *SkipWhitespace( const char (*data), qboolean *hasNewLines ) {
int c;
while( (c = *data) <= ' ') {
if( !c ) {
return NULL;
}
if( c == '\n' ) {
pi->lines++;
*hasNewLines = qtrue;
}
data++;
}
return data;
}
/*
==============
Com_ParseExt
Parse a token out of a string
Will never return NULL, just empty strings.
An empty string will only be returned at end of file.
If "allowLineBreaks" is qtrue then an empty
string will be returned if the next token is
a newline.
==============
*/
static char *Com_ParseExt( const char *(*data_p), qboolean allowLineBreaks ) {
int c = 0, len;
qboolean hasNewLines = qfalse;
const char *data;
const char **punc;
if ( !data_p ) {
Com_Error( ERR_FATAL, "Com_ParseExt: NULL data_p" );
}
data = *data_p;
len = 0;
pi->token[0] = 0;
// make sure incoming data is valid
if ( !data ) {
*data_p = NULL;
return pi->token;
}
// skip any leading whitespace
while ( 1 ) {
// skip whitespace
data = SkipWhitespace( data, &hasNewLines );
if ( !data ) {
*data_p = NULL;
return pi->token;
}
if ( hasNewLines && !allowLineBreaks ) {
*data_p = data;
return pi->token;
}
c = *data;
// skip double slash comments
if ( c == '/' && data[1] == '/' ) {
while (*data && *data != '\n') {
data++;
}
continue;
}
// skip /* */ comments
if ( c=='/' && data[1] == '*' ) {
while ( *data && ( *data != '*' || data[1] != '/' ) ) {
if( *data == '\n' ) {
pi->lines++;
}
data++;
}
if ( *data ) {
data += 2;
}
continue;
}
// a real token to parse
break;
}
// handle quoted strings
if ( c == '\"' ) {
data++;
while( 1 ) {
c = *data++;
if ( ( c=='\\' ) && ( *data == '\"' ) ) {
// allow quoted strings to use \" to indicate the " character
data++;
} else if ( c=='\"' || !c ) {
pi->token[len] = 0;
*data_p = ( char * ) data;
return pi->token;
} else if( *data == '\n' ) {
pi->lines++;
}
if ( len < MAX_TOKEN_CHARS - 1 ) {
pi->token[len] = c;
len++;
}
}
}
// check for a number
// is this parsing of negative numbers going to cause expression problems
if ( ( c >= '0' && c <= '9' ) || ( c == '-' && data[ 1 ] >= '0' && data[ 1 ] <= '9' ) ||
( c == '.' && data[ 1 ] >= '0' && data[ 1 ] <= '9' ) ) {
do {
if (len < MAX_TOKEN_CHARS - 1) {
pi->token[len] = c;
len++;
}
data++;
c = *data;
} while ( ( c >= '0' && c <= '9' ) || c == '.' );
// parse the exponent
if ( c == 'e' || c == 'E' ) {
if (len < MAX_TOKEN_CHARS - 1) {
pi->token[len] = c;
len++;
}
data++;
c = *data;
if ( c == '-' || c == '+' ) {
if (len < MAX_TOKEN_CHARS - 1) {
pi->token[len] = c;
len++;
}
data++;
c = *data;
}
do {
if (len < MAX_TOKEN_CHARS - 1) {
pi->token[len] = c;
len++;
}
data++;
c = *data;
} while ( c >= '0' && c <= '9' );
}
if (len == MAX_TOKEN_CHARS) {
len = 0;
}
pi->token[len] = 0;
*data_p = ( char * ) data;
return pi->token;
}
// check for a regular word
// we still allow forward and back slashes in name tokens for pathnames
// and also colons for drive letters
if ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || c == '_' || c == '/' || c == '\\' ) {
do {
if (len < MAX_TOKEN_CHARS - 1) {
pi->token[len] = c;
len++;
}
data++;
c = *data;
} while ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) || c == '_'
|| ( c >= '0' && c <= '9' ) || c == '/' || c == '\\' || c == ':' || c == '.' );
if (len == MAX_TOKEN_CHARS) {
len = 0;
}
pi->token[len] = 0;
*data_p = ( char * ) data;
return pi->token;
}
// check for multi-character punctuation token
for ( punc = punctuation ; *punc ; punc++ ) {
int l;
int j;
l = strlen( *punc );
for ( j = 0 ; j < l ; j++ ) {
if ( data[j] != (*punc)[j] ) {
break;
}
}
if ( j == l ) {
// a valid multi-character punctuation
memcpy( pi->token, *punc, l );
pi->token[l] = 0;
data += l;
*data_p = (char *)data;
return pi->token;
}
}
// single character punctuation
pi->token[0] = *data;
pi->token[1] = 0;
data++;
*data_p = (char *)data;
return pi->token;
}
/*
===================
Com_Parse
===================
*/
const char *Com_Parse( const char *(*data_p) ) {
if ( pi->ungetToken ) {
pi->ungetToken = qfalse;
return pi->token;
}
return Com_ParseExt( data_p, qtrue );
}
/*
===================
Com_ParseOnLine
===================
*/
const char *Com_ParseOnLine( const char *(*data_p) ) {
if ( pi->ungetToken ) {
pi->ungetToken = qfalse;
return pi->token;
}
return Com_ParseExt( data_p, qfalse );
}
/*
==================
Com_MatchToken
==================
*/
void Com_MatchToken( const char *(*buf_p), const char *match, qboolean warning ) {
const char *token;
token = Com_Parse( buf_p );
if ( strcmp( token, match ) ) {
if (warning) {
Com_ScriptWarning( "MatchToken: %s != %s", token, match );
} else {
Com_ScriptError( "MatchToken: %s != %s", token, match );
}
}
}
/*
=================
Com_SkipBracedSection
The next token should be an open brace.
Skips until a matching close brace is found.
Internal brace depths are properly skipped.
=================
*/
void Com_SkipBracedSection( const char *(*program) ) {
const char *token;
int depth;
depth = 0;
do {
token = Com_Parse( program );
if( token[1] == 0 ) {
if( token[0] == '{' ) {
depth++;
}
else if( token[0] == '}' ) {
depth--;
}
}
} while( depth && *program );
}
/*
=================
Com_SkipRestOfLine
=================
*/
void Com_SkipRestOfLine ( const char *(*data) ) {
const char *p;
int c;
p = *data;
while ( (c = *p++) != 0 ) {
if ( c == '\n' ) {
pi->lines++;
break;
}
}
*data = p;
}
/*
====================
Com_ParseRestOfLine
====================
*/
const char *Com_ParseRestOfLine( const char *(*data_p) ) {
static char line[MAX_TOKEN_CHARS];
const char *token;
line[0] = 0;
while( 1 ) {
token = Com_ParseOnLine( data_p );
if ( !token[0] ) {
break;
}
if ( line[0] ) {
Q_strcat( line, sizeof(line), " " );
}
Q_strcat( line, sizeof(line), token );
}
return line;
}
float Com_ParseFloat( const char *(*buf_p) ) {
const char *token;
token = Com_Parse( buf_p );
if ( !token[0] ) {
return 0;
}
return atof( token );
}
int Com_ParseInt( const char *(*buf_p) ) {
const char *token;
token = Com_Parse( buf_p );
if ( !token[0] ) {
return 0;
}
return atoi( token );
}
void Com_Parse1DMatrix( const char *(*buf_p), int x, float *m ) {
const 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 Com_Parse2DMatrix( const char *(*buf_p), int y, int x, float *m ) {
int i;
Com_MatchToken( buf_p, "(" );
for (i = 0 ; i < y ; i++) {
Com_Parse1DMatrix (buf_p, x, m + i * x);
}
Com_MatchToken( buf_p, ")" );
}
void Com_Parse3DMatrix( const char *(*buf_p), int z, int y, int x, float *m ) {
int i;
Com_MatchToken( buf_p, "(" );
for (i = 0 ; i < z ; i++) {
Com_Parse2DMatrix (buf_p, y, x, m + i * x*y);
}
Com_MatchToken( buf_p, ")" );
}

View file

@ -0,0 +1,955 @@
// q_shared.c -- stateless support routines that are included in each code dll
#include "q_shared.h"
/*
============================================================================
GROWLISTS
============================================================================
*/
// malloc / free all in one place for debugging
extern "C" void *Com_Allocate( int bytes );
extern "C" void Com_Dealloc( void *ptr );
void Com_InitGrowList( growList_t *list, int maxElements ) {
list->maxElements = maxElements;
list->currentElements = 0;
list->elements = (void **)Com_Allocate( list->maxElements * sizeof( void * ) );
}
int Com_AddToGrowList( growList_t *list, void *data ) {
void **old;
if ( list->currentElements != list->maxElements ) {
list->elements[list->currentElements] = data;
return list->currentElements++;
}
// grow, reallocate and move
old = list->elements;
if ( list->maxElements < 0 ) {
Com_Error( ERR_FATAL, "Com_AddToGrowList: maxElements = %i", list->maxElements );
}
if ( list->maxElements == 0 ) {
// initialize the list to hold 100 elements
Com_InitGrowList( list, 100 );
return Com_AddToGrowList( list, data );
}
list->maxElements *= 2;
Com_DPrintf( "Resizing growlist to %i maxElements\n", list->maxElements );
list->elements = (void **)Com_Allocate( list->maxElements * sizeof( void * ) );
if ( !list->elements ) {
Com_Error( ERR_DROP, "Growlist alloc failed" );
}
memcpy( list->elements, old, list->currentElements * sizeof( void * ) );
Com_Dealloc( old );
return Com_AddToGrowList( list, data );
}
void *Com_GrowListElement( const growList_t *list, int index ) {
if ( index < 0 || index >= list->currentElements ) {
Com_Error( ERR_DROP, "Com_GrowListElement: %i out of range of %i",
index, list->currentElements );
}
return list->elements[index];
}
int Com_IndexForGrowListElement( const growList_t *list, const void *element ) {
int i;
for ( i = 0 ; i < list->currentElements ; i++ ) {
if ( list->elements[i] == element ) {
return i;
}
}
return -1;
}
//============================================================================
float Com_Clamp( float min, float max, float value ) {
if ( value < min ) {
return min;
}
if ( value > max ) {
return max;
}
return value;
}
/*
============
Com_StringContains
============
*/
const char *Com_StringContains( const char *str1, const char *str2, int casesensitive) {
int len, i, j;
len = strlen(str1) - strlen(str2);
for (i = 0; i <= len; i++, str1++) {
for (j = 0; str2[j]; j++) {
if (casesensitive) {
if (str1[j] != str2[j]) {
break;
}
}
else {
if (toupper(str1[j]) != toupper(str2[j])) {
break;
}
}
}
if (!str2[j]) {
return str1;
}
}
return NULL;
}
/*
============
Com_Filter
============
*/
int Com_Filter( const char *filter, const char *name, int casesensitive)
{
char buf[MAX_TOKEN_CHARS];
const char *ptr;
int i, found;
while(*filter) {
if (*filter == '*') {
filter++;
for (i = 0; *filter; i++) {
if (*filter == '*' || *filter == '?') break;
buf[i] = *filter;
filter++;
}
buf[i] = '\0';
if (strlen(buf)) {
ptr = Com_StringContains(name, buf, casesensitive);
if (!ptr) return qfalse;
name = ptr + strlen(buf);
}
}
else if (*filter == '?') {
filter++;
name++;
}
else if (*filter == '[' && *(filter+1) == '[') {
filter++;
}
else if (*filter == '[') {
filter++;
found = qfalse;
while(*filter && !found) {
if (*filter == ']' && *(filter+1) != ']') break;
if (*(filter+1) == '-' && *(filter+2) && (*(filter+2) != ']' || *(filter+3) == ']')) {
if (casesensitive) {
if (*name >= *filter && *name <= *(filter+2)) found = qtrue;
}
else {
if (toupper(*name) >= toupper(*filter) &&
toupper(*name) <= toupper(*(filter+2))) found = qtrue;
}
filter += 3;
}
else {
if (casesensitive) {
if (*filter == *name) found = qtrue;
}
else {
if (toupper(*filter) == toupper(*name)) found = qtrue;
}
filter++;
}
}
if (!found) return qfalse;
while(*filter) {
if (*filter == ']' && *(filter+1) != ']') break;
filter++;
}
filter++;
name++;
}
else {
if (casesensitive) {
if (*filter != *name) return qfalse;
}
else {
if (toupper(*filter) != toupper(*name)) return qfalse;
}
filter++;
name++;
}
}
return qtrue;
}
/*
================
Com_HashString
================
*/
int Com_HashString( const char *fname ) {
int i;
long hash;
char letter;
hash = 0;
i = 0;
while (fname[i] != '\0') {
letter = tolower(fname[i]);
if (letter =='.') break; // don't include extension
if (letter =='\\') letter = '/'; // damn path names
hash+=(long)(letter)*(i+119);
i++;
}
hash &= (FILE_HASH_SIZE-1);
return hash;
}
/*
============
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 float (*_BigFloat) (float l);
static float (*_LittleFloat) (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);}
float BigFloat (float l) {return _BigFloat(l);}
float LittleFloat (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;
}
float FloatSwap (float f)
{
union
{
float f;
byte b[4];
} dat1, dat2;
dat1.f = f;
dat2.b[0] = dat1.b[3];
dat2.b[1] = dat1.b[2];
dat2.b[2] = dat1.b[1];
dat2.b[3] = dat1.b[0];
return dat2.f;
}
float FloatNoSwap (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;
_BigFloat = FloatSwap;
_LittleFloat = FloatNoSwap;
}
else
{
_BigShort = ShortNoSwap;
_LittleShort = ShortSwap;
_BigLong = LongNoSwap;
_LittleLong = LongSwap;
_BigFloat = FloatNoSwap;
_LittleFloat = FloatSwap;
}
}
/*
===============
Com_ParseInfos
===============
*/
int Com_ParseInfos( const char *buf, int max, char infos[][MAX_INFO_STRING] ) {
const 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_Parse( &buf );
if ( !token[0] ) {
Com_Printf( "Unexpected end of info file\n" );
break;
}
if ( !strcmp( token, "}" ) ) {
break;
}
Q_strncpyz( key, token, sizeof( key ) );
token = Com_ParseOnLine( &buf );
if ( !token[0] ) {
token = "<NULL>";
}
Info_SetValueForKey( infos[count], key, token );
}
count++;
}
return count;
}
/*
============================================================================
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 ) {
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;
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 Q_stricmpn (s1, s2, 99999);
}
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);
}
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[MAX_INFO_KEY];
static char value[2][MAX_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 ) >= MAX_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[MAX_INFO_KEY], char value[MAX_INFO_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_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 (s, newi);
}
//====================================================================
/*
===============
ParseHex
===============
*/
int ParseHex( const char *text ) {
int value;
int c;
value = 0;
while ( ( c = *text++ ) != 0 ) {
if ( c >= '0' && c <= '9' ) {
value = value * 16 + c - '0';
continue;
}
if ( c >= 'a' && c <= 'f' ) {
value = value * 16 + 10 + c - 'a';
continue;
}
if ( c >= 'A' && c <= 'F' ) {
value = value * 16 + 10 + c - 'A';
continue;
}
}
return value;
}

789
CODE-mp/Splines/q_shared.h Normal file
View file

@ -0,0 +1,789 @@
#ifndef __Q_SHARED_H
#define __Q_SHARED_H
// q_shared.h -- included first by ALL program modules.
// these are the definitions that have no dependance on
// central system services, and can be used by any part
// of the program without any state issues.
// A user mod should never modify this file
// incursion of DOOM code into the Q3A codebase
//#define Q3_VERSION "DOOM 0.01"
// alignment macros for SIMD
#define ALIGN_ON
#define ALIGN_OFF
#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 : 4201)
#pragma warning(disable : 4214)
#pragma warning(disable : 4244)
#pragma warning(disable : 4305) // truncation from const double to float
#pragma warning(disable : 4310) // cast truncates constant value
#pragma warning(disable : 4514)
#pragma warning(disable : 4711) // selected for automatic inline expansion
#pragma warning(disable : 4220) // varargs matches remaining parameters
#endif
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#ifdef WIN32 // mac doesn't have malloc.h
#include <malloc.h> // for _alloca()
#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
// for windows fastcall option
#define QDECL
//======================= 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 PATH_SEP '\\'
#endif
//======================= MAC OS X SERVER DEFINES =====================
#if defined(__MACH__) && defined(__APPLE__)
#define MAC_STATIC
#ifdef __ppc__
#define CPUSTRING "MacOSXS-ppc"
#elif defined __i386__
#define CPUSTRING "MacOSXS-i386"
#else
#define CPUSTRING "MacOSXS-other"
#endif
#define PATH_SEP '/'
#define GAME_HARD_LINKED
#define CGAME_HARD_LINKED
#define UI_HARD_LINKED
#define _alloca alloca
#undef ALIGN_ON
#undef ALIGN_OFF
#define ALIGN_ON #pragma align(16)
#define ALIGN_OFF #pragma align()
#ifdef __cplusplus
extern "C" {
#endif
void *osxAllocateMemory(long size);
void osxFreeMemory(void *pointer);
#ifdef __cplusplus
}
#endif
#endif
//======================= MAC DEFINES =================================
#ifdef __MACOS__
#define MAC_STATIC static
#define CPUSTRING "MacOS-PPC"
#define PATH_SEP ':'
void Sys_PumpEvents( void );
#endif
#ifdef __MRC__
#define MAC_STATIC
#define CPUSTRING "MacOS-PPC"
#define PATH_SEP ':'
void Sys_PumpEvents( void );
#undef QDECL
#define QDECL __cdecl
#define _alloca alloca
#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
#ifdef __i386__
#define CPUSTRING "linux-i386"
#elif defined __axp__
#define CPUSTRING "linux-alpha"
#else
#define CPUSTRING "linux-other"
#endif
#define PATH_SEP '/'
// bk001205 - try
#ifdef Q3_STATIC
#define GAME_HARD_LINKED
#define CGAME_HARD_LINKED
#define UI_HARD_LINKED
#define BOTLIB_HARD_LINKED
#endif
#endif
//=============================================================
typedef enum {qfalse, qtrue} qboolean;
typedef unsigned char byte;
#define EQUAL_EPSILON 0.001
typedef int qhandle_t;
typedef int sfxHandle_t;
typedef int fileHandle_t;
typedef int clipHandle_t;
typedef enum {
INVALID_JOINT = -1
} jointHandle_t;
#ifndef NULL
#define NULL ((void *)0)
#endif
#define MAX_QINT 0x7fffffff
#define MIN_QINT (-MAX_QINT-1)
#ifndef max
#define max( x, y ) ( ( ( x ) > ( y ) ) ? ( x ) : ( y ) )
#define min( x, y ) ( ( ( x ) < ( y ) ) ? ( x ) : ( y ) )
#endif
#ifndef sign
#define sign( f ) ( ( f > 0 ) ? 1 : ( ( f < 0 ) ? -1 : 0 ) )
#endif
// 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 256 // 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 MAX_QPATH 64 // max length of a quake game pathname
#define MAX_OSPATH 128 // max length of a filesystem pathname
#define MAX_NAME_LENGTH 32 // max length of a client name
// 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
#undef ERR_FATAL // malloc.h on unix
// parameters to the main Error routine
typedef enum {
ERR_NONE,
ERR_FATAL, // exit the entire game with a popup window
ERR_DROP, // print to console and disconnect from game
ERR_DISCONNECT, // don't kill 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
/*
==============================================================
MATHLIB
==============================================================
*/
#ifdef __cplusplus // so we can include this in C code
#define SIDE_FRONT 0
#define SIDE_BACK 1
#define SIDE_ON 2
#define SIDE_CROSS 3
#define Q_PI 3.14159265358979323846
#ifndef M_PI
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif
#include "math_vector.h"
#include "math_angles.h"
#include "math_matrix.h"
#include "math_quaternion.h"
class idVec3_t; // for defining vectors
typedef idVec3_t &vec3_p; // for passing vectors as function arguments
typedef const idVec3_t &vec3_c; // for passing vectors as const function arguments
class angles_t; // for defining angle vectors
typedef angles_t &angles_p; // for passing angles as function arguments
typedef const angles_t &angles_c; // for passing angles as const function arguments
class mat3_t; // for defining matrices
typedef mat3_t &mat3_p; // for passing matrices as function arguments
typedef const mat3_t &mat3_c; // for passing matrices as const function arguments
#define NUMVERTEXNORMALS 162
extern idVec3_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 idVec3_t vec3_origin;
extern vec4_t vec4_origin;
extern mat3_t axisDefault;
#define nanmask (255<<23)
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
float Q_fabs( float f );
float Q_rsqrt( float f ); // reciprocal square root
#define SQRTFAST( x ) ( 1.0f / Q_rsqrt( x ) )
signed char ClampChar( int i );
signed short ClampShort( int i );
// this isn't a real cheap function to call!
int DirToByte( const idVec3_t &dir );
void ByteToDir( int b, vec3_p dir );
#define DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[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 VectorCopy(a,b) ((b).x=(a).x,(b).y=(a).y,(b).z=(a).z])
#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))
#define CrossProduct(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0])
#define DotProduct4(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]+(x)[3]*(y)[3])
#define VectorSubtract4(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 VectorAdd4(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 VectorCopy4(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
#define VectorScale4(v, s, o) ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s),(o)[3]=(v)[3]*(s))
#define VectorMA4(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),(o)[3]=(v)[3]+(b)[3]*(s))
#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 SnapVector(v) {v[0]=(int)v[0];v[1]=(int)v[1];v[2]=(int)v[2];}
float NormalizeColor( vec3_c in, vec3_p out );
int VectorCompare( vec3_c v1, vec3_c v2 );
float VectorLength( vec3_c v );
float Distance( vec3_c p1, vec3_c p2 );
float DistanceSquared( vec3_c p1, vec3_c p2 );
float VectorNormalize (vec3_p v); // returns vector length
void VectorNormalizeFast(vec3_p v); // does NOT return vector length, uses rsqrt approximation
float VectorNormalize2( vec3_c v, vec3_p out );
void VectorInverse (vec3_p v);
void VectorRotate( vec3_c in, mat3_c matrix, vec3_p out );
void VectorPolar(vec3_p v, float radius, float theta, float phi);
void VectorSnap(vec3_p v);
void Vector53Copy( const idVec5_t &in, vec3_p out);
void Vector5Scale( const idVec5_t &v, float scale, idVec5_t &out);
void Vector5Add( const idVec5_t &va, const idVec5_t &vb, idVec5_t &out);
void VectorRotate3( vec3_c vIn, vec3_c vRotation, vec3_p out);
void VectorRotate3Origin(vec3_c vIn, vec3_c vRotation, vec3_c vOrigin, vec3_p out);
int Q_log2(int val);
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))
float Q_rint( float in );
void vectoangles( vec3_c value1, angles_p angles);
void AnglesToAxis( angles_c angles, mat3_p axis );
void AxisCopy( mat3_c in, mat3_p out );
qboolean AxisRotated( mat3_c in ); // assumes a non-degenerate axis
int SignbitsForNormal( vec3_c normal );
int BoxOnPlaneSide( const Bounds &b, struct cplane_s *p );
float AngleMod(float a);
float LerpAngle (float from, float to, float frac);
float AngleSubtract( float a1, float a2 );
void AnglesSubtract( angles_c v1, angles_c v2, angles_p v3 );
float AngleNormalize360 ( float angle );
float AngleNormalize180 ( float angle );
float AngleDelta ( float angle1, float angle2 );
qboolean PlaneFromPoints( vec4_t &plane, vec3_c a, vec3_c b, vec3_c c );
void ProjectPointOnPlane( vec3_p dst, vec3_c p, vec3_c normal );
void RotatePointAroundVector( vec3_p dst, vec3_c dir, vec3_c point, float degrees );
void RotateAroundDirection( mat3_p axis, float yaw );
void MakeNormalVectors( vec3_c forward, vec3_p right, vec3_p up );
// perpendicular vector could be replaced by this
int PlaneTypeForNormal( vec3_c normal );
void MatrixMultiply( mat3_c in1, mat3_c in2, mat3_p out );
void MatrixInverseMultiply( mat3_c in1, mat3_c in2, mat3_p out ); // in2 is transposed during multiply
void MatrixTransformVector( vec3_c in, mat3_c matrix, vec3_p out );
void MatrixProjectVector( vec3_c in, mat3_c matrix, vec3_p out ); // Places the vector into a new coordinate system.
void AngleVectors( angles_c angles, vec3_p forward, vec3_p right, vec3_p up);
void PerpendicularVector( vec3_p dst, vec3_c src );
float TriangleArea( vec3_c a, vec3_c b, vec3_c c );
#endif // __cplusplus
//=============================================
float Com_Clamp( float min, float max, float value );
#define FILE_HASH_SIZE 1024
int Com_HashString( const char *fname );
char *Com_SkipPath( char *pathname );
// it is ok for out == in
void Com_StripExtension( const char *in, char *out );
// "extension" should include the dot: ".map"
void Com_DefaultExtension( char *path, int maxSize, const char *extension );
int Com_ParseInfos( const char *buf, int max, char infos[][MAX_INFO_STRING] );
/*
=====================================================================================
SCRIPT PARSING
=====================================================================================
*/
// this just controls the comment printing, it doesn't actually load a file
void Com_BeginParseSession( const char *filename );
void Com_EndParseSession( void );
int Com_GetCurrentParseLine( void );
// Will never return NULL, just empty strings.
// An empty string will only be returned at end of file.
// ParseOnLine will return empty if there isn't another token on this line
// this funny typedef just means a moving pointer into a const char * buffer
const char *Com_Parse( const char *(*data_p) );
const char *Com_ParseOnLine( const char *(*data_p) );
const char *Com_ParseRestOfLine( const char *(*data_p) );
void Com_UngetToken( void );
#ifdef __cplusplus
void Com_MatchToken( const char *(*buf_p), const char *match, qboolean warning = qfalse );
#else
void Com_MatchToken( const char *(*buf_p), const char *match, qboolean warning );
#endif
void Com_ScriptError( const char *msg, ... );
void Com_ScriptWarning( const char *msg, ... );
void Com_SkipBracedSection( const char *(*program) );
void Com_SkipRestOfLine( const char *(*data) );
float Com_ParseFloat( const char *(*buf_p) );
int Com_ParseInt( const char *(*buf_p) );
void Com_Parse1DMatrix( const char *(*buf_p), int x, float *m );
void Com_Parse2DMatrix( const char *(*buf_p), int y, int x, float *m );
void Com_Parse3DMatrix( const char *(*buf_p), int z, int y, int x, float *m );
//=====================================================================================
#ifdef __cplusplus
extern "C" {
#endif
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 );
int Com_Filter( const char *filter, const char *name, int casesensitive );
const char *Com_StringContains( const char *str1, const char *str2, int casesensitive );
//=============================================
short BigShort(short l);
short LittleShort(short l);
int BigLong (int l);
int LittleLong (int l);
float BigFloat (float l);
float LittleFloat (float l);
void Swap_Init (void);
char * QDECL va(char *format, ...);
#ifdef __cplusplus
}
#endif
//=============================================
#ifdef __cplusplus
//
// mapfile parsing
//
typedef struct ePair_s {
char *key;
char *value;
} ePair_t;
typedef struct mapSide_s {
char material[MAX_QPATH];
vec4_t plane;
vec4_t textureVectors[2];
} mapSide_t;
typedef struct {
int numSides;
mapSide_t **sides;
} mapBrush_t;
typedef struct {
idVec3_t xyz;
float st[2];
} patchVertex_t;
typedef struct {
char material[MAX_QPATH];
int width, height;
patchVertex_t *patchVerts;
} mapPatch_t;
typedef struct {
char modelName[MAX_QPATH];
float matrix[16];
} mapModel_t;
typedef struct mapPrimitive_s {
int numEpairs;
ePair_t **ePairs;
// only one of these will be non-NULL
mapBrush_t *brush;
mapPatch_t *patch;
mapModel_t *model;
} mapPrimitive_t;
typedef struct mapEntity_s {
int numPrimitives;
mapPrimitive_t **primitives;
int numEpairs;
ePair_t **ePairs;
} mapEntity_t;
typedef struct {
int numEntities;
mapEntity_t **entities;
} mapFile_t;
// the order of entities, brushes, and sides will be maintained, the
// lists won't be swapped on each load or save
mapFile_t *ParseMapFile( const char *text );
void FreeMapFile( mapFile_t *mapFile );
void WriteMapFile( const mapFile_t *mapFile, FILE *f );
// key names are case-insensitive
const char *ValueForMapEntityKey( const mapEntity_t *ent, const char *key );
float FloatForMapEntityKey( const mapEntity_t *ent, const char *key );
qboolean GetVectorForMapEntityKey( const mapEntity_t *ent, const char *key, idVec3_t &vec );
typedef struct {
idVec3_t xyz;
idVec2_t st;
idVec3_t normal;
idVec3_t tangents[2];
byte smoothing[4]; // colors for silhouette smoothing
} drawVert_t;
typedef struct {
int width, height;
drawVert_t *verts;
} drawVertMesh_t;
// Tesselate a map patch into smoothed, drawable vertexes
// MaxError of around 4 is reasonable
drawVertMesh_t *SubdivideMapPatch( const mapPatch_t *patch, float maxError );
#endif // __cplusplus
//=========================================
#ifdef __cplusplus
extern "C" {
#endif
void QDECL Com_Error( int level, const char *error, ... );
void QDECL Com_Printf( const char *msg, ... );
void QDECL Com_DPrintf( const char *msg, ... );
#ifdef __cplusplus
}
#endif
typedef struct {
qboolean frameMemory;
int currentElements;
int maxElements; // will reallocate and move when exceeded
void **elements;
} growList_t;
// you don't need to init the growlist if you don't mind it growing and moving
// the list as it expands
void Com_InitGrowList( growList_t *list, int maxElements );
int Com_AddToGrowList( growList_t *list, void *data );
void *Com_GrowListElement( const growList_t *list, int index );
int Com_IndexForGrowListElement( const growList_t *list, const void *element );
//
// key / value info strings
//
char *Info_ValueForKey( const char *s, const char *key );
void Info_RemoveKey( char *s, const char *key );
void Info_SetValueForKey( char *s, const char *key, const char *value );
qboolean Info_Validate( const char *s );
void Info_NextPair( const char *(*s), char key[MAX_INFO_KEY], char value[MAX_INFO_VALUE] );
// get cvar defs, collision defs, etc
//#include "../shared/interface.h"
// get key code numbers for events
//#include "../shared/keycodes.h"
#ifdef __cplusplus
// get the polygon winding functions
//#include "../shared/windings.h"
// get the flags class
//#include "../shared/idflags.h"
#endif // __cplusplus
#endif // __Q_SHARED_H

1226
CODE-mp/Splines/splines.cpp Normal file

File diff suppressed because it is too large Load diff

1061
CODE-mp/Splines/splines.h Normal file

File diff suppressed because it is too large Load diff

325
CODE-mp/Splines/util_list.h Normal file
View file

@ -0,0 +1,325 @@
#ifndef __UTIL_LIST_H__
#define __UTIL_LIST_H__
#include <stdlib.h>
#include <assert.h>
template< class type >
class idList {
private:
int m_num;
int m_size;
int m_granularity;
type *m_list;
public:
idList( int granularity = 16 );
~idList<type>();
void Clear( void );
int Num( void );
void SetNum( int num );
void SetGranularity( int granularity );
void Condense( void );
int Size( void );
void Resize( int size );
type operator[]( int index ) const;
type &operator[]( int index );
int Append( type const & obj );
int AddUnique( type const & obj );
type *Find( type const & obj, int *index = NULL );
bool RemoveIndex( int index );
bool Remove( type const & obj );
typedef int cmp_t(const void *, const void *);
void Sort( cmp_t *compare );
};
/*
================
idList<type>::idList( int )
================
*/
template< class type >
inline idList<type>::idList( int granularity ) {
assert( granularity > 0 );
m_list = NULL;
m_granularity = granularity;
Clear();
}
/*
================
idList<type>::~idList<type>
================
*/
template< class type >
inline idList<type>::~idList() {
Clear();
}
/*
================
idList<type>::Clear
================
*/
template< class type >
inline void idList<type>::Clear( void ) {
if ( m_list ) {
delete[] m_list;
}
m_list = NULL;
m_num = 0;
m_size = 0;
}
/*
================
idList<type>::Num
================
*/
template< class type >
inline int idList<type>::Num( void ) {
return m_num;
}
/*
================
idList<type>::SetNum
================
*/
template< class type >
inline void idList<type>::SetNum( int num ) {
assert( num >= 0 );
if ( num > m_size ) {
// resize it up to the closest level of granularity
Resize( ( ( num + m_granularity - 1 ) / m_granularity ) * m_granularity );
}
m_num = num;
}
/*
================
idList<type>::SetGranularity
================
*/
template< class type >
inline void idList<type>::SetGranularity( int granularity ) {
int newsize;
assert( granularity > 0 );
m_granularity = granularity;
if ( m_list ) {
// resize it to the closest level of granularity
newsize = ( ( m_num + m_granularity - 1 ) / m_granularity ) * m_granularity;
if ( newsize != m_size ) {
Resize( newsize );
}
}
}
/*
================
idList<type>::Condense
Resizes the array to exactly the number of elements it contains
================
*/
template< class type >
inline void idList<type>::Condense( void ) {
if ( m_list ) {
if ( m_num ) {
Resize( m_num );
} else {
Clear();
}
}
}
/*
================
idList<type>::Size
================
*/
template< class type >
inline int idList<type>::Size( void ) {
return m_size;
}
/*
================
idList<type>::Resize
================
*/
template< class type >
inline void idList<type>::Resize( int size ) {
type *temp;
int i;
assert( size > 0 );
if ( size <= 0 ) {
Clear();
return;
}
temp = m_list;
m_size = size;
if ( m_size < m_num ) {
m_num = m_size;
}
m_list = new type[ m_size ];
for( i = 0; i < m_num; i++ ) {
m_list[ i ] = temp[ i ];
}
if ( temp ) {
delete[] temp;
}
}
/*
================
idList<type>::operator[] const
================
*/
template< class type >
inline type idList<type>::operator[]( int index ) const {
assert( index >= 0 );
assert( index < m_num );
return m_list[ index ];
}
/*
================
idList<type>::operator[]
================
*/
template< class type >
inline type &idList<type>::operator[]( int index ) {
assert( index >= 0 );
assert( index < m_num );
return m_list[ index ];
}
/*
================
idList<type>::Append
================
*/
template< class type >
inline int idList<type>::Append( type const & obj ) {
if ( !m_list ) {
Resize( m_granularity );
}
if ( m_num == m_size ) {
Resize( m_size + m_granularity );
}
m_list[ m_num ] = obj;
m_num++;
return m_num - 1;
}
/*
================
idList<type>::AddUnique
================
*/
template< class type >
inline int idList<type>::AddUnique( type const & obj ) {
int index;
if ( !Find( obj, &index ) ) {
index = Append( obj );
}
return index;
}
/*
================
idList<type>::Find
================
*/
template< class type >
inline type *idList<type>::Find( type const & obj, int *index ) {
int i;
for( i = 0; i < m_num; i++ ) {
if ( m_list[ i ] == obj ) {
if ( index ) {
*index = i;
}
return &m_list[ i ];
}
}
return NULL;
}
/*
================
idList<type>::RemoveIndex
================
*/
template< class type >
inline bool idList<type>::RemoveIndex( int index ) {
int i;
if ( !m_list || !m_num ) {
return false;
}
assert( index >= 0 );
assert( index < m_num );
if ( ( index < 0 ) || ( index >= m_num ) ) {
return false;
}
m_num--;
for( i = index; i < m_num; i++ ) {
m_list[ i ] = m_list[ i + 1 ];
}
return true;
}
/*
================
idList<type>::Remove
================
*/
template< class type >
inline bool idList<type>::Remove( type const & obj ) {
int index;
if ( Find( obj, &index ) ) {
return RemoveIndex( index );
}
return false;
}
/*
================
idList<type>::Sort
================
*/
template< class type >
inline void idList<type>::Sort( cmp_t *compare ) {
if ( !m_list ) {
return;
}
qsort( ( void * )m_list, ( size_t )m_num, sizeof( type ), compare );
}
#endif /* !__UTIL_LIST_H__ */

View file

@ -0,0 +1,598 @@
//need to rewrite this
#include "util_str.h"
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#ifdef _WIN32
#pragma warning(disable : 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable : 4710) // function 'blah' not inlined
#endif
static const int STR_ALLOC_GRAN = 20;
char *idStr::tolower
(
char *s1
)
{
char *s;
s = s1;
while( *s )
{
*s = ::tolower( *s );
s++;
}
return s1;
}
char *idStr::toupper
(
char *s1
)
{
char *s;
s = s1;
while( *s )
{
*s = ::toupper( *s );
s++;
}
return s1;
}
int idStr::icmpn
(
const char *s1,
const char *s2,
int n
)
{
int c1;
int c2;
do
{
c1 = *s1++;
c2 = *s2++;
if ( !n-- )
{
// idStrings are equal until end point
return 0;
}
if ( c1 != c2 )
{
if ( c1 >= 'a' && c1 <= 'z' )
{
c1 -= ( 'a' - 'A' );
}
if ( c2 >= 'a' && c2 <= 'z' )
{
c2 -= ( 'a' - 'A' );
}
if ( c1 < c2 )
{
// strings less than
return -1;
}
else if ( c1 > c2 )
{
// strings greater than
return 1;
}
}
}
while( c1 );
// strings are equal
return 0;
}
int idStr::icmp
(
const char *s1,
const char *s2
)
{
int c1;
int c2;
do
{
c1 = *s1++;
c2 = *s2++;
if ( c1 != c2 )
{
if ( c1 >= 'a' && c1 <= 'z' )
{
c1 -= ( 'a' - 'A' );
}
if ( c2 >= 'a' && c2 <= 'z' )
{
c2 -= ( 'a' - 'A' );
}
if ( c1 < c2 )
{
// strings less than
return -1;
}
else if ( c1 > c2 )
{
// strings greater than
return 1;
}
}
}
while( c1 );
// strings are equal
return 0;
}
int idStr::cmpn
(
const char *s1,
const char *s2,
int n
)
{
int c1;
int c2;
do
{
c1 = *s1++;
c2 = *s2++;
if ( !n-- )
{
// strings are equal until end point
return 0;
}
if ( c1 < c2 )
{
// strings less than
return -1;
}
else if ( c1 > c2 )
{
// strings greater than
return 1;
}
}
while( c1 );
// strings are equal
return 0;
}
int idStr::cmp
(
const char *s1,
const char *s2
)
{
int c1;
int c2;
do
{
c1 = *s1++;
c2 = *s2++;
if ( c1 < c2 )
{
// strings less than
return -1;
}
else if ( c1 > c2 )
{
// strings greater than
return 1;
}
}
while( c1 );
// strings are equal
return 0;
}
/*
============
IsNumeric
Checks a string to see if it contains only numerical values.
============
*/
bool idStr::isNumeric
(
const char *str
)
{
int len;
int i;
bool dot;
if ( *str == '-' )
{
str++;
}
dot = false;
len = strlen( str );
for( i = 0; i < len; i++ )
{
if ( !isdigit( str[ i ] ) )
{
if ( ( str[ i ] == '.' ) && !dot )
{
dot = true;
continue;
}
return false;
}
}
return true;
}
idStr operator+
(
const idStr& a,
const float b
)
{
char text[ 20 ];
idStr result( a );
sprintf( text, "%f", b );
result.append( text );
return result;
}
idStr operator+
(
const idStr& a,
const int b
)
{
char text[ 20 ];
idStr result( a );
sprintf( text, "%d", b );
result.append( text );
return result;
}
idStr operator+
(
const idStr& a,
const unsigned b
)
{
char text[ 20 ];
idStr result( a );
sprintf( text, "%u", b );
result.append( text );
return result;
}
idStr& idStr::operator+=
(
const float a
)
{
char text[ 20 ];
sprintf( text, "%f", a );
append( text );
return *this;
}
idStr& idStr::operator+=
(
const int a
)
{
char text[ 20 ];
sprintf( text, "%d", a );
append( text );
return *this;
}
idStr& idStr::operator+=
(
const unsigned a
)
{
char text[ 20 ];
sprintf( text, "%u", a );
append( text );
return *this;
}
void idStr::CapLength
(
int newlen
)
{
assert ( m_data );
if ( length() <= newlen )
return;
EnsureDataWritable ();
m_data->data[newlen] = 0;
m_data->len = newlen;
}
void idStr::EnsureDataWritable
(
void
)
{
assert ( m_data );
strdata *olddata;
int len;
if ( !m_data->refcount )
return;
olddata = m_data;
len = length();
m_data = new strdata;
EnsureAlloced ( len + 1, false );
strncpy ( m_data->data, olddata->data, len+1 );
m_data->len = len;
olddata->DelRef ();
}
void idStr::EnsureAlloced (int amount, bool keepold) {
if ( !m_data ) {
m_data = new strdata();
}
// Now, let's make sure it's writable
EnsureDataWritable ();
char *newbuffer;
bool wasalloced = ( m_data->alloced != 0 );
if ( amount < m_data->alloced ) {
return;
}
assert ( amount );
if ( amount == 1 ) {
m_data->alloced = 1;
} else {
int newsize, mod;
mod = amount % STR_ALLOC_GRAN;
if ( !mod ) {
newsize = amount;
} else {
newsize = amount + STR_ALLOC_GRAN - mod;
}
m_data->alloced = newsize;
}
newbuffer = new char[m_data->alloced];
if ( wasalloced && keepold ) {
strcpy ( newbuffer, m_data->data );
}
if ( m_data->data ) {
delete [] m_data->data;
}
m_data->data = newbuffer;
}
void idStr::BackSlashesToSlashes
(
void
)
{
int i;
EnsureDataWritable ();
for ( i=0; i < m_data->len; i++ )
{
if ( m_data->data[i] == '\\' )
m_data->data[i] = '/';
}
}
void idStr::snprintf
(
char *dst,
int size,
const char *fmt,
...
)
{
char buffer[0x10000];
int len;
va_list argptr;
va_start (argptr,fmt);
len = vsprintf (buffer,fmt,argptr);
va_end (argptr);
assert ( len < size );
strncpy (dst, buffer, size-1);
}
#ifdef _WIN32
#pragma warning(disable : 4189) // local variable is initialized but not referenced
#endif
/*
=================
TestStringClass
This is a fairly rigorous test of the idStr class's functionality.
Because of the fairly global and subtle ramifications of a bug occuring
in this class, it should be run after any changes to the class.
Add more tests as functionality is changed. Tests should include
any possible bounds violation and NULL data tests.
=================
*/
void TestStringClass
(
void
)
{
char ch; // ch == ?
idStr *t; // t == ?
idStr a; // a.len == 0, a.data == "\0"
idStr b; // b.len == 0, b.data == "\0"
idStr c( "test" ); // c.len == 4, c.data == "test\0"
idStr d( c ); // d.len == 4, d.data == "test\0"
idStr e( reinterpret_cast<const char *>(NULL) );
// e.len == 0, e.data == "\0" ASSERT!
int i; // i == ?
i = a.length(); // i == 0
i = c.length(); // i == 4
// TTimo: not used
// const char *s1 = a.c_str(); // s1 == "\0"
// const char *s2 = c.c_str(); // s2 == "test\0"
t = new idStr(); // t->len == 0, t->data == "\0"
delete t; // t == ?
b = "test"; // b.len == 4, b.data == "test\0"
t = new idStr( "test" ); // t->len == 4, t->data == "test\0"
delete t; // t == ?
a = c; // a.len == 4, a.data == "test\0"
// a = "";
a = NULL; // a.len == 0, a.data == "\0" ASSERT!
a = c + d; // a.len == 8, a.data == "testtest\0"
a = c + "wow"; // a.len == 7, a.data == "testwow\0"
a = c + reinterpret_cast<const char *>(NULL);
// a.len == 4, a.data == "test\0" ASSERT!
a = "this" + d; // a.len == 8, a.data == "thistest\0"
a = reinterpret_cast<const char *>(NULL) + d;
// a.len == 4, a.data == "test\0" ASSERT!
a += c; // a.len == 8, a.data == "testtest\0"
a += "wow"; // a.len == 11, a.data == "testtestwow\0"
a += reinterpret_cast<const char *>(NULL);
// a.len == 11, a.data == "testtestwow\0" ASSERT!
a = "test"; // a.len == 4, a.data == "test\0"
ch = a[ 0 ]; // ch == 't'
ch = a[ -1 ]; // ch == 0 ASSERT!
ch = a[ 1000 ]; // ch == 0 ASSERT!
ch = a[ 0 ]; // ch == 't'
ch = a[ 1 ]; // ch == 'e'
ch = a[ 2 ]; // ch == 's'
ch = a[ 3 ]; // ch == 't'
ch = a[ 4 ]; // ch == '\0' ASSERT!
ch = a[ 5 ]; // ch == '\0' ASSERT!
a[ 1 ] = 'b'; // a.len == 4, a.data == "tbst\0"
a[ -1 ] = 'b'; // a.len == 4, a.data == "tbst\0" ASSERT!
a[ 0 ] = '0'; // a.len == 4, a.data == "0bst\0"
a[ 1 ] = '1'; // a.len == 4, a.data == "01st\0"
a[ 2 ] = '2'; // a.len == 4, a.data == "012t\0"
a[ 3 ] = '3'; // a.len == 4, a.data == "0123\0"
a[ 4 ] = '4'; // a.len == 4, a.data == "0123\0" ASSERT!
a[ 5 ] = '5'; // a.len == 4, a.data == "0123\0" ASSERT!
a[ 7 ] = '7'; // a.len == 4, a.data == "0123\0" ASSERT!
a = "test"; // a.len == 4, a.data == "test\0"
b = "no"; // b.len == 2, b.data == "no\0"
i = ( a == b ); // i == 0
i = ( a == c ); // i == 1
i = ( a == "blow" ); // i == 0
i = ( a == "test" ); // i == 1
i = ( a == NULL ); // i == 0 ASSERT!
i = ( "test" == b ); // i == 0
i = ( "test" == a ); // i == 1
i = ( NULL == a ); // i == 0 ASSERT!
i = ( a != b ); // i == 1
i = ( a != c ); // i == 0
i = ( a != "blow" ); // i == 1
i = ( a != "test" ); // i == 0
i = ( a != NULL ); // i == 1 ASSERT!
i = ( "test" != b ); // i == 1
i = ( "test" != a ); // i == 0
i = ( NULL != a ); // i == 1 ASSERT!
a = "test"; // a.data == "test"
b = a; // b.data == "test"
a = "not"; // a.data == "not", b.data == "test"
a = b; // a.data == b.data == "test"
a += b; // a.data == "testtest", b.data = "test"
a = b;
a[1] = '1'; // a.data = "t1st", b.data = "test"
}
#ifdef _WIN32
#pragma warning(default : 4189) // local variable is initialized but not referenced
#pragma warning(disable : 4514) // unreferenced inline function has been removed
#endif

796
CODE-mp/Splines/util_str.h Normal file
View file

@ -0,0 +1,796 @@
//need to rewrite this
#ifndef __UTIL_STR_H__
#define __UTIL_STR_H__
#include <assert.h>
#include <string.h>
#include <stdio.h>
#ifdef _WIN32
#pragma warning(disable : 4710) // function 'blah' not inlined
#endif
void TestStringClass ();
class strdata
{
public:
strdata () : len( 0 ), refcount ( 0 ), data ( NULL ), alloced ( 0 ) {}
~strdata ()
{
if ( data )
delete [] data;
}
void AddRef () { refcount++; }
bool DelRef () // True if killed
{
refcount--;
if ( refcount < 0 )
{
delete this;
return true;
}
return false;
}
int len;
int refcount;
char *data;
int alloced;
};
class idStr {
protected:
strdata *m_data;
void EnsureAlloced ( int, bool keepold = true );
void EnsureDataWritable ();
public:
~idStr();
idStr();
idStr( const char *text );
idStr( const idStr& string );
idStr( const idStr string, int start, int end );
idStr( const char ch );
idStr( const int num );
idStr( const float num );
idStr( const unsigned num );
int length( void ) const;
int allocated( void ) const;
const char * c_str( void ) const;
void append( const char *text );
void append( const idStr& text );
char operator[]( int index ) const;
char& operator[]( int index );
void operator=( const idStr& text );
void operator=( const char *text );
friend idStr operator+( const idStr& a, const idStr& b );
friend idStr operator+( const idStr& a, const char *b );
friend idStr operator+( const char *a, const idStr& b );
friend idStr operator+( const idStr& a, const float b );
friend idStr operator+( const idStr& a, const int b );
friend idStr operator+( const idStr& a, const unsigned b );
friend idStr operator+( const idStr& a, const bool b );
friend idStr operator+( const idStr& a, const char b );
idStr& operator+=( const idStr& a );
idStr& operator+=( const char *a );
idStr& operator+=( const float a );
idStr& operator+=( const char a );
idStr& operator+=( const int a );
idStr& operator+=( const unsigned a );
idStr& operator+=( const bool a );
friend bool operator==( const idStr& a, const idStr& b );
friend bool operator==( const idStr& a, const char *b );
friend bool operator==( const char *a, const idStr& b );
friend bool operator!=( const idStr& a, const idStr& b );
friend bool operator!=( const idStr& a, const char *b );
friend bool operator!=( const char *a, const idStr& b );
operator const char * () const;
operator const char * ();
int icmpn( const char *text, int n ) const;
int icmpn( const idStr& text, int n ) const;
int icmp( const char *text ) const;
int icmp( const idStr& text ) const;
int cmpn( const char *text, int n ) const;
int cmpn( const idStr& text, int n ) const;
int cmp( const char *text ) const;
int cmp( const idStr& text ) const;
void tolower( void );
void toupper( void );
static char *tolower( char *s1 );
static char *toupper( char *s1 );
static int icmpn( const char *s1, const char *s2, int n );
static int icmp( const char *s1, const char *s2 );
static int cmpn( const char *s1, const char *s2, int n );
static int cmp( const char *s1, const char *s2 );
static void snprintf ( char *dst, int size, const char *fmt, ... );
static bool isNumeric( const char *str );
bool isNumeric( void ) const;
void CapLength ( int );
void BackSlashesToSlashes ();
};
inline idStr::~idStr()
{
if ( m_data )
{
m_data->DelRef ();
m_data = NULL;
}
}
inline idStr::idStr() : m_data ( NULL )
{
EnsureAlloced ( 1 );
m_data->data[ 0 ] = 0;
}
inline idStr::idStr
(
const char *text
) : m_data ( NULL )
{
int len;
assert( text );
if ( text )
{
len = strlen( text );
EnsureAlloced ( len + 1 );
strcpy( m_data->data, text );
m_data->len = len;
}
else
{
EnsureAlloced ( 1 );
m_data->data[ 0 ] = 0;
m_data->len = 0;
}
}
inline idStr::idStr
(
const idStr& text
) : m_data ( NULL )
{
m_data = text.m_data;
m_data->AddRef ();
}
inline idStr::idStr
(
const idStr text,
int start,
int end
) : m_data ( NULL )
{
int i;
int len;
if ( end > text.length() )
{
end = text.length();
}
if ( start > text.length() )
{
start = text.length();
}
len = end - start;
if ( len < 0 )
{
len = 0;
}
EnsureAlloced ( len + 1 );
for( i = 0; i < len; i++ )
{
m_data->data[ i ] = text[ start + i ];
}
m_data->data[ len ] = 0;
m_data->len = len;
}
inline idStr::idStr
(
const char ch
) : m_data ( NULL )
{
EnsureAlloced ( 2 );
m_data->data[ 0 ] = ch;
m_data->data[ 1 ] = 0;
m_data->len = 1;
}
inline idStr::idStr
(
const float num
) : m_data ( NULL )
{
char text[ 32 ];
int len;
sprintf( text, "%.3f", num );
len = strlen( text );
EnsureAlloced( len + 1 );
strcpy( m_data->data, text );
m_data->len = len;
}
inline idStr::idStr
(
const int num
) : m_data ( NULL )
{
char text[ 32 ];
int len;
sprintf( text, "%d", num );
len = strlen( text );
EnsureAlloced( len + 1 );
strcpy( m_data->data, text );
m_data->len = len;
}
inline idStr::idStr
(
const unsigned num
) : m_data ( NULL )
{
char text[ 32 ];
int len;
sprintf( text, "%u", num );
len = strlen( text );
EnsureAlloced( len + 1 );
strcpy( m_data->data, text );
m_data->len = len;
}
inline int idStr::length( void ) const
{
return ( m_data != NULL ) ? m_data->len : 0;
}
inline int idStr::allocated( void ) const
{
return ( m_data != NULL ) ? m_data->alloced + sizeof( *m_data ) : 0;
}
inline const char *idStr::c_str( void ) const
{
assert( m_data );
return m_data->data;
}
inline void idStr::append
(
const char *text
)
{
int len;
assert( text );
if ( text )
{
len = length() + strlen( text );
EnsureAlloced( len + 1 );
strcat( m_data->data, text );
m_data->len = len;
}
}
inline void idStr::append
(
const idStr& text
)
{
int len;
len = length() + text.length();
EnsureAlloced ( len + 1 );
strcat ( m_data->data, text.c_str () );
m_data->len = len;
}
inline char idStr::operator[]( int index ) const
{
assert ( m_data );
if ( !m_data )
return 0;
// don't include the '/0' in the test, because technically, it's out of bounds
assert( ( index >= 0 ) && ( index < m_data->len ) );
// In release mode, give them a null character
// don't include the '/0' in the test, because technically, it's out of bounds
if ( ( index < 0 ) || ( index >= m_data->len ) )
{
return 0;
}
return m_data->data[ index ];
}
inline char& idStr::operator[]
(
int index
)
{
// Used for result for invalid indices
static char dummy = 0;
assert ( m_data );
// We don't know if they'll write to it or not
// if it's not a const object
EnsureDataWritable ();
if ( !m_data )
return dummy;
// don't include the '/0' in the test, because technically, it's out of bounds
assert( ( index >= 0 ) && ( index < m_data->len ) );
// In release mode, let them change a safe variable
// don't include the '/0' in the test, because technically, it's out of bounds
if ( ( index < 0 ) || ( index >= m_data->len ) )
{
return dummy;
}
return m_data->data[ index ];
}
inline void idStr::operator=
(
const idStr& text
)
{
// adding the reference before deleting our current reference prevents
// us from deleting our string if we are copying from ourself
text.m_data->AddRef();
m_data->DelRef();
m_data = text.m_data;
}
inline void idStr::operator=
(
const char *text
)
{
int len;
assert( text );
if ( !text )
{
// safe behaviour if NULL
EnsureAlloced ( 1, false );
m_data->data[0] = 0;
m_data->len = 0;
return;
}
if ( !m_data )
{
len = strlen ( text );
EnsureAlloced( len + 1, false );
strcpy ( m_data->data, text );
m_data->len = len;
return;
}
if ( text == m_data->data )
return; // Copying same thing. Punt.
// If we alias and I don't do this, I could corrupt other strings... This
// will get called with EnsureAlloced anyway
EnsureDataWritable ();
// Now we need to check if we're aliasing..
if ( text >= m_data->data && text <= m_data->data + m_data->len )
{
// Great, we're aliasing. We're copying from inside ourselves.
// This means that I don't have to ensure that anything is alloced,
// though I'll assert just in case.
int diff = text - m_data->data;
int i;
assert ( strlen ( text ) < (unsigned) m_data->len );
for ( i = 0; text[i]; i++ )
{
m_data->data[i] = text[i];
}
m_data->data[i] = 0;
m_data->len -= diff;
return;
}
len = strlen( text );
EnsureAlloced ( len + 1, false );
strcpy( m_data->data, text );
m_data->len = len;
}
inline idStr operator+
(
const idStr& a,
const idStr& b
)
{
idStr result( a );
result.append( b );
return result;
}
inline idStr operator+
(
const idStr& a,
const char *b
)
{
idStr result( a );
result.append( b );
return result;
}
inline idStr operator+
(
const char *a,
const idStr& b
)
{
idStr result( a );
result.append( b );
return result;
}
inline idStr operator+
(
const idStr& a,
const bool b
)
{
idStr result( a );
result.append( b ? "true" : "false" );
return result;
}
inline idStr operator+
(
const idStr& a,
const char b
)
{
char text[ 2 ];
text[ 0 ] = b;
text[ 1 ] = 0;
return a + text;
}
inline idStr& idStr::operator+=
(
const idStr& a
)
{
append( a );
return *this;
}
inline idStr& idStr::operator+=
(
const char *a
)
{
append( a );
return *this;
}
inline idStr& idStr::operator+=
(
const char a
)
{
char text[ 2 ];
text[ 0 ] = a;
text[ 1 ] = 0;
append( text );
return *this;
}
inline idStr& idStr::operator+=
(
const bool a
)
{
append( a ? "true" : "false" );
return *this;
}
inline bool operator==
(
const idStr& a,
const idStr& b
)
{
return ( !strcmp( a.c_str(), b.c_str() ) );
}
inline bool operator==
(
const idStr& a,
const char *b
)
{
assert( b );
if ( !b )
{
return false;
}
return ( !strcmp( a.c_str(), b ) );
}
inline bool operator==
(
const char *a,
const idStr& b
)
{
assert( a );
if ( !a )
{
return false;
}
return ( !strcmp( a, b.c_str() ) );
}
inline bool operator!=
(
const idStr& a,
const idStr& b
)
{
return !( a == b );
}
inline bool operator!=
(
const idStr& a,
const char *b
)
{
return !( a == b );
}
inline bool operator!=
(
const char *a,
const idStr& b
)
{
return !( a == b );
}
inline int idStr::icmpn
(
const char *text,
int n
) const
{
assert( m_data );
assert( text );
return idStr::icmpn( m_data->data, text, n );
}
inline int idStr::icmpn
(
const idStr& text,
int n
) const
{
assert( m_data );
assert( text.m_data );
return idStr::icmpn( m_data->data, text.m_data->data, n );
}
inline int idStr::icmp
(
const char *text
) const
{
assert( m_data );
assert( text );
return idStr::icmp( m_data->data, text );
}
inline int idStr::icmp
(
const idStr& text
) const
{
assert( c_str () );
assert( text.c_str () );
return idStr::icmp( c_str () , text.c_str () );
}
inline int idStr::cmp
(
const char *text
) const
{
assert( m_data );
assert( text );
return idStr::cmp( m_data->data, text );
}
inline int idStr::cmp
(
const idStr& text
) const
{
assert( c_str () );
assert( text.c_str () );
return idStr::cmp( c_str () , text.c_str () );
}
inline int idStr::cmpn
(
const char *text,
int n
) const
{
assert( c_str () );
assert( text );
return idStr::cmpn( c_str () , text, n );
}
inline int idStr::cmpn
(
const idStr& text,
int n
) const
{
assert( c_str () );
assert( text.c_str () );
return idStr::cmpn( c_str () , text.c_str () , n );
}
inline void idStr::tolower
(
void
)
{
assert( m_data );
EnsureDataWritable ();
idStr::tolower( m_data->data );
}
inline void idStr::toupper
(
void
)
{
assert( m_data );
EnsureDataWritable ();
idStr::toupper( m_data->data );
}
inline bool idStr::isNumeric
(
void
) const
{
assert( m_data );
return idStr::isNumeric( m_data->data );
}
inline idStr::operator const char *() {
return c_str();
}
inline idStr::operator const char *
(
void
) const
{
return c_str ();
}
#endif

BIN
CODE-mp/Splines/vssver.scc Normal file

Binary file not shown.

811
CODE-mp/WinDed.dsp Normal file
View file

@ -0,0 +1,811 @@
# Microsoft Developer Studio Project File - Name="WinDed" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=WinDed - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "WinDed.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "WinDed.mak" CFG="WinDed - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "WinDed - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "WinDed - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/General/code", EAAAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "WinDed - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "DEDICATED" /D "BOTLIB" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib Winmm.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "WinDed - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "DEDICATED" /D "_JK2" /D "BOTLIB" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib Winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "WinDed - Win32 Release"
# Name "WinDed - Win32 Debug"
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\qcommon\chash.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\cm_load.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\cm_local.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\cm_patch.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\cm_patch.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\cm_polylib.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\cm_polylib.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\cm_public.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\cm_test.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\cm_trace.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\cmd.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\CNetProfile.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\common.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\cvar.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\disablewarnings.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\files.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\game_version.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\GenericParser2.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\GenericParser2.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\hstring.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\hstring.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\huffman.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\INetProfile.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\md4.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\MiniHeap.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\msg.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\net_chan.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\q_math.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\q_shared.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\qcommon.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\qfiles.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\RoffSystem.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\RoffSystem.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\sstring.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\strip.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\strip.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\tags.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\unzip.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\unzip.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\vm.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\vm_interpreted.cpp
# End Source File
# Begin Source File
SOURCE=.\qcommon\vm_local.h
# End Source File
# Begin Source File
SOURCE=.\qcommon\vm_x86.cpp
# End Source File
# End Group
# Begin Group "Ghoul2"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\ghoul2\G2.h
# End Source File
# Begin Source File
SOURCE=.\ghoul2\G2_API.cpp
# End Source File
# Begin Source File
SOURCE=.\ghoul2\G2_bolts.cpp
# End Source File
# Begin Source File
SOURCE=.\ghoul2\G2_bones.cpp
# End Source File
# Begin Source File
SOURCE=.\ghoul2\G2_gore.h
# End Source File
# Begin Source File
SOURCE=.\ghoul2\G2_local.h
# End Source File
# Begin Source File
SOURCE=.\ghoul2\G2_misc.cpp
# End Source File
# Begin Source File
SOURCE=.\ghoul2\G2_surfaces.cpp
# End Source File
# Begin Source File
SOURCE=.\ghoul2\ghoul2_shared.h
# End Source File
# End Group
# Begin Group "Server"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\server\server.h
# End Source File
# Begin Source File
SOURCE=.\server\sv_bot.cpp
# End Source File
# Begin Source File
SOURCE=.\server\sv_ccmds.cpp
# End Source File
# Begin Source File
SOURCE=.\server\sv_client.cpp
# End Source File
# Begin Source File
SOURCE=.\server\sv_game.cpp
# End Source File
# Begin Source File
SOURCE=.\server\sv_init.cpp
# End Source File
# Begin Source File
SOURCE=.\server\sv_main.cpp
# End Source File
# Begin Source File
SOURCE=.\server\sv_net_chan.cpp
# End Source File
# Begin Source File
SOURCE=.\server\sv_snapshot.cpp
# End Source File
# Begin Source File
SOURCE=.\server\sv_world.cpp
# End Source File
# End Group
# Begin Group "Null"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\null\null_client.cpp
# End Source File
# Begin Source File
SOURCE=.\null\null_glimp.cpp
# End Source File
# Begin Source File
SOURCE=.\null\null_input.cpp
# End Source File
# Begin Source File
SOURCE=.\null\null_renderer.cpp
# End Source File
# Begin Source File
SOURCE=.\null\null_snddma.cpp
# End Source File
# Begin Source File
SOURCE=.\null\win_main.cpp
# End Source File
# End Group
# Begin Group "Renderer"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\renderer\matcomp.c
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_backend.cpp
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_ghoul2.cpp
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_image.cpp
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_init.cpp
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_main.cpp
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_mesh.cpp
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_model.cpp
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_shader.cpp
# End Source File
# End Group
# Begin Group "Win32"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\win32\win_net.cpp
# End Source File
# Begin Source File
SOURCE=.\win32\win_shared.cpp
# End Source File
# End Group
# Begin Group "botlib"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\botlib\aasfile.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_bsp.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_bspq3.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_cluster.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_cluster.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_debug.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_debug.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_def.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_entity.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_entity.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_file.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_file.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_funcs.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_main.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_main.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_move.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_move.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_optimize.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_optimize.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_reach.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_reach.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_route.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_route.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_routealt.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_routealt.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_sample.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_aas_sample.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_ai_char.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_ai_chat.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_ai_gen.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_ai_goal.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_ai_move.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_ai_weap.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_ai_weight.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_ai_weight.h
# End Source File
# Begin Source File
SOURCE=.\botlib\be_ea.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_interface.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\be_interface.h
# End Source File
# Begin Source File
SOURCE=.\botlib\l_crc.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\l_crc.h
# End Source File
# Begin Source File
SOURCE=.\botlib\l_libvar.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\l_libvar.h
# End Source File
# Begin Source File
SOURCE=.\botlib\l_log.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\l_log.h
# End Source File
# Begin Source File
SOURCE=.\botlib\l_memory.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\l_memory.h
# End Source File
# Begin Source File
SOURCE=.\botlib\l_precomp.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\l_precomp.h
# End Source File
# Begin Source File
SOURCE=.\botlib\l_script.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\l_script.h
# End Source File
# Begin Source File
SOURCE=.\botlib\l_struct.cpp
# End Source File
# Begin Source File
SOURCE=.\botlib\l_struct.h
# End Source File
# Begin Source File
SOURCE=.\botlib\l_utils.h
# End Source File
# End Group
# Begin Group "headers"
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\game\anims.h
# End Source File
# Begin Source File
SOURCE=.\game\be_aas.h
# End Source File
# Begin Source File
SOURCE=.\game\be_ai_char.h
# End Source File
# Begin Source File
SOURCE=.\game\be_ai_chat.h
# End Source File
# Begin Source File
SOURCE=.\game\be_ai_gen.h
# End Source File
# Begin Source File
SOURCE=.\game\be_ai_goal.h
# End Source File
# Begin Source File
SOURCE=.\game\be_ai_move.h
# End Source File
# Begin Source File
SOURCE=.\game\be_ai_weap.h
# End Source File
# Begin Source File
SOURCE=.\game\be_ea.h
# End Source File
# Begin Source File
SOURCE=.\game\bg_public.h
# End Source File
# Begin Source File
SOURCE=.\game\bg_weapons.h
# End Source File
# Begin Source File
SOURCE=.\game\botlib.h
# End Source File
# Begin Source File
SOURCE=.\cgame\cg_public.h
# End Source File
# Begin Source File
SOURCE=.\client\client.h
# End Source File
# Begin Source File
SOURCE=.\encryption\encryption.h
# End Source File
# Begin Source File
SOURCE=.\game\g_public.h
# End Source File
# Begin Source File
SOURCE=.\renderer\glext.h
# End Source File
# Begin Source File
SOURCE=".\jpeg-6\jconfig.h"
# End Source File
# Begin Source File
SOURCE=".\jpeg-6\jerror.h"
# End Source File
# Begin Source File
SOURCE=".\jpeg-6\jmorecfg.h"
# End Source File
# Begin Source File
SOURCE=".\jpeg-6\jpegint.h"
# End Source File
# Begin Source File
SOURCE=".\jpeg-6\jpeglib.h"
# End Source File
# Begin Source File
SOURCE=.\ui\keycodes.h
# End Source File
# Begin Source File
SOURCE=.\client\keys.h
# End Source File
# Begin Source File
SOURCE=.\renderer\matcomp.h
# End Source File
# Begin Source File
SOURCE=.\renderer\mdx_format.h
# End Source File
# Begin Source File
SOURCE=.\png\png.h
# End Source File
# Begin Source File
SOURCE=.\game\q_math.c
# End Source File
# Begin Source File
SOURCE=.\game\q_shared.c
# End Source File
# Begin Source File
SOURCE=.\game\q_shared.h
# End Source File
# Begin Source File
SOURCE=.\renderer\qgl.h
# End Source File
# Begin Source File
SOURCE=.\client\snd_public.h
# End Source File
# Begin Source File
SOURCE=.\strings\str_server.h
# End Source File
# Begin Source File
SOURCE=.\game\surfaceflags.h
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_font.h
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_local.h
# End Source File
# Begin Source File
SOURCE=.\renderer\tr_public.h
# End Source File
# Begin Source File
SOURCE=.\cgame\tr_types.h
# End Source File
# Begin Source File
SOURCE=.\ui\ui_public.h
# End Source File
# Begin Source File
SOURCE=.\win32\win_local.h
# End Source File
# End Group
# End Target
# End Project

119
CODE-mp/WinDed.plg Normal file
View file

@ -0,0 +1,119 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: WinDed - Win32 Debug--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\jmonroe\LOCALS~1\Temp\RSPB2B.tmp" with contents
[
/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "DEDICATED" /D "_JK2" /D "BOTLIB" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
"C:\projects\jk2\CODE-mp\null\null_glimp.cpp"
"C:\projects\jk2\CODE-mp\null\null_renderer.cpp"
"C:\projects\jk2\CODE-mp\null\null_snddma.cpp"
]
Creating command line "cl.exe @C:\DOCUME~1\jmonroe\LOCALS~1\Temp\RSPB2B.tmp"
Creating temporary file "C:\DOCUME~1\jmonroe\LOCALS~1\Temp\RSPB2C.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib wsock32.lib Winmm.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/WinDed.pdb" /debug /machine:I386 /out:"Debug/WinDed.exe" /pdbtype:sept
".\Debug\cm_load.obj"
".\Debug\cm_patch.obj"
".\Debug\cm_polylib.obj"
".\Debug\cm_test.obj"
".\Debug\cm_trace.obj"
".\Debug\cmd.obj"
".\Debug\CNetProfile.obj"
".\Debug\common.obj"
".\Debug\cvar.obj"
".\Debug\files.obj"
".\Debug\GenericParser2.obj"
".\Debug\hstring.obj"
".\Debug\huffman.obj"
".\Debug\md4.obj"
".\Debug\msg.obj"
".\Debug\net_chan.obj"
".\Debug\q_math.obj"
".\Debug\q_shared.obj"
".\Debug\RoffSystem.obj"
".\Debug\strip.obj"
".\Debug\unzip.obj"
".\Debug\vm.obj"
".\Debug\vm_interpreted.obj"
".\Debug\vm_x86.obj"
".\Debug\G2_API.obj"
".\Debug\G2_bolts.obj"
".\Debug\G2_bones.obj"
".\Debug\G2_misc.obj"
".\Debug\G2_surfaces.obj"
".\Debug\sv_bot.obj"
".\Debug\sv_ccmds.obj"
".\Debug\sv_client.obj"
".\Debug\sv_game.obj"
".\Debug\sv_init.obj"
".\Debug\sv_main.obj"
".\Debug\sv_net_chan.obj"
".\Debug\sv_snapshot.obj"
".\Debug\sv_world.obj"
".\Debug\null_client.obj"
".\Debug\null_glimp.obj"
".\Debug\null_input.obj"
".\Debug\null_renderer.obj"
".\Debug\null_snddma.obj"
".\Debug\win_main.obj"
".\Debug\matcomp.obj"
".\Debug\tr_backend.obj"
".\Debug\tr_ghoul2.obj"
".\Debug\tr_image.obj"
".\Debug\tr_init.obj"
".\Debug\tr_main.obj"
".\Debug\tr_mesh.obj"
".\Debug\tr_model.obj"
".\Debug\tr_shader.obj"
".\Debug\win_net.obj"
".\Debug\win_shared.obj"
".\Debug\be_aas_bspq3.obj"
".\Debug\be_aas_cluster.obj"
".\Debug\be_aas_debug.obj"
".\Debug\be_aas_entity.obj"
".\Debug\be_aas_file.obj"
".\Debug\be_aas_main.obj"
".\Debug\be_aas_move.obj"
".\Debug\be_aas_optimize.obj"
".\Debug\be_aas_reach.obj"
".\Debug\be_aas_route.obj"
".\Debug\be_aas_routealt.obj"
".\Debug\be_aas_sample.obj"
".\Debug\be_ai_char.obj"
".\Debug\be_ai_chat.obj"
".\Debug\be_ai_gen.obj"
".\Debug\be_ai_goal.obj"
".\Debug\be_ai_move.obj"
".\Debug\be_ai_weap.obj"
".\Debug\be_ai_weight.obj"
".\Debug\be_ea.obj"
".\Debug\be_interface.obj"
".\Debug\l_crc.obj"
".\Debug\l_libvar.obj"
".\Debug\l_log.obj"
".\Debug\l_memory.obj"
".\Debug\l_precomp.obj"
".\Debug\l_script.obj"
".\Debug\l_struct.obj"
]
Creating command line "link.exe @C:\DOCUME~1\jmonroe\LOCALS~1\Temp\RSPB2C.tmp"
<h3>Output Window</h3>
Compiling...
null_glimp.cpp
null_renderer.cpp
null_snddma.cpp
Generating Code...
Linking...
<h3>Results</h3>
WinDed.exe - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View file

@ -16,7 +16,7 @@
#define AAS_DEBUG #define AAS_DEBUG
// these are also in q_shared.h - argh (rjr) // these are also in q_shared.h - argh (rjr)
#define MAX_CLIENTS 64 #define MAX_CLIENTS 32
#define MAX_MODELS 256 // these are sent over the net as 8 bits #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_SOUNDS 256 // so they cannot be blindly increased

View file

@ -885,7 +885,7 @@ int PS_ReadToken(script_t *script, token_t *token)
//if there is a name //if there is a name
else if ((*script->script_p >= 'a' && *script->script_p <= 'z') || else if ((*script->script_p >= 'a' && *script->script_p <= 'z') ||
(*script->script_p >= 'A' && *script->script_p <= 'Z') || (*script->script_p >= 'A' && *script->script_p <= 'Z') ||
*script->script_p == '_') *script->script_p == '_' || *script->script_p == '@')
{ {
if (!PS_ReadName(script, token)) return 0; if (!PS_ReadName(script, token)) return 0;
} //end if } //end if

View file

@ -0,0 +1,5 @@
SCC = This is a Source Code Control file
[botlib.dsp]
SCC_Aux_Path = "\\ravend\vss_projects\jk2sof2MP"
SCC_Project_Name = "$/General/code/botlib", ACAAAAAA

BIN
CODE-mp/botlib/vssver.scc Normal file

Binary file not shown.

8
CODE-mp/buildvms.bat Normal file
View file

@ -0,0 +1,8 @@
set include=
cd game
call game
cd ..\cgame
call cgame
cd ..\ui
call ui
cd ..

View file

@ -0,0 +1,3 @@
EXPORTS
vmMain
dllEntry

150
CODE-mp/cgame/JK2_cgame.plg Normal file
View file

@ -0,0 +1,150 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: JK2cgame - Win32 Final JK2--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\jmonroe\LOCALS~1\Temp\RSP31.tmp" with contents
[
/nologo /G6 /ML /W4 /GX /O2 /I ".." /I "./../game" /D "NDEBUG" /D "_WINDOWS" /D "MISSIONPACK" /D "WIN32" /D "_JK2" /D "FINAL_BUILD" /Fp"../Final/JK2cgame/JK2_cgame.pch" /YX /Fo"../Final/JK2cgame/" /Fd"../Final/JK2cgame/" /FD /c
"C:\projects\jk2\CODE-mp\game\bg_misc.c"
"C:\projects\jk2\CODE-mp\game\bg_panimate.c"
"C:\projects\jk2\CODE-mp\game\bg_pmove.c"
"C:\projects\jk2\CODE-mp\game\bg_saber.c"
"C:\projects\jk2\CODE-mp\game\bg_slidemove.c"
"C:\projects\jk2\CODE-mp\game\bg_weapons.c"
"C:\projects\jk2\CODE-mp\cgame\cg_consolecmds.c"
"C:\projects\jk2\CODE-mp\cgame\cg_draw.c"
"C:\projects\jk2\CODE-mp\cgame\cg_drawtools.c"
"C:\projects\jk2\CODE-mp\cgame\cg_effects.c"
"C:\projects\jk2\CODE-mp\cgame\cg_ents.c"
"C:\projects\jk2\CODE-mp\cgame\cg_event.c"
"C:\projects\jk2\CODE-mp\cgame\cg_info.c"
"C:\projects\jk2\CODE-mp\cgame\cg_light.c"
"C:\projects\jk2\CODE-mp\cgame\cg_localents.c"
"C:\projects\jk2\CODE-mp\cgame\cg_main.c"
"C:\projects\jk2\CODE-mp\cgame\cg_marks.c"
"C:\projects\jk2\CODE-mp\cgame\cg_newDraw.c"
"C:\projects\jk2\CODE-mp\cgame\cg_players.c"
"C:\projects\jk2\CODE-mp\cgame\cg_playerstate.c"
"C:\projects\jk2\CODE-mp\cgame\cg_predict.c"
"C:\projects\jk2\CODE-mp\cgame\cg_saga.c"
"C:\projects\jk2\CODE-mp\cgame\cg_scoreboard.c"
"C:\projects\jk2\CODE-mp\cgame\cg_servercmds.c"
"C:\projects\jk2\CODE-mp\cgame\cg_snapshot.c"
"C:\projects\jk2\CODE-mp\cgame\cg_syscalls.c"
"C:\projects\jk2\CODE-mp\cgame\cg_turret.c"
"C:\projects\jk2\CODE-mp\cgame\cg_view.c"
"C:\projects\jk2\CODE-mp\cgame\cg_weaponinit.c"
"C:\projects\jk2\CODE-mp\cgame\cg_weapons.c"
"C:\projects\jk2\CODE-mp\cgame\fx_blaster.c"
"C:\projects\jk2\CODE-mp\cgame\fx_bowcaster.c"
"C:\projects\jk2\CODE-mp\cgame\fx_bryarpistol.c"
"C:\projects\jk2\CODE-mp\cgame\fx_demp2.c"
"C:\projects\jk2\CODE-mp\cgame\fx_disruptor.c"
"C:\projects\jk2\CODE-mp\cgame\fx_flechette.c"
"C:\projects\jk2\CODE-mp\cgame\fx_force.c"
"C:\projects\jk2\CODE-mp\cgame\fx_heavyrepeater.c"
"C:\projects\jk2\CODE-mp\cgame\fx_rocketlauncher.c"
]
Creating command line "cl.exe @C:\DOCUME~1\jmonroe\LOCALS~1\Temp\RSP31.tmp"
Creating temporary file "C:\DOCUME~1\jmonroe\LOCALS~1\Temp\RSP32.tmp" with contents
[
/nologo /base:"0x30000000" /subsystem:windows /dll /incremental:no /pdb:"../Final/cgamex86.pdb" /map:"../Final/JK2cgame/cgamex86.map" /machine:I386 /def:".\JK2_cgame.def" /out:"../Final/cgamex86.dll" /implib:"../Final/cgamex86.lib"
"\projects\jk2\CODE-mp\Final\JK2cgame\bg_misc.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\bg_panimate.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\bg_pmove.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\bg_saber.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\bg_slidemove.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\bg_weapons.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_consolecmds.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_draw.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_drawtools.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_effects.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_ents.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_event.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_info.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_light.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_localents.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_main.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_marks.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_newDraw.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_players.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_playerstate.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_predict.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_saga.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_scoreboard.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_servercmds.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_snapshot.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_syscalls.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_turret.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_view.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_weaponinit.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\cg_weapons.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\fx_blaster.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\fx_bowcaster.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\fx_bryarpistol.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\fx_demp2.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\fx_disruptor.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\fx_flechette.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\fx_force.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\fx_heavyrepeater.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\fx_rocketlauncher.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\q_math.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\q_shared.obj"
"\projects\jk2\CODE-mp\Final\JK2cgame\ui_shared.obj"
]
Creating command line "link.exe @C:\DOCUME~1\jmonroe\LOCALS~1\Temp\RSP32.tmp"
<h3>Output Window</h3>
Compiling...
bg_misc.c
bg_panimate.c
bg_pmove.c
bg_saber.c
bg_slidemove.c
bg_weapons.c
cg_consolecmds.c
cg_draw.c
cg_drawtools.c
cg_effects.c
cg_ents.c
cg_event.c
cg_info.c
cg_light.c
cg_localents.c
cg_main.c
cg_marks.c
cg_newDraw.c
cg_players.c
cg_playerstate.c
cg_predict.c
cg_saga.c
cg_scoreboard.c
cg_servercmds.c
cg_snapshot.c
cg_syscalls.c
cg_turret.c
cg_view.c
cg_weaponinit.c
cg_weapons.c
fx_blaster.c
fx_bowcaster.c
fx_bryarpistol.c
fx_demp2.c
fx_disruptor.c
fx_flechette.c
fx_force.c
fx_heavyrepeater.c
fx_rocketlauncher.c
Linking...
Creating library ../Final/cgamex86.lib and object ../Final/cgamex86.exp
<h3>Results</h3>
cgamex86.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View file

@ -1231,7 +1231,6 @@ stringID_table_t animTable [MAX_ANIMATIONS+1] =
ENUM2STRING(FACE_SMILE), //# ENUM2STRING(FACE_SMILE), //#
ENUM2STRING(FACE_FROWN), //# ENUM2STRING(FACE_FROWN), //#
ENUM2STRING(FACE_DEAD), //# ENUM2STRING(FACE_DEAD), //#
ENUM2STRING(FACE_GALAK), //# This has to be last for Galak Mech to talk
//must be terminated //must be terminated
NULL,-1 NULL,-1

View file

@ -411,11 +411,8 @@ static consoleCommand_t commands[] = {
{ "nextskin", CG_TestModelNextSkin_f }, { "nextskin", CG_TestModelNextSkin_f },
{ "prevskin", CG_TestModelPrevSkin_f }, { "prevskin", CG_TestModelPrevSkin_f },
{ "viewpos", CG_Viewpos_f }, { "viewpos", CG_Viewpos_f },
{ "datapad", CG_ScoresDown_f }, //SP compatibility for default.cfg
{ "+scores", CG_ScoresDown_f }, { "+scores", CG_ScoresDown_f },
{ "-scores", CG_ScoresUp_f }, { "-scores", CG_ScoresUp_f },
// { "+zoom", CG_ZoomDown_f },
// { "-zoom", CG_ZoomUp_f },
{ "sizeup", CG_SizeUp_f }, { "sizeup", CG_SizeUp_f },
{ "sizedown", CG_SizeDown_f }, { "sizedown", CG_SizeDown_f },
{ "weapnext", CG_NextWeapon_f }, { "weapnext", CG_NextWeapon_f },

File diff suppressed because it is too large Load diff

4453
CODE-mp/cgame/cg_draw.mrg Normal file

File diff suppressed because it is too large Load diff

View file

@ -624,6 +624,48 @@ void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t
CG_Text_Paint(x, y, 1.0, color, str, 0, 0, iStyle, iMenuFont); CG_Text_Paint(x, y, 1.0, color, str, 0, 0, iStyle, iMenuFont);
} }
void UI_DrawScaledProportionalString( int x, int y, const char* str, int style, vec4_t color, float scale)
{
// having all these different style defines (1 for UI, one for CG, and now one for the re->font stuff)
// is dumb, but for now...
//
int iStyle = 0;
switch (style & (UI_LEFT|UI_CENTER|UI_RIGHT))
{
default:
case UI_LEFT:
{
// nada...
}
break;
case UI_CENTER:
{
x -= CG_Text_Width(str, scale, FONT_MEDIUM) / 2;
}
break;
case UI_RIGHT:
{
x -= CG_Text_Width(str, scale, FONT_MEDIUM) / 2;
}
break;
}
if (style & UI_DROPSHADOW)
{
iStyle = ITEM_TEXTSTYLE_SHADOWED;
}
else
if ( style & (UI_BLINK|UI_PULSE) )
{
iStyle = ITEM_TEXTSTYLE_BLINK;
}
CG_Text_Paint(x, y, scale, color, str, 0, 0, iStyle, FONT_MEDIUM);
}

View file

@ -493,7 +493,7 @@ static void CG_General( centity_t *cent ) {
vec3_t beamOrg; vec3_t beamOrg;
mdxaBone_t matrix; mdxaBone_t matrix;
if (cent->currentState.modelGhoul2 == 999) if (cent->currentState.modelGhoul2 == 127)
{ //not ready to be drawn or initialized.. { //not ready to be drawn or initialized..
return; return;
} }
@ -1056,10 +1056,13 @@ Ghoul2 Insert End
VectorScale( ent.oldorigin, tempLength, ent.oldorigin ); VectorScale( ent.oldorigin, tempLength, ent.oldorigin );
ent.endTime = cent->dustTrailTime; ent.endTime = cent->dustTrailTime;
/*
ent.renderfx |= RF_DISINTEGRATE2; ent.renderfx |= RF_DISINTEGRATE2;
ent.customShader = cgs.media.disruptorShader; ent.customShader = cgs.media.disruptorShader;
trap_R_AddRefEntityToScene( &ent ); trap_R_AddRefEntityToScene( &ent );
*/
ent.renderfx &= ~(RF_DISINTEGRATE2); ent.renderfx &= ~(RF_DISINTEGRATE2);
ent.renderfx |= (RF_DISINTEGRATE1); ent.renderfx |= (RF_DISINTEGRATE1);
@ -1881,7 +1884,9 @@ Ghoul2 Insert End
if (s1->weapon != WP_SABER && s1->weapon != G2_MODEL_PART) if (s1->weapon != WP_SABER && s1->weapon != G2_MODEL_PART)
{ {
if ( cent->currentState.eFlags | EF_ALT_FIRING ) //if ( cent->currentState.eFlags | EF_ALT_FIRING )
//rww - why was this like this?
if ( cent->currentState.eFlags & EF_ALT_FIRING )
{ {
ent.hModel = weapon->altMissileModel; ent.hModel = weapon->altMissileModel;
} }
@ -2418,6 +2423,8 @@ void CG_AddPacketEntities( void ) {
//rww - update the g2 pointer BEFORE the weapons, otherwise bad things could happen //rww - update the g2 pointer BEFORE the weapons, otherwise bad things could happen
//FIXME: These two pointers seem to differ sometimes, they shouldn't, should they? //FIXME: These two pointers seem to differ sometimes, they shouldn't, should they?
//the one on predictedPlayerEntity also seems to often be invalid, so it can't be
//reliably checked and cleared.
cg.predictedPlayerEntity.ghoul2 = cg_entities[ cg.snap->ps.clientNum].ghoul2; cg.predictedPlayerEntity.ghoul2 = cg_entities[ cg.snap->ps.clientNum].ghoul2;
CG_CheckPlayerG2Weapons(ps, &cg.predictedPlayerEntity); CG_CheckPlayerG2Weapons(ps, &cg.predictedPlayerEntity);
BG_PlayerStateToEntityState( ps, &cg.predictedPlayerEntity.currentState, qfalse ); BG_PlayerStateToEntityState( ps, &cg.predictedPlayerEntity.currentState, qfalse );

View file

@ -25,40 +25,56 @@ Also called by scoreboard drawing
const char *CG_PlaceString( int rank ) { const char *CG_PlaceString( int rank ) {
static char str[64]; static char str[64];
char *s, *t; char *s, *t;
// number extenstions, eg 1st, 2nd, 3rd, 4th etc.
// note that the rules are different for french, but by changing the required strip strings they seem to work
char sST[10];
char sND[10];
char sRD[10];
char sTH[10];
char sTiedFor[64]; // german is much longer, super safe...
trap_SP_GetStringTextString("INGAMETEXT_NUMBER_ST",sST, sizeof(sST) );
trap_SP_GetStringTextString("INGAMETEXT_NUMBER_ND",sND, sizeof(sND) );
trap_SP_GetStringTextString("INGAMETEXT_NUMBER_RD",sRD, sizeof(sRD) );
trap_SP_GetStringTextString("INGAMETEXT_NUMBER_TH",sTH, sizeof(sTH) );
trap_SP_GetStringTextString("INGAMETEXT_TIED_FOR" ,sTiedFor,sizeof(sTiedFor) );
strcat(sTiedFor," "); // save worrying about translators adding spaces or not
if ( rank & RANK_TIED_FLAG ) { if ( rank & RANK_TIED_FLAG ) {
rank &= ~RANK_TIED_FLAG; rank &= ~RANK_TIED_FLAG;
t = "Tied for "; t = sTiedFor;//"Tied for ";
} else { } else {
t = ""; t = "";
} }
if ( rank == 1 ) { if ( rank == 1 ) {
s = "1st";//S_COLOR_BLUE "1st" S_COLOR_WHITE; // draw in blue s = va("1%s",sST);//S_COLOR_BLUE "1st" S_COLOR_WHITE; // draw in blue
} else if ( rank == 2 ) { } else if ( rank == 2 ) {
s = "2nd";//S_COLOR_RED "2nd" S_COLOR_WHITE; // draw in red s = va("2%s",sND);//S_COLOR_RED "2nd" S_COLOR_WHITE; // draw in red
} else if ( rank == 3 ) { } else if ( rank == 3 ) {
s = "3rd";//S_COLOR_YELLOW "3rd" S_COLOR_WHITE; // draw in yellow s = va("3%s",sRD);//S_COLOR_YELLOW "3rd" S_COLOR_WHITE; // draw in yellow
} else if ( rank == 11 ) { } else if ( rank == 11 ) {
s = "11th"; s = va("11%s",sTH);
} else if ( rank == 12 ) { } else if ( rank == 12 ) {
s = "12th"; s = va("12%s",sTH);
} else if ( rank == 13 ) { } else if ( rank == 13 ) {
s = "13th"; s = va("13%s",sTH);
} else if ( rank % 10 == 1 ) { } else if ( rank % 10 == 1 ) {
s = va("%ist", rank); s = va("%i%s", rank,sST);
} else if ( rank % 10 == 2 ) { } else if ( rank % 10 == 2 ) {
s = va("%ind", rank); s = va("%i%s", rank,sND);
} else if ( rank % 10 == 3 ) { } else if ( rank % 10 == 3 ) {
s = va("%ird", rank); s = va("%i%s", rank,sRD);
} else { } else {
s = va("%ith", rank); s = va("%i%s", rank,sTH);
} }
Com_sprintf( str, sizeof( str ), "%s%s", t, s ); Com_sprintf( str, sizeof( str ), "%s%s", t, s );
return str; return str;
} }
qboolean CG_ThereIsAMaster(void);
/* /*
============= =============
CG_Obituary CG_Obituary
@ -163,6 +179,14 @@ static void CG_Obituary( entityState_t *ent ) {
else else
message = "SUICIDE_ELECTROCUTED_MALE"; message = "SUICIDE_ELECTROCUTED_MALE";
break; break;
case MOD_FALLING:
if ( gender == GENDER_FEMALE )
message = "SUICIDE_FALLDEATH_FEMALE";
else if ( gender == GENDER_NEUTER )
message = "SUICIDE_FALLDEATH_GENDERLESS";
else
message = "SUICIDE_FALLDEATH_MALE";
break;
default: default:
if ( gender == GENDER_FEMALE ) if ( gender == GENDER_FEMALE )
message = "SUICIDE_GENERICDEATH_FEMALE"; message = "SUICIDE_GENERICDEATH_FEMALE";
@ -203,29 +227,50 @@ clientkilled:
if ( attacker == cg.snap->ps.clientNum ) { if ( attacker == cg.snap->ps.clientNum ) {
char *s; char *s;
if ( cgs.gametype < GT_TEAM ) { if ( cgs.gametype < GT_TEAM && cgs.gametype != GT_TOURNAMENT ) {
if (cgs.gametype == GT_JEDIMASTER && if (cgs.gametype == GT_JEDIMASTER &&
attacker < MAX_CLIENTS && attacker < MAX_CLIENTS &&
!ent->isJediMaster && !ent->isJediMaster &&
!cg.snap->ps.isJediMaster) !cg.snap->ps.isJediMaster &&
CG_ThereIsAMaster())
{ {
char part1[512]; char part1[512];
char part2[512]; char part2[512];
const char *kmsg1 = CG_GetStripEdString("INGAMETEXT", "KILLED_MESSAGE"); trap_SP_GetStringTextString("INGAMETEXT_KILLED_MESSAGE", part1, sizeof(part1));
strcpy(part1, kmsg1); trap_SP_GetStringTextString("INGAMETEXT_JMKILLED_NOTJM", part2, sizeof(part2));
kmsg1 = CG_GetStripEdString("INGAMETEXT", "JMKILLED_NOTJM"); s = va("%s %s\n%s\n", part1, targetName, part2);
}
else if (cgs.gametype == GT_JEDIMASTER &&
attacker < MAX_CLIENTS &&
!ent->isJediMaster &&
!cg.snap->ps.isJediMaster)
{ //no JM, saber must be out
char part1[512];
trap_SP_GetStringTextString("INGAMETEXT_KILLED_MESSAGE", part1, sizeof(part1));
/*
kmsg1 = "for 0 points.\nGo for the saber!";
strcpy(part2, kmsg1); strcpy(part2, kmsg1);
s = va("%s %s %s\n", part1, targetName, part2); s = va("%s %s %s\n", part1, targetName, part2);
*/
s = va("%s %s\n", part1, targetName);
} }
else else
{ {
s = va("%s %s.\n%s place with %i.", (char *)CG_GetStripEdString("INGAMETEXT", "KILLED_MESSAGE"), targetName, char sPlaceWith[256];
CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ), char sKilledStr[256];
trap_SP_GetStringTextString("INGAMETEXT_PLACE_WITH", sPlaceWith, sizeof(sPlaceWith));
trap_SP_GetStringTextString("INGAMETEXT_KILLED_MESSAGE", sKilledStr, sizeof(sKilledStr));
s = va("%s %s.\n%s %s %i.", sKilledStr, targetName,
CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ),
sPlaceWith,
cg.snap->ps.persistant[PERS_SCORE] ); cg.snap->ps.persistant[PERS_SCORE] );
} }
} else { } else {
s = va("%s %s", (char *)CG_GetStripEdString("INGAMETEXT", "KILLED_MESSAGE"), targetName ); char sKilledStr[256];
trap_SP_GetStringTextString("INGAMETEXT_KILLED_MESSAGE", sKilledStr, sizeof(sKilledStr));
s = va("%s %s", sKilledStr, targetName );
} }
if (!(cg_singlePlayerActive.integer && cg_cameraOrbit.integer)) { if (!(cg_singlePlayerActive.integer && cg_cameraOrbit.integer)) {
CG_CenterPrint( s, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH ); CG_CenterPrint( s, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
@ -427,6 +472,9 @@ static void CG_UseItem( centity_t *cent ) {
break; break;
case HI_SEEKER: case HI_SEEKER:
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.deploySeeker );
break;
case HI_SHIELD: case HI_SHIELD:
case HI_DATAPAD: case HI_DATAPAD:
case HI_SENTRY_GUN: case HI_SENTRY_GUN:
@ -480,7 +528,8 @@ static void CG_ItemPickup( int itemNum ) {
bg_itemlist[itemNum].giTag != WP_DET_PACK && bg_itemlist[itemNum].giTag != WP_DET_PACK &&
bg_itemlist[itemNum].giTag != WP_THERMAL && bg_itemlist[itemNum].giTag != WP_THERMAL &&
bg_itemlist[itemNum].giTag != WP_ROCKET_LAUNCHER && bg_itemlist[itemNum].giTag != WP_ROCKET_LAUNCHER &&
bg_itemlist[itemNum].giTag > cg.snap->ps.weapon) bg_itemlist[itemNum].giTag > cg.snap->ps.weapon &&
cg.snap->ps.weapon != WP_SABER)
{ {
if (!cg.snap->ps.emplacedIndex) if (!cg.snap->ps.emplacedIndex)
{ {
@ -491,7 +540,8 @@ static void CG_ItemPickup( int itemNum ) {
} }
else if ( cg_autoswitch.integer == 2) else if ( cg_autoswitch.integer == 2)
{ //autoselect if better { //autoselect if better
if (bg_itemlist[itemNum].giTag > cg.snap->ps.weapon) if (bg_itemlist[itemNum].giTag > cg.snap->ps.weapon &&
cg.snap->ps.weapon != WP_SABER)
{ {
if (!cg.snap->ps.emplacedIndex) if (!cg.snap->ps.emplacedIndex)
{ {
@ -500,6 +550,7 @@ static void CG_ItemPickup( int itemNum ) {
cg.weaponSelect = bg_itemlist[itemNum].giTag; cg.weaponSelect = bg_itemlist[itemNum].giTag;
} }
} }
/*
else if ( cg_autoswitch.integer == 3) else if ( cg_autoswitch.integer == 3)
{ //autoselect if better and not using the saber as a weapon { //autoselect if better and not using the saber as a weapon
if (bg_itemlist[itemNum].giTag > cg.snap->ps.weapon && if (bg_itemlist[itemNum].giTag > cg.snap->ps.weapon &&
@ -512,15 +563,24 @@ static void CG_ItemPickup( int itemNum ) {
cg.weaponSelect = bg_itemlist[itemNum].giTag; cg.weaponSelect = bg_itemlist[itemNum].giTag;
} }
} }
*/
//No longer required - just not switching ever if using saber
} }
//rww - print pickup messages //rww - print pickup messages
if (bg_itemlist[itemNum].pickup_name && bg_itemlist[itemNum].pickup_name[0] && if (bg_itemlist[itemNum].classname && bg_itemlist[itemNum].classname[0] &&
(bg_itemlist[itemNum].giType != IT_TEAM || (bg_itemlist[itemNum].giTag != PW_REDFLAG && bg_itemlist[itemNum].giTag != PW_BLUEFLAG)) ) (bg_itemlist[itemNum].giType != IT_TEAM || (bg_itemlist[itemNum].giTag != PW_REDFLAG && bg_itemlist[itemNum].giTag != PW_BLUEFLAG)) )
{ //don't print messages for flags, they have their own pickup event broadcasts { //don't print messages for flags, they have their own pickup event broadcasts
const char *strText = CG_GetStripEdString("INGAMETEXT", "PICKUPLINE"); char text[1024];
Com_Printf("%s %s\n", strText, bg_itemlist[itemNum].pickup_name); if ( trap_SP_GetStringTextString( va("INGAME_%s",bg_itemlist[itemNum].classname), text, sizeof( text )))
{
Com_Printf("%s %s\n", CG_GetStripEdString("INGAMETEXT", "PICKUPLINE"), text);
}
else
{
Com_Printf("%s %s\n", CG_GetStripEdString("INGAMETEXT", "PICKUPLINE"), bg_itemlist[itemNum].classname);
}
} }
} }
@ -867,6 +927,40 @@ void DoFall(centity_t *cent, entityState_t *es, int clientNum)
cg.landTime = cg.time; cg.landTime = cg.time;
} }
} }
int CG_InClientBitflags(entityState_t *ent, int client)
{
int checkIn;
int sub = 0;
if (client > 47)
{
checkIn = ent->trickedentindex4;
sub = 48;
}
else if (client > 31)
{
checkIn = ent->trickedentindex3;
sub = 32;
}
else if (client > 15)
{
checkIn = ent->trickedentindex2;
sub = 16;
}
else
{
checkIn = ent->trickedentindex;
}
if (checkIn & (1 << (client-sub)))
{
return 1;
}
return 0;
}
/* /*
============== ==============
CG_EntityEvent CG_EntityEvent
@ -936,6 +1030,8 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
cl_ent->trickAlphaTime = 0; cl_ent->trickAlphaTime = 0;
cl_ent->ghoul2weapon = NULL; cl_ent->ghoul2weapon = NULL;
cl_ent->weapon = WP_NONE; cl_ent->weapon = WP_NONE;
cl_ent->teamPowerEffectTime = 0;
cl_ent->teamPowerType = 0;
} }
break; break;
@ -1036,7 +1132,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
{ //starting the duel { //starting the duel
if (es->eventParm == 2) if (es->eventParm == 2)
{ {
CG_CenterPrint( "BEGIN", 120, GIANTCHAR_WIDTH*2 ); CG_CenterPrint( CG_GetStripEdString("SVINGAME", "BEGIN_DUEL"), 120, GIANTCHAR_WIDTH*2 );
trap_S_StartLocalSound( cgs.media.countFightSound, CHAN_ANNOUNCER ); trap_S_StartLocalSound( cgs.media.countFightSound, CHAN_ANNOUNCER );
} }
else else
@ -1135,7 +1231,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
const char *strText = CG_GetStripEdString("INGAMETEXT", "PICKUPLINE"); const char *strText = CG_GetStripEdString("INGAMETEXT", "PICKUPLINE");
//Com_Printf("%s %s\n", strText, showPowersName[index]); //Com_Printf("%s %s\n", strText, showPowersName[index]);
CG_CenterPrint( va("%s %s\n", strText, showPowersName[index]), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH ); CG_CenterPrint( va("%s %s\n", strText, CG_GetStripEdString("INGAME",showPowersName[index])), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
} }
//Show the player their force selection bar in case picking the holocron up changed the current selection //Show the player their force selection bar in case picking the holocron up changed the current selection
@ -1178,7 +1274,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
} }
item = &bg_itemlist[ index ]; item = &bg_itemlist[ index ];
if ( item->giType != IT_POWERUP && item->giType != IT_TEAM) { if ( /*item->giType != IT_POWERUP && */item->giType != IT_TEAM) {
if (item->pickup_sound && item->pickup_sound[0]) if (item->pickup_sound && item->pickup_sound[0])
{ {
trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound ) ); trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound ) );
@ -1421,6 +1517,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
if (cg.snap->ps.clientNum == es->number) if (cg.snap->ps.clientNum == es->number)
{ {
trap_S_StartLocalSound(cgs.media.happyMusic, CHAN_LOCAL); trap_S_StartLocalSound(cgs.media.happyMusic, CHAN_LOCAL);
CGCam_SetMusicMult(0.3, 5000);
} }
} }
break; break;
@ -1499,6 +1596,69 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
} }
} }
break; break;
case EV_PREDEFSOUND:
DEBUGNAME("EV_PREDEFSOUND");
{
int sID = -1;
switch (es->eventParm)
{
case PDSOUND_PROTECTHIT:
sID = trap_S_RegisterSound("sound/weapons/force/protecthit.mp3");
break;
case PDSOUND_PROTECT:
sID = trap_S_RegisterSound("sound/weapons/force/protect.mp3");
break;
case PDSOUND_ABSORBHIT:
sID = trap_S_RegisterSound("sound/weapons/force/absorbhit.mp3");
break;
case PDSOUND_ABSORB:
sID = trap_S_RegisterSound("sound/weapons/force/absorb.mp3");
break;
case PDSOUND_FORCEJUMP:
sID = trap_S_RegisterSound("sound/weapons/force/jump.mp3");
break;
case PDSOUND_FORCEGRIP:
sID = trap_S_RegisterSound("sound/weapons/force/grip.mp3");
break;
default:
break;
}
if (sID != 1)
{
trap_S_StartSound(es->origin, es->number, CHAN_AUTO, sID);
}
}
break;
case EV_TEAM_POWER:
DEBUGNAME("EV_TEAM_POWER");
{
int clnum = 0;
while (clnum < MAX_CLIENTS)
{
if (CG_InClientBitflags(es, clnum))
{
if (es->eventParm == 1)
{ //eventParm 1 is heal
trap_S_StartSound (NULL, clnum, CHAN_AUTO, cgs.media.teamHealSound );
cg_entities[clnum].teamPowerEffectTime = cg.time + 1000;
cg_entities[clnum].teamPowerType = 1;
}
else
{ //eventParm 2 is force regen
trap_S_StartSound (NULL, clnum, CHAN_AUTO, cgs.media.teamRegenSound );
cg_entities[clnum].teamPowerEffectTime = cg.time + 1000;
cg_entities[clnum].teamPowerType = 0;
}
}
clnum++;
}
}
break;
case EV_SCREENSHAKE: case EV_SCREENSHAKE:
DEBUGNAME("EV_SCREENSHAKE"); DEBUGNAME("EV_SCREENSHAKE");
if (!es->modelindex || cg.predictedPlayerState.clientNum == es->modelindex-1) if (!es->modelindex || cg.predictedPlayerState.clientNum == es->modelindex-1)
@ -1700,6 +1860,13 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
DEBUGNAME("EV_DESTROY_GHOUL2_INSTANCE"); DEBUGNAME("EV_DESTROY_GHOUL2_INSTANCE");
if (cg_entities[es->eventParm].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[es->eventParm].ghoul2)) if (cg_entities[es->eventParm].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[es->eventParm].ghoul2))
{ {
if (es->eventParm < MAX_CLIENTS)
{ //You try to do very bad thing!
#ifdef _DEBUG
Com_Printf("WARNING: Tried to kill a client ghoul2 instance with a server event!\n");
#endif
break;
}
trap_G2API_CleanGhoul2Models(&(cg_entities[es->eventParm].ghoul2)); trap_G2API_CleanGhoul2Models(&(cg_entities[es->eventParm].ghoul2));
} }
break; break;
@ -1719,7 +1886,12 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
{ {
trap_Cvar_Set("ui_rankChange", va("%i", es->eventParm)); trap_Cvar_Set("ui_rankChange", va("%i", es->eventParm));
trap_OpenUIMenu(3); trap_Cvar_Set("ui_myteam", va("%i", es->bolt2));
if (!( trap_Key_GetCatcher() & KEYCATCH_UI ) && !es->bolt1)
{
trap_OpenUIMenu(3);
}
} }
break; break;
@ -1729,6 +1901,12 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
trap_Cvar_Set("ui_freeSaber", va("%i", es->eventParm)); trap_Cvar_Set("ui_freeSaber", va("%i", es->eventParm));
break; break;
case EV_SET_FORCE_DISABLE:
DEBUGNAME("EV_SET_FORCE_DISABLE");
trap_Cvar_Set("ui_forcePowerDisable", va("%i", es->eventParm));
break;
// //
// missile impacts // missile impacts
// //
@ -2045,6 +2223,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
if (es->eventParm && es->number == cg.snap->ps.clientNum) if (es->eventParm && es->number == cg.snap->ps.clientNum)
{ {
trap_S_StartLocalSound(cgs.media.dramaticFailure, CHAN_LOCAL); trap_S_StartLocalSound(cgs.media.dramaticFailure, CHAN_LOCAL);
CGCam_SetMusicMult(0.3, 5000);
} }
break; break;
@ -2077,7 +2256,10 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
case EV_FORCE_DRAINED: case EV_FORCE_DRAINED:
DEBUGNAME("EV_FORCE_DRAINED"); DEBUGNAME("EV_FORCE_DRAINED");
ByteToDir( es->eventParm, dir ); ByteToDir( es->eventParm, dir );
FX_ForceDrained(position, dir); //FX_ForceDrained(position, dir);
trap_S_StartSound (NULL, es->owner, CHAN_AUTO, cgs.media.drainSound );
cg_entities[es->owner].teamPowerEffectTime = cg.time + 1000;
cg_entities[es->owner].teamPowerType = 2;
break; break;
case EV_GIB_PLAYER: case EV_GIB_PLAYER:
@ -2139,7 +2321,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
case EV_TESTLINE: case EV_TESTLINE:
DEBUGNAME("EV_TESTLINE"); DEBUGNAME("EV_TESTLINE");
CG_TestLine(es->origin, es->origin2, es->trickedentindex, es->weapon, 1); CG_TestLine(es->origin, es->origin2, es->time2, es->weapon, 1);
break; break;
case EV_BODY_QUEUE_COPY: case EV_BODY_QUEUE_COPY:

View file

@ -7,39 +7,11 @@
#define MAX_LOADING_PLAYER_ICONS 16 #define MAX_LOADING_PLAYER_ICONS 16
#define MAX_LOADING_ITEM_ICONS 26 #define MAX_LOADING_ITEM_ICONS 26
static int loadingPlayerIconCount; //static int loadingPlayerIconCount;
static int loadingItemIconCount; //static qhandle_t loadingPlayerIcons[MAX_LOADING_PLAYER_ICONS];
static qhandle_t loadingPlayerIcons[MAX_LOADING_PLAYER_ICONS];
static qhandle_t loadingItemIcons[MAX_LOADING_ITEM_ICONS];
void CG_LoadBar(void); void CG_LoadBar(void);
/*
===================
CG_DrawLoadingIcons
===================
*/
static void CG_DrawLoadingIcons( void ) {
int n;
int x, y;
for( n = 0; n < loadingPlayerIconCount; n++ ) {
x = 16 + n * 78;
y = 324-40;
CG_DrawPic( x, y, 64, 64, loadingPlayerIcons[n] );
}
for( n = 0; n < loadingItemIconCount; n++ ) {
y = 400-40;
if( n >= 13 ) {
y += 40;
}
x = 16 + n % 13 * 48;
CG_DrawPic( x, y, 32, 32, loadingItemIcons[n] );
}
}
/* /*
====================== ======================
CG_LoadingString CG_LoadingString
@ -61,12 +33,8 @@ void CG_LoadingItem( int itemNum ) {
gitem_t *item; gitem_t *item;
item = &bg_itemlist[itemNum]; item = &bg_itemlist[itemNum];
if ( item->icon && loadingItemIconCount < MAX_LOADING_ITEM_ICONS ) {
loadingItemIcons[loadingItemIconCount++] = trap_R_RegisterShaderNoMip( item->icon );
}
CG_LoadingString( item->pickup_name ); CG_LoadingString( CG_GetStripEdString("INGAME",item->classname) );
} }
/* /*
@ -76,13 +44,14 @@ CG_LoadingClient
*/ */
void CG_LoadingClient( int clientNum ) { void CG_LoadingClient( int clientNum ) {
const char *info; const char *info;
char *skin;
char personality[MAX_QPATH]; char personality[MAX_QPATH];
char model[MAX_QPATH];
char iconName[MAX_QPATH];
info = CG_ConfigString( CS_PLAYERS + clientNum ); info = CG_ConfigString( CS_PLAYERS + clientNum );
/*
char model[MAX_QPATH];
char iconName[MAX_QPATH];
char *skin;
if ( loadingPlayerIconCount < MAX_LOADING_PLAYER_ICONS ) { if ( loadingPlayerIconCount < MAX_LOADING_PLAYER_ICONS ) {
Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) ); Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) );
skin = Q_strrchr( model, '/' ); skin = Q_strrchr( model, '/' );
@ -107,7 +76,7 @@ void CG_LoadingClient( int clientNum ) {
loadingPlayerIconCount++; loadingPlayerIconCount++;
} }
} }
*/
Q_strncpyz( personality, Info_ValueForKey( info, "n" ), sizeof(personality) ); Q_strncpyz( personality, Info_ValueForKey( info, "n" ), sizeof(personality) );
Q_CleanStr( personality ); Q_CleanStr( personality );
@ -128,6 +97,7 @@ CG_DrawInformation
Draw all the status / pacifier stuff during level loading Draw all the status / pacifier stuff during level loading
==================== ====================
*/ */
#define UI_INFOFONT (UI_BIGFONT)
void CG_DrawInformation( void ) { void CG_DrawInformation( void ) {
const char *s; const char *s;
const char *info; const char *info;
@ -156,11 +126,13 @@ void CG_DrawInformation( void ) {
// the first 150 rows are reserved for the client connection // the first 150 rows are reserved for the client connection
// screen to write into // screen to write into
if ( cg.infoScreenText[0] ) { if ( cg.infoScreenText[0] ) {
UI_DrawProportionalString( 320, 128-32, va("Loading... %s", cg.infoScreenText), const char *psLoading = CG_GetStripEdString("MENUS3", "LOADING_MAPNAME");
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_DrawProportionalString( 320, 128-32, va(/*"Loading... %s"*/ psLoading, cg.infoScreenText),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
} else { } else {
UI_DrawProportionalString( 320, 128-32, "Awaiting snapshot...", const char *psAwaitingSnapshot = CG_GetStripEdString("MENUS3", "AWAITING_SNAPSHOT");
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_DrawProportionalString( 320, 128-32, /*"Awaiting snapshot..."*/psAwaitingSnapshot,
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
} }
// draw info string information // draw info string information
@ -174,14 +146,15 @@ void CG_DrawInformation( void ) {
Q_strncpyz(buf, Info_ValueForKey( info, "sv_hostname" ), 1024); Q_strncpyz(buf, Info_ValueForKey( info, "sv_hostname" ), 1024);
Q_CleanStr(buf); Q_CleanStr(buf);
UI_DrawProportionalString( 320, y, buf, UI_DrawProportionalString( 320, y, buf,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
// pure server // pure server
s = Info_ValueForKey( sysInfo, "sv_pure" ); s = Info_ValueForKey( sysInfo, "sv_pure" );
if ( s[0] == '1' ) { if ( s[0] == '1' ) {
UI_DrawProportionalString( 320, y, "Pure Server", const char *psPure = CG_GetStripEdString("INGAMETEXT", "PURE_SERVER");
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_DrawProportionalString( 320, y, psPure,
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
@ -189,7 +162,7 @@ void CG_DrawInformation( void ) {
s = CG_ConfigString( CS_MOTD ); s = CG_ConfigString( CS_MOTD );
if ( s[0] ) { if ( s[0] ) {
UI_DrawProportionalString( 320, y, s, UI_DrawProportionalString( 320, y, s,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
@ -201,15 +174,15 @@ void CG_DrawInformation( void ) {
s = CG_ConfigString( CS_MESSAGE ); s = CG_ConfigString( CS_MESSAGE );
if ( s[0] ) { if ( s[0] ) {
UI_DrawProportionalString( 320, y, s, UI_DrawProportionalString( 320, y, s,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
// cheats warning // cheats warning
s = Info_ValueForKey( sysInfo, "sv_cheats" ); s = Info_ValueForKey( sysInfo, "sv_cheats" );
if ( s[0] == '1' ) { if ( s[0] == '1' ) {
UI_DrawProportionalString( 320, y, va("%s", (char *)CG_GetStripEdString("INGAMETEXT", "CHEATSAREENABLED")), UI_DrawProportionalString( 320, y, CG_GetStripEdString("INGAMETEXT", "CHEATSAREENABLED"),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
@ -234,34 +207,34 @@ void CG_DrawInformation( void ) {
s = "Team FFA"; s = "Team FFA";
break; break;
case GT_SAGA: case GT_SAGA:
s = "Saga"; s = "N/A";
break; break;
case GT_CTF: case GT_CTF:
s = "Capture The Flag"; s = "Capture The Flag";
break; break;
case GT_CTY: case GT_CTY:
s = "Capture The Ysalimari"; s = "Capture The Ysalamiri";
break; break;
default: default:
s = "Unknown Gametype"; s = "Unknown Gametype";
break; break;
} }
UI_DrawProportionalString( 320, y, s, UI_DrawProportionalString( 320, y, s,
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
value = atoi( Info_ValueForKey( info, "timelimit" ) ); value = atoi( Info_ValueForKey( info, "timelimit" ) );
if ( value ) { if ( value ) {
UI_DrawProportionalString( 320, y, va( "%s %i", (char *)CG_GetStripEdString("INGAMETEXT", "TIMELIMIT"), value ), UI_DrawProportionalString( 320, y, va( "%s %i", CG_GetStripEdString("INGAMETEXT", "TIMELIMIT"), value ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
if (cgs.gametype < GT_CTF ) { if (cgs.gametype < GT_CTF ) {
value = atoi( Info_ValueForKey( info, "fraglimit" ) ); value = atoi( Info_ValueForKey( info, "fraglimit" ) );
if ( value ) { if ( value ) {
UI_DrawProportionalString( 320, y, va( "%s %i", (char *)CG_GetStripEdString("INGAMETEXT", "FRAGLIMIT"), value ), UI_DrawProportionalString( 320, y, va( "%s %i", CG_GetStripEdString("INGAMETEXT", "FRAGLIMIT"), value ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
@ -269,8 +242,8 @@ void CG_DrawInformation( void ) {
{ {
value = atoi( Info_ValueForKey( info, "duel_fraglimit" ) ); value = atoi( Info_ValueForKey( info, "duel_fraglimit" ) );
if ( value ) { if ( value ) {
UI_DrawProportionalString( 320, y, va( "%s %i", (char *)CG_GetStripEdString("INGAMETEXT", "WINLIMIT"), value ), UI_DrawProportionalString( 320, y, va( "%s %i", CG_GetStripEdString("INGAMETEXT", "WINLIMIT"), value ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
} }
@ -279,8 +252,8 @@ void CG_DrawInformation( void ) {
if (cgs.gametype >= GT_CTF) { if (cgs.gametype >= GT_CTF) {
value = atoi( Info_ValueForKey( info, "capturelimit" ) ); value = atoi( Info_ValueForKey( info, "capturelimit" ) );
if ( value ) { if ( value ) {
UI_DrawProportionalString( 320, y, va( "%s %i", (char *)CG_GetStripEdString("INGAMETEXT", "CAPTURELIMIT"), value ), UI_DrawProportionalString( 320, y, va( "%s %i", CG_GetStripEdString("INGAMETEXT", "CAPTURELIMIT"), value ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
} }
@ -289,8 +262,8 @@ void CG_DrawInformation( void ) {
{ {
value = atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) ); value = atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) );
if ( value ) { if ( value ) {
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "FORCEBASEDTEAMS") ), UI_DrawProportionalString( 320, y, CG_GetStripEdString("INGAMETEXT", "FORCEBASEDTEAMS"),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
} }
@ -299,29 +272,108 @@ void CG_DrawInformation( void ) {
value = atoi( Info_ValueForKey( info, "g_maxForceRank" ) ); value = atoi( Info_ValueForKey( info, "g_maxForceRank" ) );
if ( value && !valueNOFP ) { if ( value && !valueNOFP ) {
UI_DrawProportionalString( 320, y, va( "%s %i", (char *)CG_GetStripEdString("INGAMETEXT", "MAXFORCERANK"), value ), char fmStr[1024];
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite );
trap_SP_GetStringTextString("INGAMETEXT_MAXFORCERANK",fmStr, sizeof(fmStr));
UI_DrawProportionalString( 320, y, va( "%s %s", fmStr, CG_GetStripEdString("INGAMETEXT", forceMasteryLevels[value]) ),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
else if (!valueNOFP) else if (!valueNOFP)
{ {
UI_DrawProportionalString( 320, y, va( "%s 20", (char *)CG_GetStripEdString("INGAMETEXT", "MAXFORCERANK") ), char fmStr[1024];
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); trap_SP_GetStringTextString("INGAMETEXT_MAXFORCERANK",fmStr, sizeof(fmStr));
UI_DrawProportionalString( 320, y, va( "%s %s", fmStr, (char *)CG_GetStripEdString("INGAMETEXT", forceMasteryLevels[7]) ),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
value = atoi( Info_ValueForKey( info, "g_weaponDisable" ) ); if (cgs.gametype == GT_TOURNAMENT)
{
value = atoi( Info_ValueForKey( info, "g_duelWeaponDisable" ) );
}
else
{
value = atoi( Info_ValueForKey( info, "g_weaponDisable" ) );
}
if ( cgs.gametype != GT_JEDIMASTER && value ) { if ( cgs.gametype != GT_JEDIMASTER && value ) {
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "SABERONLYSET") ), UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "SABERONLYSET") ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
if ( valueNOFP ) { if ( valueNOFP ) {
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "NOFPSET") ), UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "NOFPSET") ),
UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, colorWhite ); UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT; y += PROP_HEIGHT;
} }
// Display the rules based on type
y += PROP_HEIGHT;
switch ( cgs.gametype ) {
case GT_FFA:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_FFA_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
break;
case GT_HOLOCRON:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_HOLO_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_HOLO_2")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
break;
case GT_JEDIMASTER:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_JEDI_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_JEDI_2")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
break;
case GT_SINGLE_PLAYER:
break;
case GT_TOURNAMENT:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_DUEL_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_DUEL_2")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
break;
case GT_TEAM:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_TEAM_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_TEAM_2")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
break;
case GT_SAGA:
break;
case GT_CTF:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_CTF_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_CTF_2")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
break;
case GT_CTY:
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_CTY_1")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
UI_DrawProportionalString( 320, y, va( "%s", (char *)CG_GetStripEdString("INGAMETEXT", "RULES_CTY_2")),
UI_CENTER|UI_INFOFONT|UI_DROPSHADOW, colorWhite );
y += PROP_HEIGHT;
break;
default:
break;
}
} }
/* /*
@ -331,20 +383,24 @@ CG_LoadBar
*/ */
void CG_LoadBar(void) void CG_LoadBar(void)
{ {
int x,y,i,xLength,height,pad; const int numticks = 9, tickwidth = 40, tickheight = 8;
const int tickpadx = 20, tickpady = 12;
y = 442; const int capwidth = 8;
pad = 5; const int barwidth = numticks*tickwidth+tickpadx*2+capwidth*2, barleft = ((640-barwidth)/2);
x = 202 + pad; const int barheight = tickheight + tickpady*2, bartop = 480-barheight;
height = 12; const int capleft = barleft+tickpadx, tickleft = capleft+capwidth, ticktop = bartop+tickpady;
xLength = 21;
trap_R_SetColor( colorWhite ); trap_R_SetColor( colorWhite );
CG_DrawPic(166,428,640-(164*2), 32, cgs.media.loadBarLEDSurround); // Draw background
CG_DrawPic(barleft, bartop, barwidth, barheight, cgs.media.loadBarLEDSurround);
for (i=0;i < cg.loadLCARSStage;i++) // Draw left cap (backwards)
{ CG_DrawPic(tickleft, ticktop, -capwidth, tickheight, cgs.media.loadBarLEDCap);
CG_DrawPic(x + (i*pad) + (i*xLength),y, 32, 8, cgs.media.loadBarLED);
} // Draw bar
CG_DrawPic(tickleft, ticktop, tickwidth*cg.loadLCARSStage, tickheight, cgs.media.loadBarLED);
// Draw right cap
CG_DrawPic(tickleft+tickwidth*cg.loadLCARSStage, ticktop, capwidth, tickheight, cgs.media.loadBarLEDCap);
} }

View file

@ -78,7 +78,6 @@
#define DEFAULT_MODEL "kyle" #define DEFAULT_MODEL "kyle"
#define DEFAULT_TEAM_MODEL "kyle" #define DEFAULT_TEAM_MODEL "kyle"
#define DEFAULT_TEAM_HEAD "kyle"
#define DEFAULT_FORCEPOWERS "5-1-000000000000000000" #define DEFAULT_FORCEPOWERS "5-1-000000000000000000"
//"rank-side-heal.lev.speed.push.pull.tele.grip.lightning.rage.protect.absorb.teamheal.teamforce.drain.see" //"rank-side-heal.lev.speed.push.pull.tele.grip.lightning.rage.protect.absorb.teamheal.teamforce.drain.see"
@ -234,6 +233,9 @@ typedef struct centity_s {
int trickAlpha; int trickAlpha;
int trickAlphaTime; int trickAlphaTime;
int teamPowerEffectTime;
qboolean teamPowerType; //0 regen, 1 heal, 2 drain
} centity_t; } centity_t;
@ -482,8 +484,8 @@ typedef struct {
// gameplay // gameplay
char modelName[MAX_QPATH]; char modelName[MAX_QPATH];
char skinName[MAX_QPATH]; char skinName[MAX_QPATH];
char headModelName[MAX_QPATH]; // char headModelName[MAX_QPATH];
char headSkinName[MAX_QPATH]; // char headSkinName[MAX_QPATH];
char forcePowers[MAX_QPATH]; char forcePowers[MAX_QPATH];
char redTeam[MAX_TEAMNAME]; char redTeam[MAX_TEAMNAME];
char blueTeam[MAX_TEAMNAME]; char blueTeam[MAX_TEAMNAME];
@ -506,8 +508,8 @@ typedef struct {
qhandle_t torsoModel; qhandle_t torsoModel;
qhandle_t torsoSkin; qhandle_t torsoSkin;
qhandle_t headModel; //qhandle_t headModel;
qhandle_t headSkin; //qhandle_t headSkin;
qboolean ATST; qboolean ATST;
@ -874,20 +876,22 @@ extern forceTicPos_t ammoTicPos[];
typedef struct cgscreffects_s typedef struct cgscreffects_s
{ {
float FOV; float FOV;
float FOV2; float FOV2;
float shake_intensity; float shake_intensity;
int shake_duration; int shake_duration;
int shake_start; int shake_start;
float music_volume_mulitplier; float music_volume_multiplier;
int music_volume_time; int music_volume_time;
qboolean music_volume_set;
} cgscreffects_t; } cgscreffects_t;
extern cgscreffects_t cgScreenEffects; extern cgscreffects_t cgScreenEffects;
void CGCam_Shake( float intensity, int duration ); void CGCam_Shake( float intensity, int duration );
void CGCam_SetMusicMult( float multiplier, int duration );
// all of the model, shader, and sound references that are // all of the model, shader, and sound references that are
// loaded at gamestate time are stored in cgMedia_t // loaded at gamestate time are stored in cgMedia_t
@ -898,6 +902,7 @@ typedef struct {
qhandle_t whiteShader; qhandle_t whiteShader;
qhandle_t loadBarLED; qhandle_t loadBarLED;
qhandle_t loadBarLEDCap;
qhandle_t loadBarLEDSurround; qhandle_t loadBarLEDSurround;
qhandle_t bryarFrontFlash; qhandle_t bryarFrontFlash;
@ -990,6 +995,8 @@ typedef struct {
// Pain view shader // Pain view shader
qhandle_t viewPainShader; qhandle_t viewPainShader;
qhandle_t viewPainShader_Shields;
qhandle_t viewPainShader_ShieldsAndHealth;
// powerup shaders // powerup shaders
qhandle_t quadShader; qhandle_t quadShader;
@ -1006,6 +1013,8 @@ typedef struct {
qhandle_t playerShieldDamage; qhandle_t playerShieldDamage;
qhandle_t forceSightBubble; qhandle_t forceSightBubble;
qhandle_t forceShell;
qhandle_t sightShell;
// Disruptor zoom graphics // Disruptor zoom graphics
qhandle_t disruptorMask; qhandle_t disruptorMask;
@ -1035,6 +1044,15 @@ typedef struct {
qhandle_t heartShader; qhandle_t heartShader;
// All the player shells
qhandle_t ysaliredShader;
qhandle_t ysaliblueShader;
qhandle_t ysalimariShader;
qhandle_t boonShader;
qhandle_t endarkenmentShader;
qhandle_t enlightenmentShader;
qhandle_t invulnerabilityShader;
#ifdef JK2AWARDS #ifdef JK2AWARDS
// medals shown during gameplay // medals shown during gameplay
qhandle_t medalImpressive; qhandle_t medalImpressive;
@ -1057,6 +1075,9 @@ typedef struct {
sfxHandle_t grenadeBounce1; sfxHandle_t grenadeBounce1;
sfxHandle_t grenadeBounce2; sfxHandle_t grenadeBounce2;
sfxHandle_t teamHealSound;
sfxHandle_t teamRegenSound;
sfxHandle_t teleInSound; sfxHandle_t teleInSound;
sfxHandle_t teleOutSound; sfxHandle_t teleOutSound;
sfxHandle_t respawnSound; sfxHandle_t respawnSound;
@ -1089,6 +1110,7 @@ typedef struct {
sfxHandle_t watrOutSound; sfxHandle_t watrOutSound;
sfxHandle_t watrUnSound; sfxHandle_t watrUnSound;
sfxHandle_t deploySeeker;
sfxHandle_t medkitSound; sfxHandle_t medkitSound;
// teamplay sounds // teamplay sounds
@ -1111,6 +1133,8 @@ typedef struct {
sfxHandle_t redTookYsalSound; sfxHandle_t redTookYsalSound;
sfxHandle_t blueTookYsalSound; sfxHandle_t blueTookYsalSound;
sfxHandle_t drainSound;
//music blips //music blips
sfxHandle_t happyMusic; sfxHandle_t happyMusic;
sfxHandle_t dramaticFailure; sfxHandle_t dramaticFailure;
@ -1288,6 +1312,7 @@ typedef struct {
int dmflags; int dmflags;
int teamflags; int teamflags;
int fraglimit; int fraglimit;
int duel_fraglimit;
int capturelimit; int capturelimit;
int timelimit; int timelimit;
int maxclients; int maxclients;
@ -1311,6 +1336,9 @@ typedef struct {
int scores1, scores2; // from configstrings int scores1, scores2; // from configstrings
int jediMaster; int jediMaster;
int duelWinner;
int duelist1;
int duelist2;
int redflag, blueflag; // flag status from configstrings int redflag, blueflag; // flag status from configstrings
int flagStatus; int flagStatus;
@ -1430,6 +1458,8 @@ extern vmCvar_t cg_simpleItems;
extern vmCvar_t cg_fov; extern vmCvar_t cg_fov;
extern vmCvar_t cg_zoomFov; extern vmCvar_t cg_zoomFov;
extern vmCvar_t cg_swingAngles;
extern vmCvar_t cg_saberContact; extern vmCvar_t cg_saberContact;
extern vmCvar_t cg_saberTrail; extern vmCvar_t cg_saberTrail;
@ -1469,6 +1499,7 @@ extern vmCvar_t cg_teamChatsOnly;
extern vmCvar_t cg_noVoiceChats; extern vmCvar_t cg_noVoiceChats;
extern vmCvar_t cg_noVoiceText; extern vmCvar_t cg_noVoiceText;
extern vmCvar_t cg_scorePlum; extern vmCvar_t cg_scorePlum;
extern vmCvar_t cg_hudFiles;
extern vmCvar_t cg_smoothClients; extern vmCvar_t cg_smoothClients;
extern vmCvar_t pmove_fixed; extern vmCvar_t pmove_fixed;
extern vmCvar_t pmove_msec; extern vmCvar_t pmove_msec;
@ -1495,6 +1526,8 @@ extern vmCvar_t cg_enableBreath;
extern vmCvar_t cg_singlePlayerActive; extern vmCvar_t cg_singlePlayerActive;
extern vmCvar_t cg_recordSPDemo; extern vmCvar_t cg_recordSPDemo;
extern vmCvar_t cg_recordSPDemoName; extern vmCvar_t cg_recordSPDemoName;
extern vmCvar_t ui_myteam;
/* /*
Ghoul2 Insert Start Ghoul2 Insert Start
*/ */
@ -1589,6 +1622,7 @@ void CG_ColorForHealth( vec4_t hcolor );
void CG_GetColorForHealth( int health, int armor, vec4_t hcolor ); void CG_GetColorForHealth( int health, int armor, vec4_t hcolor );
void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color ); void UI_DrawProportionalString( int x, int y, const char* str, int style, vec4_t color );
void UI_DrawScaledProportionalString( int x, int y, const char* str, int style, vec4_t color, float scale);
void CG_DrawRect( float x, float y, float width, float height, float size, const float *color ); 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_DrawSides(float x, float y, float w, float h, float size);
void CG_DrawTopBottom(float x, float y, float w, float h, float size); void CG_DrawTopBottom(float x, float y, float w, float h, float size);
@ -1619,6 +1653,7 @@ void CG_SelectNextPlayer(void);
float CG_GetValue(int ownerDraw); float CG_GetValue(int ownerDraw);
qboolean CG_OwnerDrawVisible(int flags); qboolean CG_OwnerDrawVisible(int flags);
void CG_RunMenuScript(char **args); void CG_RunMenuScript(char **args);
qboolean CG_DeferMenuScript(char **args);
void CG_ShowResponseHead(void); void CG_ShowResponseHead(void);
void CG_SetPrintString(int type, const char *p); void CG_SetPrintString(int type, const char *p);
void CG_InitTeamChat(void); void CG_InitTeamChat(void);
@ -2057,7 +2092,7 @@ void trap_FX_PlayBoltedEffectID( int id, sharedBoltInterface_t *fxObj );
void trap_FX_AddScheduledEffects( void ); void trap_FX_AddScheduledEffects( void );
int trap_FX_InitSystem( void ); // called in CG_Init to purge the fx system. int trap_FX_InitSystem( void ); // called in CG_Init to purge the fx system.
qboolean trap_FX_FreeSystem( void ); // ditches all active effects; qboolean trap_FX_FreeSystem( void ); // ditches all active effects;
void trap_FX_AdjustTime( int time ); void trap_FX_AdjustTime( int time, vec3_t vieworg, vec3_t viewaxis[3] );
void trap_FX_AddPoly( addpolyArgStruct_t *p ); void trap_FX_AddPoly( addpolyArgStruct_t *p );
void trap_FX_AddBezier( addbezierArgStruct_t *p ); void trap_FX_AddBezier( addbezierArgStruct_t *p );

View file

@ -409,6 +409,8 @@ vmCvar_t cg_simpleItems;
vmCvar_t cg_fov; vmCvar_t cg_fov;
vmCvar_t cg_zoomFov; vmCvar_t cg_zoomFov;
vmCvar_t cg_swingAngles;
vmCvar_t cg_saberContact; vmCvar_t cg_saberContact;
vmCvar_t cg_saberTrail; vmCvar_t cg_saberTrail;
@ -485,6 +487,8 @@ vmCvar_t cg_singlePlayerActive;
vmCvar_t cg_recordSPDemo; vmCvar_t cg_recordSPDemo;
vmCvar_t cg_recordSPDemoName; vmCvar_t cg_recordSPDemoName;
vmCvar_t ui_myteam;
typedef struct { typedef struct {
vmCvar_t *vmCvar; vmCvar_t *vmCvar;
char *cvarName; char *cvarName;
@ -547,6 +551,8 @@ static cvarTable_t cvarTable[] = { // bk001129
{ &cg_tracerWidth, "cg_tracerwidth", "1", CVAR_CHEAT }, { &cg_tracerWidth, "cg_tracerwidth", "1", CVAR_CHEAT },
{ &cg_tracerLength, "cg_tracerlength", "100", CVAR_CHEAT }, { &cg_tracerLength, "cg_tracerlength", "100", CVAR_CHEAT },
{ &cg_swingAngles, "cg_swingAngles", "1", 0 },
{ &cg_saberContact, "cg_saberContact", "1", 0 }, { &cg_saberContact, "cg_saberContact", "1", 0 },
{ &cg_saberTrail, "cg_saberTrail", "1", 0 }, { &cg_saberTrail, "cg_saberTrail", "1", 0 },
@ -562,7 +568,7 @@ static cvarTable_t cvarTable[] = { // bk001129
{ &cg_thirdPersonAngle, "cg_thirdPersonAngle", "0", CVAR_CHEAT }, { &cg_thirdPersonAngle, "cg_thirdPersonAngle", "0", CVAR_CHEAT },
{ &cg_thirdPersonPitchOffset, "cg_thirdPersonPitchOffset", "0", CVAR_CHEAT }, { &cg_thirdPersonPitchOffset, "cg_thirdPersonPitchOffset", "0", CVAR_CHEAT },
{ &cg_thirdPersonVertOffset, "cg_thirdPersonVertOffset", "16", CVAR_CHEAT }, { &cg_thirdPersonVertOffset, "cg_thirdPersonVertOffset", "16", CVAR_CHEAT },
{ &cg_thirdPersonCameraDamp, "cg_thirdPersonCameraDamp", "0.3", CVAR_CHEAT }, { &cg_thirdPersonCameraDamp, "cg_thirdPersonCameraDamp", "0.3", 0 },
{ &cg_thirdPersonTargetDamp, "cg_thirdPersonTargetDamp", "0.5", CVAR_CHEAT }, { &cg_thirdPersonTargetDamp, "cg_thirdPersonTargetDamp", "0.5", CVAR_CHEAT },
{ &cg_thirdPersonHorzOffset, "cg_thirdPersonHorzOffset", "0", CVAR_CHEAT }, { &cg_thirdPersonHorzOffset, "cg_thirdPersonHorzOffset", "0", CVAR_CHEAT },
@ -592,8 +598,8 @@ static cvarTable_t cvarTable[] = { // bk001129
{ &cg_currentSelectedPlayer, "cg_currentSelectedPlayer", "0", CVAR_ARCHIVE}, { &cg_currentSelectedPlayer, "cg_currentSelectedPlayer", "0", CVAR_ARCHIVE},
{ &cg_currentSelectedPlayerName, "cg_currentSelectedPlayerName", "", CVAR_ARCHIVE}, { &cg_currentSelectedPlayerName, "cg_currentSelectedPlayerName", "", CVAR_ARCHIVE},
{ &cg_singlePlayer, "ui_singlePlayerActive", "0", CVAR_USERINFO}, { &cg_singlePlayer, "ui_singlePlayerActive", "0", CVAR_USERINFO},
{ &cg_enableDust, "g_enableDust", "0", CVAR_SERVERINFO}, { &cg_enableDust, "g_enableDust", "0", 0},
{ &cg_enableBreath, "g_enableBreath", "0", CVAR_SERVERINFO}, { &cg_enableBreath, "g_enableBreath", "0", 0},
{ &cg_singlePlayerActive, "ui_singlePlayerActive", "0", CVAR_USERINFO}, { &cg_singlePlayerActive, "ui_singlePlayerActive", "0", CVAR_USERINFO},
{ &cg_recordSPDemo, "ui_recordSPDemo", "0", CVAR_ARCHIVE}, { &cg_recordSPDemo, "ui_recordSPDemo", "0", CVAR_ARCHIVE},
{ &cg_recordSPDemoName, "ui_recordSPDemoName", "", CVAR_ARCHIVE}, { &cg_recordSPDemoName, "ui_recordSPDemoName", "", CVAR_ARCHIVE},
@ -604,6 +610,7 @@ static cvarTable_t cvarTable[] = { // bk001129
{ &cg_timescaleFadeSpeed, "cg_timescaleFadeSpeed", "0", 0}, { &cg_timescaleFadeSpeed, "cg_timescaleFadeSpeed", "0", 0},
{ &cg_timescale, "timescale", "1", 0}, { &cg_timescale, "timescale", "1", 0},
{ &cg_scorePlum, "cg_scorePlums", "1", CVAR_USERINFO | CVAR_ARCHIVE}, { &cg_scorePlum, "cg_scorePlums", "1", CVAR_USERINFO | CVAR_ARCHIVE},
{ &cg_hudFiles, "cg_hudFiles", "0", CVAR_USERINFO | CVAR_ARCHIVE},
{ &cg_smoothClients, "cg_smoothClients", "0", CVAR_USERINFO | CVAR_ARCHIVE}, { &cg_smoothClients, "cg_smoothClients", "0", CVAR_USERINFO | CVAR_ARCHIVE},
{ &cg_cameraMode, "com_cameraMode", "0", CVAR_CHEAT}, { &cg_cameraMode, "com_cameraMode", "0", CVAR_CHEAT},
@ -614,6 +621,9 @@ static cvarTable_t cvarTable[] = { // bk001129
{ &cg_smallFont, "ui_smallFont", "0.25", CVAR_ARCHIVE}, { &cg_smallFont, "ui_smallFont", "0.25", CVAR_ARCHIVE},
{ &cg_bigFont, "ui_bigFont", "0.4", CVAR_ARCHIVE}, { &cg_bigFont, "ui_bigFont", "0.4", CVAR_ARCHIVE},
{ &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE}, { &cg_trueLightning, "cg_trueLightning", "0.0", CVAR_ARCHIVE},
{ &ui_myteam, "ui_myteam", "0", CVAR_ROM|CVAR_INTERNAL},
// { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE } // { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE }
/* /*
Ghoul2 Insert Start Ghoul2 Insert Start
@ -648,15 +658,16 @@ void CG_RegisterCvars( void ) {
forceModelModificationCount = cg_forceModel.modificationCount; forceModelModificationCount = cg_forceModel.modificationCount;
trap_Cvar_Register(NULL, "model", DEFAULT_MODEL, CVAR_USERINFO | CVAR_ARCHIVE ); 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, "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_model", DEFAULT_TEAM_MODEL, CVAR_USERINFO | CVAR_ARCHIVE );
trap_Cvar_Register(NULL, "team_headmodel", DEFAULT_TEAM_HEAD, CVAR_USERINFO | CVAR_ARCHIVE ); //trap_Cvar_Register(NULL, "team_headmodel", DEFAULT_TEAM_HEAD, CVAR_USERINFO | CVAR_ARCHIVE );
trap_Cvar_Register(NULL, "forcepowers", DEFAULT_FORCEPOWERS, CVAR_USERINFO | CVAR_ARCHIVE ); trap_Cvar_Register(NULL, "forcepowers", DEFAULT_FORCEPOWERS, CVAR_USERINFO | CVAR_ARCHIVE );
// Cvars uses for transferring data between client and server // Cvars uses for transferring data between client and server
trap_Cvar_Register(NULL, "ui_about_gametype", "0", CVAR_ROM|CVAR_INTERNAL ); trap_Cvar_Register(NULL, "ui_about_gametype", "0", CVAR_ROM|CVAR_INTERNAL );
trap_Cvar_Register(NULL, "ui_about_fraglimit", "0", CVAR_ROM|CVAR_INTERNAL ); trap_Cvar_Register(NULL, "ui_about_fraglimit", "0", CVAR_ROM|CVAR_INTERNAL );
trap_Cvar_Register(NULL, "ui_about_capturelimit", "0", CVAR_ROM|CVAR_INTERNAL ); trap_Cvar_Register(NULL, "ui_about_capturelimit", "0", CVAR_ROM|CVAR_INTERNAL );
trap_Cvar_Register(NULL, "ui_about_duellimit", "0", CVAR_ROM|CVAR_INTERNAL );
trap_Cvar_Register(NULL, "ui_about_timelimit", "0", CVAR_ROM|CVAR_INTERNAL ); trap_Cvar_Register(NULL, "ui_about_timelimit", "0", CVAR_ROM|CVAR_INTERNAL );
trap_Cvar_Register(NULL, "ui_about_maxclients", "0", CVAR_ROM|CVAR_INTERNAL ); trap_Cvar_Register(NULL, "ui_about_maxclients", "0", CVAR_ROM|CVAR_INTERNAL );
trap_Cvar_Register(NULL, "ui_about_dmflags", "0", CVAR_ROM|CVAR_INTERNAL ); trap_Cvar_Register(NULL, "ui_about_dmflags", "0", CVAR_ROM|CVAR_INTERNAL );
@ -940,9 +951,10 @@ static void CG_RegisterSounds( void ) {
trap_S_RegisterSound( "sound/weapons/saber/saberhitwall3" ); trap_S_RegisterSound( "sound/weapons/saber/saberhitwall3" );
trap_S_RegisterSound("sound/weapons/saber/saberhit.wav"); trap_S_RegisterSound("sound/weapons/saber/saberhit.wav");
cgs.media.teamHealSound = trap_S_RegisterSound("sound/weapons/force/teamheal.wav");
cgs.media.teamRegenSound = trap_S_RegisterSound("sound/weapons/force/teamforce.wav");
trap_S_RegisterSound("sound/weapons/force/heal.wav"); trap_S_RegisterSound("sound/weapons/force/heal.wav");
trap_S_RegisterSound("sound/weapons/force/teamheal.wav");
trap_S_RegisterSound("sound/weapons/force/teamforce.wav");
trap_S_RegisterSound("sound/weapons/force/speed.wav"); trap_S_RegisterSound("sound/weapons/force/speed.wav");
trap_S_RegisterSound("sound/weapons/force/see.wav"); trap_S_RegisterSound("sound/weapons/force/see.wav");
trap_S_RegisterSound("sound/weapons/force/rage.wav"); trap_S_RegisterSound("sound/weapons/force/rage.wav");
@ -950,12 +962,10 @@ static void CG_RegisterSounds( void ) {
trap_S_RegisterSound("sound/weapons/force/lightninghit.wav"); trap_S_RegisterSound("sound/weapons/force/lightninghit.wav");
trap_S_RegisterSound("sound/weapons/force/drain.wav"); trap_S_RegisterSound("sound/weapons/force/drain.wav");
trap_S_RegisterSound("sound/weapons/force/jumpbuild.wav"); trap_S_RegisterSound("sound/weapons/force/jumpbuild.wav");
trap_S_RegisterSound("sound/weapons/force/jump.wav");
trap_S_RegisterSound("sound/weapons/force/distract.wav"); trap_S_RegisterSound("sound/weapons/force/distract.wav");
trap_S_RegisterSound("sound/weapons/force/distractstop.wav"); trap_S_RegisterSound("sound/weapons/force/distractstop.wav");
trap_S_RegisterSound("sound/weapons/force/pull.wav"); trap_S_RegisterSound("sound/weapons/force/pull.wav");
trap_S_RegisterSound("sound/weapons/force/push.wav"); trap_S_RegisterSound("sound/weapons/force/push.wav");
trap_S_RegisterSound("sound/weapons/force/grip.mp3");
if (cg_buildScript.integer) if (cg_buildScript.integer)
{ {
@ -982,7 +992,8 @@ static void CG_RegisterSounds( void ) {
trap_S_RegisterSound("sound/chars/turret/startup.wav"); trap_S_RegisterSound("sound/chars/turret/startup.wav");
trap_S_RegisterSound("sound/chars/turret/shutdown.wav"); trap_S_RegisterSound("sound/chars/turret/shutdown.wav");
trap_S_RegisterSound("sound/chars/turret/move.wav"); trap_S_RegisterSound("sound/chars/turret/move.wav");
trap_S_RegisterSound("sound/player/suitenergy.wav"); trap_S_RegisterSound("sound/player/pickuphealth.wav");
trap_S_RegisterSound("sound/player/pickupshield.wav");
trap_S_RegisterSound("sound/effects/glassbreak1.wav"); trap_S_RegisterSound("sound/effects/glassbreak1.wav");
@ -991,6 +1002,13 @@ static void CG_RegisterSounds( void ) {
trap_S_RegisterSound("sound/weapons/force/speedloop.wav"); trap_S_RegisterSound("sound/weapons/force/speedloop.wav");
trap_S_RegisterSound("sound/weapons/force/protecthit.mp3"); //PDSOUND_PROTECTHIT
trap_S_RegisterSound("sound/weapons/force/protect.mp3"); //PDSOUND_PROTECT
trap_S_RegisterSound("sound/weapons/force/absorbhit.mp3"); //PDSOUND_ABSORBHIT
trap_S_RegisterSound("sound/weapons/force/absorb.mp3"); //PDSOUND_ABSORB
trap_S_RegisterSound("sound/weapons/force/jump.mp3"); //PDSOUND_FORCEJUMP
trap_S_RegisterSound("sound/weapons/force/grip.mp3"); //PDSOUND_FORCEGRIP
if ( cgs.gametype >= GT_TEAM || cg_buildScript.integer ) { if ( cgs.gametype >= GT_TEAM || cg_buildScript.integer ) {
#ifdef JK2AWARDS #ifdef JK2AWARDS
@ -1016,6 +1034,8 @@ static void CG_RegisterSounds( void ) {
} }
} }
cgs.media.drainSound = trap_S_RegisterSound("sound/weapons/force/drained.mp3");
cgs.media.happyMusic = trap_S_RegisterSound("music/goodsmall.mp3"); cgs.media.happyMusic = trap_S_RegisterSound("music/goodsmall.mp3");
cgs.media.dramaticFailure = trap_S_RegisterSound("music/badsmall.mp3"); cgs.media.dramaticFailure = trap_S_RegisterSound("music/badsmall.mp3");
@ -1132,6 +1152,7 @@ static void CG_RegisterSounds( void ) {
cg.loadLCARSStage = 2; cg.loadLCARSStage = 2;
// FIXME: only needed with item // FIXME: only needed with item
cgs.media.deploySeeker = trap_S_RegisterSound ("sound/chars/seeker/misc/hiss");
cgs.media.medkitSound = trap_S_RegisterSound ("sound/items/use_bacta.wav"); cgs.media.medkitSound = trap_S_RegisterSound ("sound/items/use_bacta.wav");
cgs.media.winnerSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM006" ); cgs.media.winnerSound = trap_S_RegisterSound( "sound/chars/mothma/misc/40MOM006" );
@ -1318,6 +1339,8 @@ static void CG_RegisterGraphics( void ) {
cgs.media.playerShieldDamage = trap_R_RegisterShader("gfx/misc/personalshield"); cgs.media.playerShieldDamage = trap_R_RegisterShader("gfx/misc/personalshield");
cgs.media.forceSightBubble = trap_R_RegisterShader("gfx/misc/sightbubble"); cgs.media.forceSightBubble = trap_R_RegisterShader("gfx/misc/sightbubble");
cgs.media.forceShell = trap_R_RegisterShader("powerups/forceshell");
cgs.media.sightShell = trap_R_RegisterShader("powerups/sightshell");
cgs.media.itemHoloModel = trap_R_RegisterModel("models/map_objects/mp/holo.md3"); cgs.media.itemHoloModel = trap_R_RegisterModel("models/map_objects/mp/holo.md3");
@ -1353,19 +1376,16 @@ static void CG_RegisterGraphics( void ) {
cgs.media.blueFlagModel = trap_R_RegisterModel( "models/flags/b_flag_ysal.md3" ); cgs.media.blueFlagModel = trap_R_RegisterModel( "models/flags/b_flag_ysal.md3" );
} }
trap_R_RegisterShader( "gfx/hud/mpi_rflag_x" ); trap_R_RegisterShaderNoMip( "gfx/hud/mpi_rflag_x" );
trap_R_RegisterShader( "gfx/hud/mpi_bflag_x" ); trap_R_RegisterShaderNoMip( "gfx/hud/mpi_bflag_x" );
trap_R_RegisterShader( "gfx/hud/mpi_rflag_ys" ); trap_R_RegisterShaderNoMip( "gfx/hud/mpi_rflag_ys" );
trap_R_RegisterShader( "gfx/hud/mpi_bflag_ys" ); trap_R_RegisterShaderNoMip( "gfx/hud/mpi_bflag_ys" );
trap_R_RegisterShader( "gfx/hud/mpi_rflag" ); trap_R_RegisterShaderNoMip( "gfx/hud/mpi_rflag" );
trap_R_RegisterShader( "gfx/hud/mpi_bflag" ); trap_R_RegisterShaderNoMip( "gfx/hud/mpi_bflag" );
if (cg_buildScript.integer) trap_R_RegisterShaderNoMip("gfx/2d/net.tga");
{
trap_R_RegisterShader("gfx/2d/net.tga");
}
cgs.media.flagPoleModel = trap_R_RegisterModel( "models/flag2/flagpole.md3" ); cgs.media.flagPoleModel = trap_R_RegisterModel( "models/flag2/flagpole.md3" );
cgs.media.flagFlapModel = trap_R_RegisterModel( "models/flag2/flagflap3.md3" ); cgs.media.flagFlapModel = trap_R_RegisterModel( "models/flag2/flagflap3.md3" );
@ -1394,12 +1414,24 @@ static void CG_RegisterGraphics( void ) {
cgs.media.redQuadShader = trap_R_RegisterShader("powerups/blueflag" ); cgs.media.redQuadShader = trap_R_RegisterShader("powerups/blueflag" );
cgs.media.teamStatusBar = trap_R_RegisterShader( "gfx/2d/colorbar.tga" ); cgs.media.teamStatusBar = trap_R_RegisterShader( "gfx/2d/colorbar.tga" );
} }
else if ( cgs.gametype == GT_JEDIMASTER )
{
cgs.media.teamRedShader = trap_R_RegisterShader( "sprites/team_red" );
}
cgs.media.armorModel = 0;//trap_R_RegisterModel( "models/powerups/armor/armor_yel.md3" ); cgs.media.armorModel = 0;//trap_R_RegisterModel( "models/powerups/armor/armor_yel.md3" );
cgs.media.armorIcon = 0;//trap_R_RegisterShaderNoMip( "icons/iconr_yellow" ); cgs.media.armorIcon = 0;//trap_R_RegisterShaderNoMip( "icons/iconr_yellow" );
cgs.media.heartShader = trap_R_RegisterShaderNoMip( "ui/assets/statusbar/selectedhealth.tga" ); cgs.media.heartShader = trap_R_RegisterShaderNoMip( "ui/assets/statusbar/selectedhealth.tga" );
cgs.media.ysaliredShader = trap_R_RegisterShader( "powerups/ysaliredshell");
cgs.media.ysaliblueShader = trap_R_RegisterShader( "powerups/ysaliblueshell");
cgs.media.ysalimariShader = trap_R_RegisterShader( "powerups/ysalimarishell");
cgs.media.boonShader = trap_R_RegisterShader( "powerups/boonshell");
cgs.media.endarkenmentShader = trap_R_RegisterShader( "powerups/endarkenmentshell");
cgs.media.enlightenmentShader = trap_R_RegisterShader( "powerups/enlightenmentshell");
cgs.media.invulnerabilityShader = trap_R_RegisterShader( "powerups/invulnerabilityshell");
#ifdef JK2AWARDS #ifdef JK2AWARDS
cgs.media.medalImpressive = trap_R_RegisterShaderNoMip( "medal_impressive" ); cgs.media.medalImpressive = trap_R_RegisterShaderNoMip( "medal_impressive" );
cgs.media.medalExcellent = trap_R_RegisterShaderNoMip( "medal_excellent" ); cgs.media.medalExcellent = trap_R_RegisterShaderNoMip( "medal_excellent" );
@ -1454,7 +1486,10 @@ Ghoul2 Insert End
cgs.media.shadowMarkShader = trap_R_RegisterShader( "markShadow" ); cgs.media.shadowMarkShader = trap_R_RegisterShader( "markShadow" );
cgs.media.wakeMarkShader = trap_R_RegisterShader( "wake" ); cgs.media.wakeMarkShader = trap_R_RegisterShader( "wake" );
cgs.media.bloodMarkShader = trap_R_RegisterShader( "bloodMark" ); cgs.media.bloodMarkShader = trap_R_RegisterShader( "bloodMark" );
cgs.media.viewPainShader = trap_R_RegisterShader( "gfx/misc/borgeyeflare" );
cgs.media.viewPainShader = trap_R_RegisterShader( "gfx/misc/borgeyeflare" );
cgs.media.viewPainShader_Shields = trap_R_RegisterShader( "gfx/mp/dmgshader_shields" );
cgs.media.viewPainShader_ShieldsAndHealth = trap_R_RegisterShader( "gfx/mp/dmgshader_shieldsandhealth" );
// register the inline models // register the inline models
cgs.numInlineModels = trap_CM_NumInlineModels(); cgs.numInlineModels = trap_CM_NumInlineModels();
@ -1545,9 +1580,12 @@ Ghoul2 Insert End
const char *CG_GetStripEdString(char *refSection, char *refName) const char *CG_GetStripEdString(char *refSection, char *refName)
{ {
static char text[1024]={0}; static char text[2][1024]={0}; //just incase it's nested
trap_SP_GetStringTextString(va("%s_%s", refSection, refName), text, sizeof(text)); static int index = 0;
return text;
index ^= 1;
trap_SP_GetStringTextString(va("%s_%s", refSection, refName), text[index], sizeof(text[0]));
return text[index];
} }
@ -2057,7 +2095,7 @@ static qhandle_t CG_FeederItemImage(float feederID, int index) {
return 0; return 0;
} }
static void CG_FeederSelection(float feederID, int index) { static qboolean CG_FeederSelection(float feederID, int index) {
if ( cgs.gametype >= GT_TEAM ) { if ( cgs.gametype >= GT_TEAM ) {
int i, count; int i, count;
int team = (feederID == FEEDER_REDTEAM_LIST) ? TEAM_RED : TEAM_BLUE; int team = (feederID == FEEDER_REDTEAM_LIST) ? TEAM_RED : TEAM_BLUE;
@ -2073,6 +2111,8 @@ static void CG_FeederSelection(float feederID, int index) {
} else { } else {
cg.selectedScore = index; cg.selectedScore = index;
} }
return qtrue;
} }
static float CG_Cvar_Get(const char *cvar) { static float CG_Cvar_Get(const char *cvar) {
@ -2159,6 +2199,7 @@ void CG_LoadHudMenu()
cgDC.getValue = &CG_GetValue; cgDC.getValue = &CG_GetValue;
cgDC.ownerDrawVisible = &CG_OwnerDrawVisible; cgDC.ownerDrawVisible = &CG_OwnerDrawVisible;
cgDC.runScript = &CG_RunMenuScript; cgDC.runScript = &CG_RunMenuScript;
cgDC.deferScript = &CG_DeferMenuScript;
cgDC.getTeamColor = &CG_GetTeamColor; cgDC.getTeamColor = &CG_GetTeamColor;
cgDC.setCVar = trap_Cvar_Set; cgDC.setCVar = trap_Cvar_Set;
cgDC.getCVarString = trap_Cvar_VariableStringBuffer; cgDC.getCVarString = trap_Cvar_VariableStringBuffer;
@ -2345,6 +2386,7 @@ Ghoul2 Insert End
cgs.media.whiteShader = trap_R_RegisterShader( "white" ); cgs.media.whiteShader = trap_R_RegisterShader( "white" );
cgs.media.loadBarLED = trap_R_RegisterShaderNoMip( "gfx/hud/load_tick" ); cgs.media.loadBarLED = trap_R_RegisterShaderNoMip( "gfx/hud/load_tick" );
cgs.media.loadBarLEDCap = trap_R_RegisterShaderNoMip( "gfx/hud/load_tick_cap" );
cgs.media.loadBarLEDSurround= trap_R_RegisterShaderNoMip( "gfx/hud/mp_levelload" ); cgs.media.loadBarLEDSurround= trap_R_RegisterShaderNoMip( "gfx/hud/mp_levelload" );
//rww - precache HUD weapon icons here //rww - precache HUD weapon icons here
@ -2438,9 +2480,9 @@ Ghoul2 Insert End
cgs.media.HUDLeftStatic = cgs.media.HUDLeftFrame;//trap_R_RegisterShaderNoMip( "gfx/hud/static_test" ); cgs.media.HUDLeftStatic = cgs.media.HUDLeftFrame;//trap_R_RegisterShaderNoMip( "gfx/hud/static_test" );
cgs.media.HUDLeft = cgs.media.HUDInnerLeft;//trap_R_RegisterShaderNoMip( "gfx/hud/hudleft" ); cgs.media.HUDLeft = cgs.media.HUDInnerLeft;//trap_R_RegisterShaderNoMip( "gfx/hud/hudleft" );
cgs.media.HUDSaberStyle1 = trap_R_RegisterShader( "gfx/hud/saber_styles1" ); cgs.media.HUDSaberStyle1 = trap_R_RegisterShader( "gfx/hud/saber_stylesFast" );
cgs.media.HUDSaberStyle2 = trap_R_RegisterShader( "gfx/hud/saber_styles2" ); cgs.media.HUDSaberStyle2 = trap_R_RegisterShader( "gfx/hud/saber_stylesMed" );
cgs.media.HUDSaberStyle3 = trap_R_RegisterShader( "gfx/hud/saber_styles3" ); cgs.media.HUDSaberStyle3 = trap_R_RegisterShader( "gfx/hud/saber_stylesStrong" );
cgs.media.HUDRightFrame = trap_R_RegisterShaderNoMip("gfx/hud/hudrightframe"); cgs.media.HUDRightFrame = trap_R_RegisterShaderNoMip("gfx/hud/hudrightframe");
cgs.media.HUDInnerRight = trap_R_RegisterShaderNoMip( "gfx/hud/hudright_innerframe" ); cgs.media.HUDInnerRight = trap_R_RegisterShaderNoMip( "gfx/hud/hudright_innerframe" );

0
CODE-mp/cgame/cg_media.h Normal file
View file

View file

@ -133,233 +133,6 @@ void CG_SelectPrevPlayer(void) {
} }
static void CG_DrawPlayerArmorIcon( rectDef_t *rect, qboolean draw2D ) {
centity_t *cent;
playerState_t *ps;
vec3_t angles;
vec3_t origin;
if ( cg_drawStatus.integer == 0 ) {
return;
}
cent = &cg_entities[cg.snap->ps.clientNum];
ps = &cg.snap->ps;
if ( draw2D || ( !cg_draw3dIcons.integer && cg_drawIcons.integer) ) { // bk001206 - parentheses
CG_DrawPic( rect->x, rect->y + rect->h/2 + 1, rect->w, rect->h, cgs.media.armorIcon );
} else if (cg_draw3dIcons.integer) {
VectorClear( angles );
origin[0] = 90;
origin[1] = 0;
origin[2] = -10;
angles[YAW] = ( cg.time & 2047 ) * 360 / 2048.0;
CG_Draw3DModel( rect->x, rect->y, rect->w, rect->h, cgs.media.armorModel, 0, origin, angles );
}
}
static void CG_DrawPlayerArmorValue(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle) {
char num[16];
int value;
centity_t *cent;
playerState_t *ps;
cent = &cg_entities[cg.snap->ps.clientNum];
ps = &cg.snap->ps;
value = ps->stats[STAT_ARMOR];
if (shader) {
trap_R_SetColor( color );
CG_DrawPic(rect->x, rect->y, rect->w, rect->h, shader);
trap_R_SetColor( NULL );
} else {
Com_sprintf (num, sizeof(num), "%i", value);
value = CG_Text_Width(num, scale, 0);
CG_Text_Paint(rect->x + (rect->w - value) / 2, rect->y + rect->h, scale, color, num, 0, 0, textStyle, FONT_MEDIUM);
}
}
static void CG_DrawPlayerAmmoIcon( rectDef_t *rect, qboolean draw2D ) {
centity_t *cent;
playerState_t *ps;
vec3_t angles;
vec3_t origin;
cent = &cg_entities[cg.snap->ps.clientNum];
ps = &cg.snap->ps;
if ( draw2D || (!cg_draw3dIcons.integer && cg_drawIcons.integer) ) { // bk001206 - parentheses
qhandle_t icon;
icon = cg_weapons[ cg.predictedPlayerState.weapon ].ammoIcon;
if ( icon ) {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, icon );
}
} else if (cg_draw3dIcons.integer) {
if ( cent->currentState.weapon && cg_weapons[ cent->currentState.weapon ].ammoModel ) {
VectorClear( angles );
origin[0] = 70;
origin[1] = 0;
origin[2] = 0;
angles[YAW] = 90 + 20 * sin( cg.time / 1000.0 );
CG_Draw3DModel( rect->x, rect->y, rect->w, rect->h, cg_weapons[ cent->currentState.weapon ].ammoModel, 0, origin, angles );
}
}
}
static void CG_DrawPlayerAmmoValue(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle) {
char num[16];
int value;
centity_t *cent;
playerState_t *ps;
cent = &cg_entities[cg.snap->ps.clientNum];
ps = &cg.snap->ps;
if ( cent->currentState.weapon )
{
value = ps->ammo[weaponData[cent->currentState.weapon].ammoIndex];
if ( value > -1 ) {
if (shader) {
trap_R_SetColor( color );
CG_DrawPic(rect->x, rect->y, rect->w, rect->h, shader);
trap_R_SetColor( NULL );
} else {
Com_sprintf (num, sizeof(num), "%i", value);
value = CG_Text_Width(num, scale, 0);
CG_Text_Paint(rect->x + (rect->w - value) / 2, rect->y + rect->h, scale, color, num, 0, 0, textStyle, FONT_MEDIUM);
}
}
}
}
static void CG_DrawPlayerForceValue(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle) {
char num[16];
int value;
centity_t *cent;
playerState_t *ps;
cent = &cg_entities[cg.snap->ps.clientNum];
ps = &cg.snap->ps;
if ( cent->currentState.weapon )
{
value = ps->fd.forcePower;
if ( value > -1 )
{
if (shader)
{
trap_R_SetColor( color );
CG_DrawPic(rect->x, rect->y, rect->w, rect->h, shader);
trap_R_SetColor( NULL );
}
else
{
Com_sprintf (num, sizeof(num), "%i", value);
value = CG_Text_Width(num, scale, 0);
CG_Text_Paint(rect->x + (rect->w - value) / 2, rect->y + rect->h, scale, color, num, 0, 0, textStyle, FONT_MEDIUM);
}
}
}
}
static void CG_DrawPlayerHead(rectDef_t *rect, qboolean draw2D) {
vec3_t angles;
float size, stretch;
float frac;
float x = rect->x;
VectorClear( angles );
if ( cg.damageTime && cg.time - cg.damageTime < DAMAGE_TIME ) {
frac = (float)(cg.time - cg.damageTime ) / DAMAGE_TIME;
size = rect->w * 1.25 * ( 1.5 - frac * 0.5 );
stretch = size - rect->w * 1.25;
// kick in the direction of damage
x -= stretch * 0.5 + cg.damageX * stretch * 0.5;
cg.headStartYaw = 180 + cg.damageX * 45;
cg.headEndYaw = 180 + 20 * cos( crandom()*M_PI );
cg.headEndPitch = 5 * cos( crandom()*M_PI );
cg.headStartTime = cg.time;
cg.headEndTime = cg.time + 100 + random() * 2000;
} else {
if ( cg.time >= cg.headEndTime ) {
// select a new head angle
cg.headStartYaw = cg.headEndYaw;
cg.headStartPitch = cg.headEndPitch;
cg.headStartTime = cg.headEndTime;
cg.headEndTime = cg.time + 100 + random() * 2000;
cg.headEndYaw = 180 + 20 * cos( crandom()*M_PI );
cg.headEndPitch = 5 * cos( crandom()*M_PI );
}
size = rect->w * 1.25;
}
// if the server was frozen for a while we may have a bad head start time
if ( cg.headStartTime > cg.time ) {
cg.headStartTime = cg.time;
}
frac = ( cg.time - cg.headStartTime ) / (float)( cg.headEndTime - cg.headStartTime );
frac = frac * frac * ( 3 - 2 * frac );
angles[YAW] = cg.headStartYaw + ( cg.headEndYaw - cg.headStartYaw ) * frac;
angles[PITCH] = cg.headStartPitch + ( cg.headEndPitch - cg.headStartPitch ) * frac;
CG_DrawHead( x, rect->y, rect->w, rect->h, cg.snap->ps.clientNum, angles );
}
static void CG_DrawSelectedPlayerHealth( rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle ) {
clientInfo_t *ci;
int value;
char num[16];
ci = cgs.clientinfo + sortedTeamPlayers[CG_GetSelectedPlayer()];
if (ci) {
if (shader) {
trap_R_SetColor( color );
CG_DrawPic(rect->x, rect->y, rect->w, rect->h, shader);
trap_R_SetColor( NULL );
} else {
Com_sprintf (num, sizeof(num), "%i", ci->health);
value = CG_Text_Width(num, scale, 0);
CG_Text_Paint(rect->x + (rect->w - value) / 2, rect->y + rect->h, scale, color, num, 0, 0, textStyle, FONT_MEDIUM);
}
}
}
static void CG_DrawSelectedPlayerArmor( rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle ) {
clientInfo_t *ci;
int value;
char num[16];
ci = cgs.clientinfo + sortedTeamPlayers[CG_GetSelectedPlayer()];
if (ci) {
if (ci->armor > 0) {
if (shader) {
trap_R_SetColor( color );
CG_DrawPic(rect->x, rect->y, rect->w, rect->h, shader);
trap_R_SetColor( NULL );
} else {
Com_sprintf (num, sizeof(num), "%i", ci->armor);
value = CG_Text_Width(num, scale, 0);
CG_Text_Paint(rect->x + (rect->w - value) / 2, rect->y + rect->h, scale, color, num, 0, 0, textStyle, FONT_MEDIUM);
}
}
}
}
qhandle_t CG_StatusHandle(int task) { qhandle_t CG_StatusHandle(int task) {
qhandle_t h = cgs.media.assaultShader; qhandle_t h = cgs.media.assaultShader;
switch (task) { switch (task) {
@ -391,442 +164,6 @@ qhandle_t CG_StatusHandle(int task) {
return h; return h;
} }
static void CG_DrawSelectedPlayerStatus( rectDef_t *rect ) {
clientInfo_t *ci = cgs.clientinfo + sortedTeamPlayers[CG_GetSelectedPlayer()];
if (ci) {
qhandle_t h;
if (cgs.orderPending) {
// blink the icon
if ( cg.time > cgs.orderTime - 2500 && (cg.time >> 9 ) & 1 ) {
return;
}
h = CG_StatusHandle(cgs.currentOrder);
} else {
h = CG_StatusHandle(ci->teamTask);
}
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, h );
}
}
static void CG_DrawPlayerStatus( rectDef_t *rect ) {
clientInfo_t *ci = &cgs.clientinfo[cg.snap->ps.clientNum];
if (ci) {
qhandle_t h = CG_StatusHandle(ci->teamTask);
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, h);
}
}
static void CG_DrawSelectedPlayerName( rectDef_t *rect, float scale, vec4_t color, qboolean voice, int textStyle) {
clientInfo_t *ci;
ci = cgs.clientinfo + ((voice) ? cgs.currentVoiceClient : sortedTeamPlayers[CG_GetSelectedPlayer()]);
if (ci) {
CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, ci->name, 0, 0, textStyle, FONT_MEDIUM);
}
}
static void CG_DrawSelectedPlayerLocation( rectDef_t *rect, float scale, vec4_t color, int textStyle ) {
clientInfo_t *ci;
ci = cgs.clientinfo + sortedTeamPlayers[CG_GetSelectedPlayer()];
if (ci) {
const char *p = CG_ConfigString(CS_LOCATIONS + ci->location);
if (!p || !*p) {
p = "unknown";
}
CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, p, 0, 0, textStyle, FONT_MEDIUM);
}
}
static void CG_DrawPlayerLocation( rectDef_t *rect, float scale, vec4_t color, int textStyle ) {
clientInfo_t *ci = &cgs.clientinfo[cg.snap->ps.clientNum];
if (ci) {
const char *p = CG_ConfigString(CS_LOCATIONS + ci->location);
if (!p || !*p) {
p = "unknown";
}
CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, p, 0, 0, textStyle, FONT_MEDIUM);
}
}
static void CG_DrawSelectedPlayerWeapon( rectDef_t *rect ) {
clientInfo_t *ci;
ci = cgs.clientinfo + sortedTeamPlayers[CG_GetSelectedPlayer()];
if (ci) {
if ( cg_weapons[ci->curWeapon].weaponIcon ) {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cg_weapons[ci->curWeapon].weaponIcon );
} else {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.deferShader);
}
}
}
static void CG_DrawPlayerScore( rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle ) {
char num[16];
int value = cg.snap->ps.persistant[PERS_SCORE];
if (shader) {
trap_R_SetColor( color );
CG_DrawPic(rect->x, rect->y, rect->w, rect->h, shader);
trap_R_SetColor( NULL );
} else {
Com_sprintf (num, sizeof(num), "%i", value);
value = CG_Text_Width(num, scale, 0);
CG_Text_Paint(rect->x + (rect->w - value) / 2, rect->y + rect->h, scale, color, num, 0, 0, textStyle, FONT_MEDIUM);
}
}
static void CG_DrawPlayerItem( rectDef_t *rect, float scale, qboolean draw2D) {
int value;
vec3_t origin, angles;
value = cg.snap->ps.stats[STAT_HOLDABLE_ITEM];
if ( value ) {
CG_RegisterItemVisuals( value );
if (qtrue) {
CG_RegisterItemVisuals( value );
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cg_items[ value ].icon );
} else {
VectorClear( angles );
origin[0] = 90;
origin[1] = 0;
origin[2] = -10;
angles[YAW] = ( cg.time & 2047 ) * 360 / 2048.0;
CG_Draw3DModel(rect->x, rect->y, rect->w, rect->h, cg_items[ value ].models[0], 0, origin, angles );
}
}
}
static void CG_DrawSelectedPlayerPowerup( rectDef_t *rect, qboolean draw2D ) {
clientInfo_t *ci;
int j;
float x, y;
ci = cgs.clientinfo + sortedTeamPlayers[CG_GetSelectedPlayer()];
if (ci) {
x = rect->x;
y = rect->y;
for (j = 0; j < PW_NUM_POWERUPS; j++) {
if (ci->powerups & (1 << j)) {
gitem_t *item;
item = BG_FindItemForPowerup( j );
if (item) {
CG_DrawPic( x, y, rect->w, rect->h, trap_R_RegisterShader( item->icon ) );
x += 3;
y += 3;
return;
}
}
}
}
}
static void CG_DrawSelectedPlayerHead( rectDef_t *rect, qboolean draw2D, qboolean voice ) {
clipHandle_t cm;
clientInfo_t *ci;
float len;
vec3_t origin;
vec3_t mins, maxs, angles;
ci = cgs.clientinfo + ((voice) ? cgs.currentVoiceClient : sortedTeamPlayers[CG_GetSelectedPlayer()]);
if (ci) {
if ( cg_draw3dIcons.integer ) {
cm = ci->headModel;
if ( !cm ) {
return;
}
// offset the origin y and z to center the head
trap_R_ModelBounds( cm, mins, maxs );
origin[2] = -0.5 * ( mins[2] + maxs[2] );
origin[1] = 0.5 * ( mins[1] + maxs[1] );
// calculate distance so the head nearly fills the box
// assume heads are taller than wide
len = 0.7 * ( maxs[2] - mins[2] );
origin[0] = len / 0.268; // len / tan( fov/2 )
// allow per-model tweaking
VectorAdd( origin, ci->headOffset, origin );
angles[PITCH] = 0;
angles[YAW] = 180;
angles[ROLL] = 0;
CG_Draw3DModel( rect->x, rect->y, rect->w, rect->h, ci->headModel, ci->headSkin, origin, angles );
} else if ( cg_drawIcons.integer ) {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, ci->modelIcon );
}
// if they are deferred, draw a cross out
if ( ci->deferred ) {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.deferShader );
}
}
}
static void CG_DrawPlayerHealth(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle ) {
playerState_t *ps;
int value;
char num[16];
ps = &cg.snap->ps;
value = ps->stats[STAT_HEALTH];
if (shader) {
trap_R_SetColor( color );
CG_DrawPic(rect->x, rect->y, rect->w, rect->h, shader);
trap_R_SetColor( NULL );
} else {
Com_sprintf (num, sizeof(num), "%i", value);
value = CG_Text_Width(num, scale, 0);
CG_Text_Paint(rect->x + (rect->w - value) / 2, rect->y + rect->h, scale, color, num, 0, 0, textStyle, FONT_MEDIUM);
}
}
static void CG_DrawRedScore(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle ) {
int value;
char num[16];
if ( cgs.scores1 == SCORE_NOT_PRESENT ) {
Com_sprintf (num, sizeof(num), "-");
}
else {
Com_sprintf (num, sizeof(num), "%i", cgs.scores1);
}
value = CG_Text_Width(num, scale, 0);
CG_Text_Paint(rect->x + rect->w - value, rect->y + rect->h, scale, color, num, 0, 0, textStyle, FONT_MEDIUM);
}
static void CG_DrawBlueScore(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle ) {
int value;
char num[16];
if ( cgs.scores2 == SCORE_NOT_PRESENT ) {
Com_sprintf (num, sizeof(num), "-");
}
else {
Com_sprintf (num, sizeof(num), "%i", cgs.scores2);
}
value = CG_Text_Width(num, scale, 0);
CG_Text_Paint(rect->x + rect->w - value, rect->y + rect->h, scale, color, num, 0, 0, textStyle, FONT_MEDIUM);
}
// FIXME: team name support
static void CG_DrawRedName(rectDef_t *rect, float scale, vec4_t color, int textStyle ) {
CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, cg_redTeamName.string , 0, 0, textStyle, FONT_MEDIUM);
}
static void CG_DrawBlueName(rectDef_t *rect, float scale, vec4_t color, int textStyle ) {
CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, cg_blueTeamName.string, 0, 0, textStyle, FONT_MEDIUM);
}
static void CG_DrawBlueFlagName(rectDef_t *rect, float scale, vec4_t color, int textStyle ) {
int i;
for ( i = 0 ; i < cgs.maxclients ; i++ ) {
if ( cgs.clientinfo[i].infoValid && cgs.clientinfo[i].team == TEAM_RED && cgs.clientinfo[i].powerups & ( 1<< PW_BLUEFLAG )) {
CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, cgs.clientinfo[i].name, 0, 0, textStyle, FONT_MEDIUM);
return;
}
}
}
static void CG_DrawBlueFlagStatus(rectDef_t *rect, qhandle_t shader) {
if (cgs.gametype != GT_CTF && cgs.gametype != GT_CTY) {
return;
}
if (shader) {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
} else {
gitem_t *item = BG_FindItemForPowerup( PW_BLUEFLAG );
if (item) {
vec4_t color = {0, 0, 1, 1};
trap_R_SetColor(color);
if( cgs.blueflag >= 0 && cgs.blueflag <= 2 ) {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.flagShaders[cgs.blueflag] );
} else {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.flagShaders[0] );
}
trap_R_SetColor(NULL);
}
}
}
static void CG_DrawBlueFlagHead(rectDef_t *rect) {
int i;
for ( i = 0 ; i < cgs.maxclients ; i++ ) {
if ( cgs.clientinfo[i].infoValid && cgs.clientinfo[i].team == TEAM_RED && cgs.clientinfo[i].powerups & ( 1<< PW_BLUEFLAG )) {
vec3_t angles;
VectorClear( angles );
angles[YAW] = 180 + 20 * sin( cg.time / 650.0 );;
CG_DrawHead( rect->x, rect->y, rect->w, rect->h, 0,angles );
return;
}
}
}
static void CG_DrawRedFlagName(rectDef_t *rect, float scale, vec4_t color, int textStyle ) {
int i;
for ( i = 0 ; i < cgs.maxclients ; i++ ) {
if ( cgs.clientinfo[i].infoValid && cgs.clientinfo[i].team == TEAM_BLUE && cgs.clientinfo[i].powerups & ( 1<< PW_REDFLAG )) {
CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, cgs.clientinfo[i].name, 0, 0, textStyle, FONT_MEDIUM);
return;
}
}
}
static void CG_DrawRedFlagStatus(rectDef_t *rect, qhandle_t shader) {
if (cgs.gametype != GT_CTF && cgs.gametype != GT_CTY) {
return;
}
if (shader) {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, shader );
} else {
gitem_t *item = BG_FindItemForPowerup( PW_REDFLAG );
if (item) {
vec4_t color = {1, 0, 0, 1};
trap_R_SetColor(color);
if( cgs.redflag >= 0 && cgs.redflag <= 2) {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.flagShaders[cgs.redflag] );
} else {
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cgs.media.flagShaders[0] );
}
trap_R_SetColor(NULL);
}
}
}
static void CG_DrawRedFlagHead(rectDef_t *rect) {
int i;
for ( i = 0 ; i < cgs.maxclients ; i++ ) {
if ( cgs.clientinfo[i].infoValid && cgs.clientinfo[i].team == TEAM_BLUE && cgs.clientinfo[i].powerups & ( 1<< PW_REDFLAG )) {
vec3_t angles;
VectorClear( angles );
angles[YAW] = 180 + 20 * sin( cg.time / 650.0 );;
CG_DrawHead( rect->x, rect->y, rect->w, rect->h, 0,angles );
return;
}
}
}
static void CG_DrawCTFPowerUp(rectDef_t *rect)
{
// int value;
if (cgs.gametype < GT_CTF) {
return;
}
/*
value = cg.snap->ps.stats[STAT_PERSISTANT_POWERUP];
if ( value ) {
CG_RegisterItemVisuals( value );
CG_DrawPic( rect->x, rect->y, rect->w, rect->h, cg_items[ value ].icon );
}
*/
}
static void CG_DrawTeamColor(rectDef_t *rect, vec4_t color) {
CG_DrawTeamBackground(rect->x, rect->y, rect->w, rect->h, color[3], cg.snap->ps.persistant[PERS_TEAM]);
}
static void CG_DrawAreaPowerUp(rectDef_t *rect, int align, float special, float scale, vec4_t color) {
char num[16];
int sorted[MAX_POWERUPS];
int sortedTime[MAX_POWERUPS];
int i, j, k;
int active;
playerState_t *ps;
int t;
gitem_t *item;
float f;
rectDef_t r2;
float *inc;
r2.x = rect->x;
r2.y = rect->y;
r2.w = rect->w;
r2.h = rect->h;
inc = (align == HUD_VERTICAL) ? &r2.y : &r2.x;
ps = &cg.snap->ps;
if ( ps->stats[STAT_HEALTH] <= 0 ) {
return;
}
// sort the list by time remaining
active = 0;
for ( i = 0 ; i < MAX_POWERUPS ; i++ ) {
if ( !ps->powerups[ i ] ) {
continue;
}
t = ps->powerups[ i ] - cg.time;
// ZOID--don't draw if the power up has unlimited time (999 seconds)
// This is true of the CTF flags
if ( t <= 0 || t >= 999000) {
continue;
}
// insert into the list
for ( j = 0 ; j < active ; j++ ) {
if ( sortedTime[j] >= t ) {
for ( k = active - 1 ; k >= j ; k-- ) {
sorted[k+1] = sorted[k];
sortedTime[k+1] = sortedTime[k];
}
break;
}
}
sorted[j] = i;
sortedTime[j] = t;
active++;
}
// draw the icons and timers
for ( i = 0 ; i < active ; i++ ) {
item = BG_FindItemForPowerup( sorted[i] );
if (item) {
t = ps->powerups[ sorted[i] ];
if ( t - cg.time >= POWERUP_BLINKS * POWERUP_BLINK_TIME ) {
trap_R_SetColor( NULL );
} else {
vec4_t modulate;
f = (float)( t - cg.time ) / POWERUP_BLINK_TIME;
f -= (int)f;
modulate[0] = modulate[1] = modulate[2] = modulate[3] = f;
trap_R_SetColor( modulate );
}
CG_DrawPic( r2.x, r2.y, r2.w * .75, r2.h, trap_R_RegisterShader( item->icon ) );
Com_sprintf (num, sizeof(num), "%i", sortedTime[i] / 1000);
CG_Text_Paint(r2.x + (r2.w * .75) + 3 , r2.y + r2.h, scale, color, num, 0, 0, 0, FONT_MEDIUM);
*inc += r2.w + special;
}
}
trap_R_SetColor( NULL );
}
float CG_GetValue(int ownerDraw) { float CG_GetValue(int ownerDraw) {
centity_t *cent; centity_t *cent;
@ -986,32 +323,8 @@ qboolean CG_OwnerDrawVisible(int flags) {
} }
static void CG_DrawPlayerHasFlag(rectDef_t *rect, qboolean force2D) {
int adj = (force2D) ? 0 : 2;
if( cg.predictedPlayerState.powerups[PW_REDFLAG] ) {
CG_DrawFlagModel( rect->x + adj, rect->y + adj, rect->w - adj, rect->h - adj, TEAM_RED, force2D);
} else if( cg.predictedPlayerState.powerups[PW_BLUEFLAG] ) {
CG_DrawFlagModel( rect->x + adj, rect->y + adj, rect->w - adj, rect->h - adj, TEAM_BLUE, force2D);
} else if( cg.predictedPlayerState.powerups[PW_NEUTRALFLAG] ) {
CG_DrawFlagModel( rect->x + adj, rect->y + adj, rect->w - adj, rect->h - adj, TEAM_FREE, force2D);
}
}
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, FONT_MEDIUM);
}
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, FONT_MEDIUM);
}
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, FONT_MEDIUM);
}
const char *CG_GetKillerText(void) { const char *CG_GetKillerText(void) {
const char *s = ""; static const char *s = "";
if ( cg.killerName[0] ) { if ( cg.killerName[0] ) {
s = va("%s %s", CG_GetStripEdString("INGAMETEXT", "KILLEDBY"), cg.killerName ); s = va("%s %s", CG_GetStripEdString("INGAMETEXT", "KILLEDBY"), cg.killerName );
} }
@ -1019,38 +332,15 @@ const char *CG_GetKillerText(void) {
} }
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, FONT_MEDIUM);
}
}
static void CG_DrawCapFragLimit(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle) {
int limit = (cgs.gametype >= GT_CTF) ? cgs.capturelimit : cgs.fraglimit;
CG_Text_Paint(rect->x, rect->y, scale, color, va("%2i", limit),0, 0, textStyle, FONT_MEDIUM);
}
static void CG_Draw1stPlace(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle) {
if (cgs.scores1 != SCORE_NOT_PRESENT) {
CG_Text_Paint(rect->x, rect->y, scale, color, va("%2i", cgs.scores1),0, 0, textStyle, FONT_MEDIUM);
}
}
static void CG_Draw2ndPlace(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle) {
if (cgs.scores2 != SCORE_NOT_PRESENT) {
CG_Text_Paint(rect->x, rect->y, scale, color, va("%2i", cgs.scores2),0, 0, textStyle, FONT_MEDIUM);
}
}
const char *CG_GetGameStatusText(void) { const char *CG_GetGameStatusText(void) {
const char *s = ""; static const char *s = "";
if ( cgs.gametype < GT_TEAM) { if ( cgs.gametype < GT_TEAM) {
if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR ) { if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR )
s = va("%s place with %i",CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ),cg.snap->ps.persistant[PERS_SCORE] ); {
char sPlaceWith[256];
trap_SP_GetStringTextString("INGAMETEXT_PLACE_WITH", sPlaceWith, sizeof(sPlaceWith));
s = va("%s %s %i",CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ), sPlaceWith, cg.snap->ps.persistant[PERS_SCORE] );
} }
} else { } else {
if ( cg.teamScores[0] == cg.teamScores[1] ) { if ( cg.teamScores[0] == cg.teamScores[1] ) {
@ -1064,10 +354,6 @@ const char *CG_GetGameStatusText(void) {
return s; return s;
} }
static void CG_DrawGameStatus(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle ) {
CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, CG_GetGameStatusText(), 0, 0, textStyle, FONT_MEDIUM);
}
const char *CG_GameTypeString(void) { const char *CG_GameTypeString(void) {
if ( cgs.gametype == GT_FFA ) { if ( cgs.gametype == GT_FFA ) {
return "Free For All"; return "Free For All";
@ -1078,17 +364,14 @@ const char *CG_GameTypeString(void) {
} else if ( cgs.gametype == GT_TEAM ) { } else if ( cgs.gametype == GT_TEAM ) {
return "Team FFA"; return "Team FFA";
} else if ( cgs.gametype == GT_SAGA ) { } else if ( cgs.gametype == GT_SAGA ) {
return "Saga"; return "N/A";
} else if ( cgs.gametype == GT_CTF ) { } else if ( cgs.gametype == GT_CTF ) {
return "Capture the Flag"; return "Capture the Flag";
} else if ( cgs.gametype == GT_CTY ) { } else if ( cgs.gametype == GT_CTY ) {
return "Capture the Ysalimari"; return "Capture the Ysalamiri";
} }
return ""; return "";
} }
static void CG_DrawGameType(rectDef_t *rect, float scale, vec4_t color, qhandle_t shader, int textStyle ) {
CG_Text_Paint(rect->x, rect->y + rect->h, scale, color, CG_GameTypeString(), 0, 0, textStyle, FONT_MEDIUM);
}
extern int MenuFontToHandle(int iMenuFont); extern int MenuFontToHandle(int iMenuFont);
@ -1709,6 +992,10 @@ void CG_ShowResponseHead(void) {
void CG_RunMenuScript(char **args) { void CG_RunMenuScript(char **args) {
} }
qboolean CG_DeferMenuScript (char **args)
{
return qfalse;
}
void CG_GetTeamColor(vec4_t *color) { void CG_GetTeamColor(vec4_t *color) {
if (cg.snap->ps.persistant[PERS_TEAM] == TEAM_RED) { if (cg.snap->ps.persistant[PERS_TEAM] == TEAM_RED) {

View file

File diff suppressed because it is too large Load diff

View file

@ -274,6 +274,7 @@ void CG_CheckChangedPredictableEvents( playerState_t *ps ) {
pushReward pushReward
================== ==================
*/ */
#ifdef JK2AWARDS
static void pushReward(sfxHandle_t sfx, qhandle_t shader, int rewardCount) { static void pushReward(sfxHandle_t sfx, qhandle_t shader, int rewardCount) {
if (cg.rewardStack < (MAX_REWARDSTACK-1)) { if (cg.rewardStack < (MAX_REWARDSTACK-1)) {
cg.rewardStack++; cg.rewardStack++;
@ -282,6 +283,7 @@ static void pushReward(sfxHandle_t sfx, qhandle_t shader, int rewardCount) {
cg.rewardCount[cg.rewardStack] = rewardCount; cg.rewardCount[cg.rewardStack] = rewardCount;
} }
} }
#endif
int cgAnnouncerTime = 0; //to prevent announce sounds from playing on top of each other int cgAnnouncerTime = 0; //to prevent announce sounds from playing on top of each other
@ -406,8 +408,13 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
} else if ( ps->persistant[PERS_RANK] == RANK_TIED_FLAG ) { } else if ( ps->persistant[PERS_RANK] == RANK_TIED_FLAG ) {
//CG_AddBufferedSound(cgs.media.tiedLeadSound); //CG_AddBufferedSound(cgs.media.tiedLeadSound);
} else if ( ( ops->persistant[PERS_RANK] & ~RANK_TIED_FLAG ) == 0 ) { } else if ( ( ops->persistant[PERS_RANK] & ~RANK_TIED_FLAG ) == 0 ) {
CG_AddBufferedSound(cgs.media.lostLeadSound); //rww - only bother saying this if you have more than 1 kill already.
cgAnnouncerTime = cg.time + 3000; //joining the server and hearing "the force is not with you" is silly.
if (ps->persistant[PERS_SCORE] > 0)
{
CG_AddBufferedSound(cgs.media.lostLeadSound);
cgAnnouncerTime = cg.time + 3000;
}
} }
} }
} }

View file

@ -2,7 +2,7 @@
// //
// cg_scoreboard -- draw the scoreboard on top of the game screen // cg_scoreboard -- draw the scoreboard on top of the game screen
#include "cg_local.h" #include "cg_local.h"
#include "../ui/ui_shared.h"
#define SCOREBOARD_X (0) #define SCOREBOARD_X (0)
@ -12,8 +12,8 @@
// Where the status bar starts, so we don't overwrite it // Where the status bar starts, so we don't overwrite it
#define SB_STATUSBAR 420 #define SB_STATUSBAR 420
#define SB_NORMAL_HEIGHT 40 #define SB_NORMAL_HEIGHT 25
#define SB_INTER_HEIGHT 16 // interleaved height #define SB_INTER_HEIGHT 15 // interleaved height
#define SB_MAXCLIENTS_NORMAL ((SB_STATUSBAR - SB_TOP) / SB_NORMAL_HEIGHT) #define SB_MAXCLIENTS_NORMAL ((SB_STATUSBAR - SB_TOP) / SB_NORMAL_HEIGHT)
#define SB_MAXCLIENTS_INTER ((SB_STATUSBAR - SB_TOP) / SB_INTER_HEIGHT - 1) #define SB_MAXCLIENTS_INTER ((SB_STATUSBAR - SB_TOP) / SB_INTER_HEIGHT - 1)
@ -30,14 +30,14 @@
#define SB_BOTICON_X (SCOREBOARD_X+32) #define SB_BOTICON_X (SCOREBOARD_X+32)
#define SB_HEAD_X (SCOREBOARD_X+64) #define SB_HEAD_X (SCOREBOARD_X+64)
#define SB_SCORELINE_X 64 #define SB_SCORELINE_X 100
#define SB_SCORELINE_WIDTH (640 - SB_SCORELINE_X * 2)
#define SB_RATING_WIDTH (6 * BIGCHAR_WIDTH) // width 6 #define SB_RATING_WIDTH 0 // (6 * BIGCHAR_WIDTH)
#define SB_SCORE_X (SB_SCORELINE_X + BIGCHAR_WIDTH) // width 6 #define SB_NAME_X (SB_SCORELINE_X)
#define SB_RATING_X (SB_SCORELINE_X + 6 * BIGCHAR_WIDTH) // width 6 #define SB_SCORE_X (SB_SCORELINE_X + .55 * SB_SCORELINE_WIDTH)
#define SB_PING_X (SB_SCORELINE_X + 12 * BIGCHAR_WIDTH + 8) // width 5 #define SB_PING_X (SB_SCORELINE_X + .70 * SB_SCORELINE_WIDTH)
#define SB_TIME_X (SB_SCORELINE_X + 17 * BIGCHAR_WIDTH + 8) // width 5 #define SB_TIME_X (SB_SCORELINE_X + .85 * SB_SCORELINE_WIDTH)
#define SB_NAME_X (SB_SCORELINE_X + 22 * BIGCHAR_WIDTH) // width 15
// The new and improved score board // The new and improved score board
// //
@ -58,11 +58,21 @@ static qboolean localClient; // true if local client has been displayed
CG_DrawScoreboard CG_DrawScoreboard
================= =================
*/ */
static void CG_DrawClientScore( int y, score_t *score, float *color, float fade, qboolean largeFormat ) { static void CG_DrawClientScore( int y, score_t *score, float *color, float fade, qboolean largeFormat )
char string[1024]; {
//vec3_t headAngles; //vec3_t headAngles;
clientInfo_t *ci; clientInfo_t *ci;
int iconx, headx; int iconx, headx;
float scale;
if ( largeFormat )
{
scale = 1.0f;
}
else
{
scale = 0.75f;
}
if ( score->client < 0 || score->client >= cgs.maxclients ) { if ( score->client < 0 || score->client >= cgs.maxclients ) {
Com_Printf( "Bad score->client: %i\n", score->client ); Com_Printf( "Bad score->client: %i\n", score->client );
@ -84,59 +94,32 @@ static void CG_DrawClientScore( int y, score_t *score, float *color, float fade,
} }
} else if ( ci->powerups & ( 1 << PW_REDFLAG ) ) { } else if ( ci->powerups & ( 1 << PW_REDFLAG ) ) {
if( largeFormat ) { if( largeFormat ) {
CG_DrawFlagModel( iconx, y*1.63, 32, 32, TEAM_RED, qfalse ); CG_DrawFlagModel( iconx*cgs.screenXScale, y*cgs.screenYScale, 32*cgs.screenXScale, 32*cgs.screenYScale, TEAM_RED, qfalse );
} }
else { else {
CG_DrawFlagModel( iconx, y*1.63, 32, 32, TEAM_RED, qfalse ); CG_DrawFlagModel( iconx*cgs.screenXScale, y*cgs.screenYScale, 32*cgs.screenXScale, 32*cgs.screenYScale, TEAM_RED, qfalse );
} }
} else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) ) { } else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) ) {
if( largeFormat ) { if( largeFormat ) {
CG_DrawFlagModel( iconx, y*1.63, 32, 32, TEAM_BLUE, qfalse ); CG_DrawFlagModel( iconx*cgs.screenXScale, y*cgs.screenYScale, 32*cgs.screenXScale, 32*cgs.screenYScale, TEAM_BLUE, qfalse );
} }
else { else {
CG_DrawFlagModel( iconx, y*1.63, 32, 32, TEAM_BLUE, qfalse ); CG_DrawFlagModel( iconx*cgs.screenXScale, y*cgs.screenYScale, 32*cgs.screenXScale, 32*cgs.screenYScale, TEAM_BLUE, qfalse );
} }
} else { } else {
// draw the wins / losses
/* /*
if ( ci->botSkill > 0 && ci->botSkill <= 5 ) { if ( cgs.gametype == GT_TOURNAMENT )
if ( cg_drawIcons.integer ) { {
if( largeFormat ) { CG_DrawSmallStringColor( iconx, y + SMALLCHAR_HEIGHT/2, va("%i/%i", ci->wins, ci->losses ), color );
CG_DrawPic( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, cgs.media.botSkillShaders[ ci->botSkill - 1 ] );
}
else {
CG_DrawPic( iconx, y, 16, 16, cgs.media.botSkillShaders[ ci->botSkill - 1 ] );
}
}
} else if ( ci->handicap < 100 ) {
Com_sprintf( string, sizeof( string ), "%i", ci->handicap );
if ( cgs.gametype == GT_TOURNAMENT )
CG_DrawSmallStringColor( iconx, y - SMALLCHAR_HEIGHT/2, string, color );
else
CG_DrawSmallStringColor( iconx, y, string, color );
} }
*/ */
//rww - in duel, we now show wins/losses in place of "frags". This is because duel now defaults to 1 kill per round.
// draw the wins / losses
if ( cgs.gametype == GT_TOURNAMENT ) {
Com_sprintf( string, sizeof( string ), "%i/%i", ci->wins, ci->losses );
CG_DrawSmallStringColor( iconx, y + SMALLCHAR_HEIGHT/2, string, color );
}
}
// draw the score line
if ( score->ping == -1 ) {
Com_sprintf(string, sizeof(string),
" connecting %s", ci->name);
} else if ( ci->team == TEAM_SPECTATOR ) {
Com_sprintf(string, sizeof(string),
" SPECT %3i %4i %s", score->ping, score->time, ci->name);
} else {
Com_sprintf(string, sizeof(string),
"%5i %4i %4i %s", score->score, score->ping, score->time, ci->name);
} }
// highlight your position // highlight your position
if ( score->client == cg.snap->ps.clientNum ) { if ( score->client == cg.snap->ps.clientNum )
{
float hcolor[4]; float hcolor[4];
int rank; int rank;
@ -167,22 +150,30 @@ static void CG_DrawClientScore( int y, score_t *score, float *color, float fade,
} }
hcolor[3] = fade * 0.7; hcolor[3] = fade * 0.7;
CG_FillRect( SB_SCORELINE_X + BIGCHAR_WIDTH + (SB_RATING_WIDTH / 2), y, CG_FillRect( SB_SCORELINE_X - 5, y + 2, 640 - SB_SCORELINE_X * 2 + 10, largeFormat?SB_NORMAL_HEIGHT:SB_INTER_HEIGHT, hcolor );
640 - SB_SCORELINE_X - BIGCHAR_WIDTH, BIGCHAR_HEIGHT+12, hcolor );
} }
// CG_DrawBigString( SB_SCORELINE_X + (SB_RATING_WIDTH / 2), y, string, fade ); CG_Text_Paint (SB_NAME_X, y, 0.9f * scale, colorWhite, ci->name,0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
//UI_DrawProportionalString(SB_SCORELINE_X + (SB_RATING_WIDTH/2), y, string, UI_DROPSHADOW, colorTable[CT_WHITE]); if ( ci->team != TEAM_SPECTATOR || cgs.gametype == GT_TOURNAMENT )
UI_DrawProportionalString(SB_SCORE_X + (SB_RATING_WIDTH / 2), y, va("%i", score->score), UI_SMALLFONT | UI_DROPSHADOW, colorTable[CT_WHITE]); {
UI_DrawProportionalString(SB_PING_X - (SB_RATING_WIDTH / 2), y, va("%i", score->ping), UI_SMALLFONT | UI_DROPSHADOW, colorTable[CT_WHITE]); if (cgs.gametype == GT_TOURNAMENT)
UI_DrawProportionalString(SB_TIME_X - (SB_RATING_WIDTH / 2), y, va("%i", score->time), UI_SMALLFONT | UI_DROPSHADOW, colorTable[CT_WHITE]); {
UI_DrawProportionalString(SB_NAME_X - (SB_RATING_WIDTH / 2), y, ci->name, UI_SMALLFONT | UI_DROPSHADOW, colorTable[CT_WHITE]); CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, colorWhite, va("%i/%i", ci->wins, ci->losses),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
}
else
{
CG_Text_Paint (SB_SCORE_X, y, 1.0f * scale, colorWhite, va("%i", score->score),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
}
}
CG_Text_Paint (SB_PING_X, y, 1.0f * scale, colorWhite, va("%i", score->ping),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
CG_Text_Paint (SB_TIME_X, y, 1.0f * scale, colorWhite, va("%i", score->time),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_SMALL );
// add the "ready" marker for intermission exiting // add the "ready" marker for intermission exiting
if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << score->client ) ) { if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << score->client ) )
CG_DrawBigStringColor( iconx-64, y+6, "READY", color ); {
CG_Text_Paint (SB_NAME_X - 64, y + 2, 0.7f * scale, colorWhite, CG_GetStripEdString("INGAMETEXT", "READY"),0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
} }
} }
@ -191,7 +182,8 @@ static void CG_DrawClientScore( int y, score_t *score, float *color, float fade,
CG_TeamScoreboard CG_TeamScoreboard
================= =================
*/ */
static int CG_TeamScoreboard( int y, team_t team, float fade, int maxClients, int lineHeight ) { static int CG_TeamScoreboard( int y, team_t team, float fade, int maxClients, int lineHeight, qboolean countOnly )
{
int i; int i;
score_t *score; score_t *score;
float color[4]; float color[4];
@ -210,7 +202,10 @@ static int CG_TeamScoreboard( int y, team_t team, float fade, int maxClients, in
continue; continue;
} }
CG_DrawClientScore( y + lineHeight * count, score, color, fade, lineHeight == SB_NORMAL_HEIGHT ); if ( !countOnly )
{
CG_DrawClientScore( y + lineHeight * count, score, color, fade, lineHeight == SB_NORMAL_HEIGHT );
}
count++; count++;
} }
@ -218,6 +213,28 @@ static int CG_TeamScoreboard( int y, team_t team, float fade, int maxClients, in
return count; return count;
} }
int CG_GetTeamCount(team_t team, int maxClients)
{
int i = 0;
int count = 0;
clientInfo_t *ci;
score_t *score;
for ( i = 0 ; i < cg.numScores && count < maxClients ; i++ )
{
score = &cg.scores[i];
ci = &cgs.clientinfo[ score->client ];
if ( team != ci->team )
{
continue;
}
count++;
}
return count;
}
/* /*
================= =================
CG_DrawScoreboard CG_DrawScoreboard
@ -266,21 +283,64 @@ qboolean CG_DrawOldScoreboard( void ) {
fade = *fadeColor; fade = *fadeColor;
} }
// fragged by ... line // fragged by ... line
if ( cg.killerName[0] ) { // or if in intermission and duel, prints the winner of the duel round
s = va("%s %s", CG_GetStripEdString("INGAMETEXT", "KILLEDBY"), cg.killerName ); if (cgs.gametype == GT_TOURNAMENT && cgs.duelWinner != -1 &&
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; cg.predictedPlayerState.pm_type == PM_INTERMISSION)
{
s = va("%s %s", cgs.clientinfo[cgs.duelWinner].name, CG_GetStripEdString("INGAMETEXT", "DUEL_WINS") );
/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
x = ( SCREEN_WIDTH - w ) / 2; x = ( SCREEN_WIDTH - w ) / 2;
y = 40; y = 40;
CG_DrawBigString( x, y, s, fade ); CG_DrawBigString( x, y, s, fade );
*/
x = ( SCREEN_WIDTH ) / 2;
y = 40;
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
else if (cgs.gametype == GT_TOURNAMENT && cgs.duelist1 != -1 && cgs.duelist2 != -1 &&
cg.predictedPlayerState.pm_type == PM_INTERMISSION)
{
s = va("%s %s %s", cgs.clientinfo[cgs.duelist1].name, CG_GetStripEdString("INGAMETEXT", "SPECHUD_VERSUS"), cgs.clientinfo[cgs.duelist2].name );
/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
x = ( SCREEN_WIDTH - w ) / 2;
y = 40;
CG_DrawBigString( x, y, s, fade );
*/
x = ( SCREEN_WIDTH ) / 2;
y = 40;
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
else if ( cg.killerName[0] ) {
s = va("%s %s", CG_GetStripEdString("INGAMETEXT", "KILLEDBY"), cg.killerName );
/*w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
x = ( SCREEN_WIDTH - w ) / 2;
y = 40;
CG_DrawBigString( x, y, s, fade );
*/
x = ( SCREEN_WIDTH ) / 2;
y = 40;
CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
} }
// current rank // current rank
if ( cgs.gametype < GT_TEAM) { if ( cgs.gametype < GT_TEAM) {
if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR ) { if (cg.snap->ps.persistant[PERS_TEAM] != TEAM_SPECTATOR )
s = va("%s place with %i", {
char sPlace[256];
char sOf[256];
char sWith[256];
trap_SP_GetStringTextString("INGAMETEXT_PLACE", sPlace, sizeof(sPlace));
trap_SP_GetStringTextString("INGAMETEXT_OF", sOf, sizeof(sOf));
trap_SP_GetStringTextString("INGAMETEXT_WITH", sWith, sizeof(sWith));
s = va("%s %s (%s %i) %s %i",
CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ), CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ),
sPlace,
sOf,
cg.numScores,
sWith,
cg.snap->ps.persistant[PERS_SCORE] ); cg.snap->ps.persistant[PERS_SCORE] );
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH; w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
x = ( SCREEN_WIDTH ) / 2; x = ( SCREEN_WIDTH ) / 2;
@ -297,26 +357,31 @@ qboolean CG_DrawOldScoreboard( void ) {
s = va("Blue leads %i to %i",cg.teamScores[1], cg.teamScores[0] ); s = va("Blue leads %i to %i",cg.teamScores[1], cg.teamScores[0] );
} }
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
x = ( SCREEN_WIDTH ) / 2; x = ( SCREEN_WIDTH ) / 2;
y = 60; y = 60;
//CG_DrawBigString( x, y, s, fade );
UI_DrawProportionalString(x, y, s, UI_CENTER|UI_DROPSHADOW, colorTable[CT_WHITE]); CG_Text_Paint ( x - CG_Text_Width ( s, 1.0f, FONT_MEDIUM ) / 2, y, 1.0f, colorWhite, s, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
} }
// scoreboard // scoreboard
y = SB_HEADER; y = SB_HEADER;
// CG_DrawPic( SB_SCORE_X + (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardScore ); CG_DrawPic ( SB_SCORELINE_X - 40, y - 5, SB_SCORELINE_WIDTH + 80, 40, trap_R_RegisterShaderNoMip ( "gfx/menus/menu_buttonback.tga" ) );
// CG_DrawPic( SB_PING_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardPing );
// CG_DrawPic( SB_TIME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardTime );
// CG_DrawPic( SB_NAME_X - (SB_RATING_WIDTH / 2), y, 64, 32, cgs.media.scoreboardName );
UI_DrawProportionalString(SB_SCORE_X + (SB_RATING_WIDTH / 2), y, "Score", UI_SMALLFONT | UI_DROPSHADOW, colorTable[CT_WHITE]); CG_Text_Paint ( SB_NAME_X, y, 1.0f, colorWhite, "Name", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
UI_DrawProportionalString(SB_PING_X - (SB_RATING_WIDTH / 2), y, "Ping", UI_SMALLFONT | UI_DROPSHADOW, colorTable[CT_WHITE]); if (cgs.gametype == GT_TOURNAMENT)
UI_DrawProportionalString(SB_TIME_X - (SB_RATING_WIDTH / 2), y, "Time", UI_SMALLFONT | UI_DROPSHADOW, colorTable[CT_WHITE]); {
UI_DrawProportionalString(SB_NAME_X - (SB_RATING_WIDTH / 2), y, "Name", UI_SMALLFONT | UI_DROPSHADOW, colorTable[CT_WHITE]); char sWL[100];
trap_SP_GetStringTextString("INGAMETEXT_W_L", sWL, sizeof(sWL));
CG_Text_Paint ( SB_SCORE_X, y, 1.0f, colorWhite, sWL, 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
else
{
CG_Text_Paint ( SB_SCORE_X, y, 1.0f, colorWhite, "Score", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
}
CG_Text_Paint ( SB_PING_X, y, 1.0f, colorWhite, "Ping", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
CG_Text_Paint ( SB_TIME_X, y, 1.0f, colorWhite, "Time", 0, 0, ITEM_TEXTSTYLE_OUTLINED, FONT_MEDIUM );
y = SB_TOP; y = SB_TOP;
@ -329,12 +394,20 @@ qboolean CG_DrawOldScoreboard( void ) {
} else { } else {
maxClients = SB_MAXCLIENTS_NORMAL; maxClients = SB_MAXCLIENTS_NORMAL;
lineHeight = SB_NORMAL_HEIGHT; lineHeight = SB_NORMAL_HEIGHT;
topBorderSize = 16; topBorderSize = 8;
bottomBorderSize = 16; bottomBorderSize = 8;
} }
localClient = qfalse; localClient = qfalse;
//I guess this should end up being able to display 19 clients at once.
//In a team game, if there are 9 or more clients on the team not in the lead,
//we only want to show 10 of the clients on the team in the lead, so that we
//have room to display the clients in the lead on the losing team.
//I guess this can be accomplished simply by printing the first teams score with a maxClients
//value passed in related to how many players are on both teams.
if ( cgs.gametype >= GT_TEAM ) { if ( cgs.gametype >= GT_TEAM ) {
// //
// teamplay scoreboard // teamplay scoreboard
@ -342,34 +415,82 @@ qboolean CG_DrawOldScoreboard( void ) {
y += lineHeight/2; y += lineHeight/2;
if ( cg.teamScores[0] >= cg.teamScores[1] ) { if ( cg.teamScores[0] >= cg.teamScores[1] ) {
n1 = CG_TeamScoreboard( y, TEAM_RED, fade, maxClients, lineHeight ); int team1MaxCl = CG_GetTeamCount(TEAM_RED, maxClients);
CG_DrawTeamBackground( 0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED ); int team2MaxCl = CG_GetTeamCount(TEAM_BLUE, maxClients);
if (team1MaxCl > 10 && (team1MaxCl+team2MaxCl) > maxClients)
{
team1MaxCl -= team2MaxCl;
//subtract as many as you have to down to 10, once we get there
//we just set it to 10
if (team1MaxCl < 10)
{
team1MaxCl = 10;
}
}
team2MaxCl = (maxClients-team1MaxCl); //team2 can display however many is left over after team1's display
n1 = CG_TeamScoreboard( y, TEAM_RED, fade, team1MaxCl, lineHeight, qtrue );
CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
CG_TeamScoreboard( y, TEAM_RED, fade, team1MaxCl, lineHeight, qfalse );
y += (n1 * lineHeight) + BIGCHAR_HEIGHT; y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
maxClients -= n1;
n2 = CG_TeamScoreboard( y, TEAM_BLUE, fade, maxClients, lineHeight ); //maxClients -= n1;
CG_DrawTeamBackground( 0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
n2 = CG_TeamScoreboard( y, TEAM_BLUE, fade, team2MaxCl, lineHeight, qtrue );
CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
CG_TeamScoreboard( y, TEAM_BLUE, fade, team2MaxCl, lineHeight, qfalse );
y += (n2 * lineHeight) + BIGCHAR_HEIGHT; y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
maxClients -= n2;
//maxClients -= n2;
maxClients -= (team1MaxCl+team2MaxCl);
} else { } else {
n1 = CG_TeamScoreboard( y, TEAM_BLUE, fade, maxClients, lineHeight ); int team1MaxCl = CG_GetTeamCount(TEAM_BLUE, maxClients);
CG_DrawTeamBackground( 0, y - topBorderSize, 640, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE ); int team2MaxCl = CG_GetTeamCount(TEAM_RED, maxClients);
if (team1MaxCl > 10 && (team1MaxCl+team2MaxCl) > maxClients)
{
team1MaxCl -= team2MaxCl;
//subtract as many as you have to down to 10, once we get there
//we just set it to 10
if (team1MaxCl < 10)
{
team1MaxCl = 10;
}
}
team2MaxCl = (maxClients-team1MaxCl); //team2 can display however many is left over after team1's display
n1 = CG_TeamScoreboard( y, TEAM_BLUE, fade, team1MaxCl, lineHeight, qtrue );
CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n1 * lineHeight + bottomBorderSize, 0.33f, TEAM_BLUE );
CG_TeamScoreboard( y, TEAM_BLUE, fade, team1MaxCl, lineHeight, qfalse );
y += (n1 * lineHeight) + BIGCHAR_HEIGHT; y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
maxClients -= n1;
n2 = CG_TeamScoreboard( y, TEAM_RED, fade, maxClients, lineHeight ); //maxClients -= n1;
CG_DrawTeamBackground( 0, y - topBorderSize, 640, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
n2 = CG_TeamScoreboard( y, TEAM_RED, fade, team2MaxCl, lineHeight, qtrue );
CG_DrawTeamBackground( SB_SCORELINE_X - 5, y - topBorderSize, 640 - SB_SCORELINE_X * 2 + 10, n2 * lineHeight + bottomBorderSize, 0.33f, TEAM_RED );
CG_TeamScoreboard( y, TEAM_RED, fade, team2MaxCl, lineHeight, qfalse );
y += (n2 * lineHeight) + BIGCHAR_HEIGHT; y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
maxClients -= n2;
//maxClients -= n2;
maxClients -= (team1MaxCl+team2MaxCl);
} }
n1 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients, lineHeight ); n1 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients, lineHeight, qfalse );
y += (n1 * lineHeight) + BIGCHAR_HEIGHT; y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
} else { } else {
// //
// free for all scoreboard // free for all scoreboard
// //
n1 = CG_TeamScoreboard( y, TEAM_FREE, fade, maxClients, lineHeight ); n1 = CG_TeamScoreboard( y, TEAM_FREE, fade, maxClients, lineHeight, qfalse );
y += (n1 * lineHeight) + BIGCHAR_HEIGHT; y += (n1 * lineHeight) + BIGCHAR_HEIGHT;
n2 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight ); n2 = CG_TeamScoreboard( y, TEAM_SPECTATOR, fade, maxClients - n1, lineHeight, qfalse );
y += (n2 * lineHeight) + BIGCHAR_HEIGHT; y += (n2 * lineHeight) + BIGCHAR_HEIGHT;
} }
@ -383,124 +504,13 @@ qboolean CG_DrawOldScoreboard( void ) {
} }
} }
/*
// load any models that have been deferred // load any models that have been deferred
if ( ++cg.deferredPlayerLoading > 10 ) { if ( ++cg.deferredPlayerLoading > 10 ) {
CG_LoadDeferredPlayers(); CG_LoadDeferredPlayers();
} }
*/
return qtrue; return qtrue;
} }
//================================================================================ //================================================================================
/*
================
CG_CenterGiantLine
================
*/
static void CG_CenterGiantLine( float y, const char *string ) {
float x;
vec4_t color;
color[0] = 1;
color[1] = 1;
color[2] = 1;
color[3] = 1;
x = 0.5 * ( 640 - GIANT_WIDTH * CG_DrawStrlen( string ) );
CG_DrawStringExt( x, y, string, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
}
/*
=================
CG_DrawTourneyScoreboard
Draw the oversize scoreboard for tournements
=================
*/
void CG_DrawOldTourneyScoreboard( void ) {
const char *s;
vec4_t color;
int min, tens, ones;
clientInfo_t *ci;
int y;
int i;
// request more scores regularly
if ( cg.scoresRequestTime + 2000 < cg.time ) {
cg.scoresRequestTime = cg.time;
trap_SendClientCommand( "score" );
}
color[0] = 1;
color[1] = 1;
color[2] = 1;
color[3] = 1;
// draw the dialog background
color[0] = color[1] = color[2] = 0;
color[3] = 1;
CG_FillRect( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, color );
// print the mesage of the day
s = CG_ConfigString( CS_MOTD );
if ( !s[0] ) {
s = "Scoreboard";
}
// print optional title
CG_CenterGiantLine( 8, s );
// print server time
ones = cg.time / 1000;
min = ones / 60;
ones %= 60;
tens = ones / 10;
ones %= 10;
s = va("%i:%i%i", min, tens, ones );
CG_CenterGiantLine( 64, s );
// print the two scores
y = 160;
if ( cgs.gametype >= GT_TEAM ) {
//
// teamplay scoreboard
//
CG_DrawStringExt( 8, y, "Red Team", color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
s = va("%i", cg.teamScores[0] );
CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
y += 64;
CG_DrawStringExt( 8, y, "Blue Team", color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
s = va("%i", cg.teamScores[1] );
CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
} else {
//
// free for all scoreboard
//
for ( i = 0 ; i < MAX_CLIENTS ; i++ ) {
ci = &cgs.clientinfo[i];
if ( !ci->infoValid ) {
continue;
}
if ( ci->team != TEAM_FREE ) {
continue;
}
CG_DrawStringExt( 8, y, ci->name, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
s = va("%i", ci->score );
CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 );
y += 64;
}
}
}

View file

@ -46,9 +46,17 @@ CG_ParseScores
================= =================
*/ */
static void CG_ParseScores( void ) { static void CG_ParseScores( void ) {
int i, powerups; int i, powerups, readScores;
cg.numScores = atoi( CG_Argv( 1 ) ); cg.numScores = atoi( CG_Argv( 1 ) );
readScores = cg.numScores;
if (readScores > MAX_CLIENT_SCORE_SEND)
{
readScores = MAX_CLIENT_SCORE_SEND;
}
if ( cg.numScores > MAX_CLIENTS ) { if ( cg.numScores > MAX_CLIENTS ) {
cg.numScores = MAX_CLIENTS; cg.numScores = MAX_CLIENTS;
} }
@ -57,7 +65,7 @@ static void CG_ParseScores( void ) {
cg.teamScores[1] = atoi( CG_Argv( 3 ) ); cg.teamScores[1] = atoi( CG_Argv( 3 ) );
memset( cg.scores, 0, sizeof( cg.scores ) ); memset( cg.scores, 0, sizeof( cg.scores ) );
for ( i = 0 ; i < cg.numScores ; i++ ) { for ( i = 0 ; i < readScores ; i++ ) {
// //
cg.scores[i].client = atoi( CG_Argv( i * 14 + 4 ) ); cg.scores[i].client = atoi( CG_Argv( i * 14 + 4 ) );
cg.scores[i].score = atoi( CG_Argv( i * 14 + 5 ) ); cg.scores[i].score = atoi( CG_Argv( i * 14 + 5 ) );
@ -129,10 +137,15 @@ void CG_ParseServerinfo( void ) {
cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) ); cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) );
cgs.teamflags = atoi( Info_ValueForKey( info, "teamflags" ) ); cgs.teamflags = atoi( Info_ValueForKey( info, "teamflags" ) );
cgs.fraglimit = atoi( Info_ValueForKey( info, "fraglimit" ) ); cgs.fraglimit = atoi( Info_ValueForKey( info, "fraglimit" ) );
cgs.duel_fraglimit = atoi( Info_ValueForKey( info, "duel_fraglimit" ) );
cgs.capturelimit = atoi( Info_ValueForKey( info, "capturelimit" ) ); cgs.capturelimit = atoi( Info_ValueForKey( info, "capturelimit" ) );
cgs.timelimit = atoi( Info_ValueForKey( info, "timelimit" ) ); cgs.timelimit = atoi( Info_ValueForKey( info, "timelimit" ) );
cgs.maxclients = atoi( Info_ValueForKey( info, "sv_maxclients" ) ); cgs.maxclients = atoi( Info_ValueForKey( info, "sv_maxclients" ) );
mapname = Info_ValueForKey( info, "mapname" ); mapname = Info_ValueForKey( info, "mapname" );
//rww - You must do this one here, Info_ValueForKey always uses the same memory pointer.
trap_Cvar_Set ( "ui_about_mapname", mapname );
Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname ); Com_sprintf( cgs.mapname, sizeof( cgs.mapname ), "maps/%s.bsp", mapname );
Q_strncpyz( cgs.redTeam, Info_ValueForKey( info, "g_redTeam" ), sizeof(cgs.redTeam) ); Q_strncpyz( cgs.redTeam, Info_ValueForKey( info, "g_redTeam" ), sizeof(cgs.redTeam) );
trap_Cvar_Set("g_redTeam", cgs.redTeam); trap_Cvar_Set("g_redTeam", cgs.redTeam);
@ -141,11 +154,11 @@ void CG_ParseServerinfo( void ) {
trap_Cvar_Set ( "ui_about_gametype", va("%i", cgs.gametype ) ); trap_Cvar_Set ( "ui_about_gametype", va("%i", cgs.gametype ) );
trap_Cvar_Set ( "ui_about_fraglimit", va("%i", cgs.fraglimit ) ); trap_Cvar_Set ( "ui_about_fraglimit", va("%i", cgs.fraglimit ) );
trap_Cvar_Set ( "ui_about_duellimit", va("%i", cgs.duel_fraglimit ) );
trap_Cvar_Set ( "ui_about_capturelimit", va("%i", cgs.capturelimit ) ); trap_Cvar_Set ( "ui_about_capturelimit", va("%i", cgs.capturelimit ) );
trap_Cvar_Set ( "ui_about_timelimit", va("%i", cgs.timelimit ) ); trap_Cvar_Set ( "ui_about_timelimit", va("%i", cgs.timelimit ) );
trap_Cvar_Set ( "ui_about_maxclients", va("%i", cgs.maxclients ) ); trap_Cvar_Set ( "ui_about_maxclients", va("%i", cgs.maxclients ) );
trap_Cvar_Set ( "ui_about_dmflags", va("%i", cgs.dmflags ) ); trap_Cvar_Set ( "ui_about_dmflags", va("%i", cgs.dmflags ) );
trap_Cvar_Set ( "ui_about_mapname", mapname );
trap_Cvar_Set ( "ui_about_hostname", Info_ValueForKey( info, "sv_hostname" ) ); trap_Cvar_Set ( "ui_about_hostname", Info_ValueForKey( info, "sv_hostname" ) );
trap_Cvar_Set ( "ui_about_needpass", Info_ValueForKey( info, "g_needpass" ) ); trap_Cvar_Set ( "ui_about_needpass", Info_ValueForKey( info, "g_needpass" ) );
trap_Cvar_Set ( "ui_about_botminplayers", Info_ValueForKey ( info, "bot_minplayers" ) ); trap_Cvar_Set ( "ui_about_botminplayers", Info_ValueForKey ( info, "bot_minplayers" ) );
@ -178,6 +191,7 @@ Called on load to set the initial values from configure strings
void CG_SetConfigValues( void ) void CG_SetConfigValues( void )
{ {
const char *s; const char *s;
const char *str;
cgs.scores1 = atoi( CG_ConfigString( CS_SCORES1 ) ); cgs.scores1 = atoi( CG_ConfigString( CS_SCORES1 ) );
cgs.scores2 = atoi( CG_ConfigString( CS_SCORES2 ) ); cgs.scores2 = atoi( CG_ConfigString( CS_SCORES2 ) );
@ -191,6 +205,38 @@ void CG_SetConfigValues( void )
// Track who the jedi master is // Track who the jedi master is
cgs.jediMaster = atoi ( CG_ConfigString ( CS_CLIENT_JEDIMASTER ) ); cgs.jediMaster = atoi ( CG_ConfigString ( CS_CLIENT_JEDIMASTER ) );
cgs.duelWinner = atoi ( CG_ConfigString ( CS_CLIENT_DUELWINNER ) );
str = CG_ConfigString(CS_CLIENT_DUELISTS);
if (str && str[0])
{
char buf[64];
int c = 0;
int i = 0;
while (str[i] && str[i] != '|')
{
buf[c] = str[i];
c++;
i++;
}
buf[c] = 0;
cgs.duelist1 = atoi ( buf );
c = 0;
i++;
while (str[i])
{
buf[c] = str[i];
c++;
i++;
}
buf[c] = 0;
cgs.duelist2 = atoi ( buf );
}
} }
/* /*
@ -265,6 +311,34 @@ static void CG_ConfigStringModified( void ) {
cgs.scores2 = atoi( str ); cgs.scores2 = atoi( str );
} else if ( num == CS_CLIENT_JEDIMASTER ) { } else if ( num == CS_CLIENT_JEDIMASTER ) {
cgs.jediMaster = atoi ( str ); cgs.jediMaster = atoi ( str );
} else if ( num == CS_CLIENT_DUELWINNER ) {
cgs.duelWinner = atoi ( str );
} else if ( num == CS_CLIENT_DUELISTS ) {
char buf[64];
int c = 0;
int i = 0;
while (str[i] && str[i] != '|')
{
buf[c] = str[i];
c++;
i++;
}
buf[c] = 0;
cgs.duelist1 = atoi ( buf );
c = 0;
i++;
while (str[i])
{
buf[c] = str[i];
c++;
i++;
}
buf[c] = 0;
cgs.duelist2 = atoi ( buf );
} else if ( num == CS_LEVEL_START_TIME ) { } else if ( num == CS_LEVEL_START_TIME ) {
cgs.levelStartTime = atoi( str ); cgs.levelStartTime = atoi( str );
} else if ( num == CS_VOTE_TIME ) { } else if ( num == CS_VOTE_TIME ) {
@ -459,6 +533,8 @@ void CG_KillCEntityInstances()
cg_entities[i].trickAlphaTime = 0; cg_entities[i].trickAlphaTime = 0;
VectorClear(cg_entities[i].turAngles); VectorClear(cg_entities[i].turAngles);
cg_entities[i].weapon = 0; cg_entities[i].weapon = 0;
cg_entities[i].teamPowerEffectTime = 0;
cg_entities[i].teamPowerType = 0;
i++; i++;
} }
@ -505,7 +581,7 @@ static void CG_MapRestart( void ) {
// play the "fight" sound if this is a restart without warmup // play the "fight" sound if this is a restart without warmup
if ( cg.warmup == 0 /* && cgs.gametype == GT_TOURNAMENT */) { if ( cg.warmup == 0 /* && cgs.gametype == GT_TOURNAMENT */) {
trap_S_StartLocalSound( cgs.media.countFightSound, CHAN_ANNOUNCER ); trap_S_StartLocalSound( cgs.media.countFightSound, CHAN_ANNOUNCER );
CG_CenterPrint( "BEGIN", 120, GIANTCHAR_WIDTH*2 ); CG_CenterPrint( CG_GetStripEdString("SVINGAME", "BEGIN_DUEL"), 120, GIANTCHAR_WIDTH*2 );
} }
if (cg_singlePlayerActive.integer) { if (cg_singlePlayerActive.integer) {
trap_Cvar_Set("ui_matchStartTime", va("%i", cg.time)); trap_Cvar_Set("ui_matchStartTime", va("%i", cg.time));
@ -546,7 +622,7 @@ typedef struct headModelVoiceChat_s
} headModelVoiceChat_t; } headModelVoiceChat_t;
voiceChatList_t voiceChatLists[MAX_VOICEFILES]; voiceChatList_t voiceChatLists[MAX_VOICEFILES];
headModelVoiceChat_t headModelVoiceChat[MAX_HEADMODELS]; //headModelVoiceChat_t headModelVoiceChat[MAX_HEADMODELS];
/* /*
================= =================
@ -740,13 +816,14 @@ CG_VoiceChatListForClient
*/ */
voiceChatList_t *CG_VoiceChatListForClient( int clientNum ) { voiceChatList_t *CG_VoiceChatListForClient( int clientNum ) {
clientInfo_t *ci; clientInfo_t *ci;
int voiceChatNum, i, j, k, gender;
char filename[MAX_QPATH], headModelName[MAX_QPATH];
if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) { if ( clientNum < 0 || clientNum >= MAX_CLIENTS ) {
clientNum = 0; clientNum = 0;
} }
ci = &cgs.clientinfo[ clientNum ]; ci = &cgs.clientinfo[ clientNum ];
/*
int voiceChatNum, i, j, k, gender;
char filename[MAX_QPATH], headModelName[MAX_QPATH];
for ( k = 0; k < 2; k++ ) { for ( k = 0; k < 2; k++ ) {
if ( k == 0 ) { if ( k == 0 ) {
@ -821,6 +898,7 @@ voiceChatList_t *CG_VoiceChatListForClient( int clientNum ) {
break; break;
} }
} }
*/
// just return the first voice chat list // just return the first voice chat list
return &voiceChatLists[0]; return &voiceChatLists[0];
} }
@ -996,6 +1074,77 @@ static void CG_RemoveChatEscapeChar( char *text ) {
text[l] = '\0'; text[l] = '\0';
} }
#define MAX_STRIPED_SV_STRING 1024
void CG_CheckSVStripEdRef(char *buf, const char *str)
{ //I don't really like doing this. But it utilizes the system that was already in place.
int i = 0;
int b = 0;
int strLen = 0;
qboolean gotStrip = qfalse;
if (!str || !str[0])
{
if (str)
{
strcpy(buf, str);
}
return;
}
strcpy(buf, str);
strLen = strlen(str);
if (strLen >= MAX_STRIPED_SV_STRING)
{
return;
}
while (i < strLen && str[i])
{
gotStrip = qfalse;
if (str[i] == '@' && (i+1) < strLen)
{
if (str[i+1] == '@' && (i+2) < strLen)
{
if (str[i+2] == '@' && (i+3) < strLen)
{ //@@@ should mean to insert a striped reference here, so insert it into buf at the current place
char stripRef[MAX_STRIPED_SV_STRING];
int r = 0;
while (i < strLen && str[i] == '@')
{
i++;
}
while (i < strLen && str[i] && str[i] != ' ' && str[i] != ':' && str[i] != '.' && str[i] != '\n')
{
stripRef[r] = str[i];
r++;
i++;
}
stripRef[r] = 0;
buf[b] = 0;
Q_strcat(buf, MAX_STRIPED_SV_STRING, CG_GetStripEdString("SVINGAME", stripRef));
b = strlen(buf);
}
}
}
if (!gotStrip)
{
buf[b] = str[i];
b++;
}
i++;
}
buf[b] = 0;
}
/* /*
================= =================
CG_ServerCommand CG_ServerCommand
@ -1039,8 +1188,75 @@ static void CG_ServerCommand( void ) {
return; return;
} }
if ( !strcmp( cmd, "nfr" ) )
{ //"nfr" == "new force rank" (want a short string)
int doMenu = 0;
int setTeam = 0;
int newRank = 0;
if (trap_Argc() < 3)
{
#ifdef _DEBUG
Com_Printf("WARNING: Invalid newForceRank string\n");
#endif
return;
}
newRank = atoi(CG_Argv(1));
doMenu = atoi(CG_Argv(2));
setTeam = atoi(CG_Argv(3));
trap_Cvar_Set("ui_rankChange", va("%i", newRank));
trap_Cvar_Set("ui_myteam", va("%i", setTeam));
if (!( trap_Key_GetCatcher() & KEYCATCH_UI ) && doMenu)
{
trap_OpenUIMenu(3);
}
return;
}
if ( !strcmp( cmd, "kg2" ) )
{ //Kill a ghoul2 instance in this slot.
//If it has been occupied since this message was sent somehow, the worst that can (should) happen
//is the instance will have to reinit with its current info.
int indexNum = 0;
int argNum = trap_Argc();
int i = 1;
if (argNum < 1)
{
return;
}
while (i < argNum)
{
indexNum = atoi(CG_Argv(i));
if (cg_entities[indexNum].ghoul2 && trap_G2_HaveWeGhoul2Models(cg_entities[indexNum].ghoul2))
{
if (indexNum < MAX_CLIENTS)
{ //You try to do very bad thing!
#ifdef _DEBUG
Com_Printf("WARNING: Tried to kill a client ghoul2 instance with a kg2 command!\n");
#endif
return;
}
trap_G2API_CleanGhoul2Models(&(cg_entities[indexNum].ghoul2));
}
i++;
}
return;
}
if ( !strcmp( cmd, "cp" ) ) { if ( !strcmp( cmd, "cp" ) ) {
CG_CenterPrint( CG_Argv(1), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH ); char strEd[MAX_STRIPED_SV_STRING];
CG_CheckSVStripEdRef(strEd, CG_Argv(1));
CG_CenterPrint( strEd, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH );
return; return;
} }
@ -1050,7 +1266,9 @@ static void CG_ServerCommand( void ) {
} }
if ( !strcmp( cmd, "print" ) ) { if ( !strcmp( cmd, "print" ) ) {
CG_Printf( "%s", CG_Argv(1) ); char strEd[MAX_STRIPED_SV_STRING];
CG_CheckSVStripEdRef(strEd, CG_Argv(1));
CG_Printf( "%s", strEd );
return; return;
} }

View file

@ -0,0 +1,171 @@
code
equ trap_Print -1 ; CG_PRINT
equ trap_Error -2 ; CG_ERROR
equ trap_Milliseconds -3 ; CG_MILLISECONDS
equ trap_Cvar_Register -4 ; CG_CVAR_REGISTER
equ trap_Cvar_Update -5 ; CG_CVAR_UPDATE
equ trap_Cvar_Set -6 ; CG_CVAR_SET
equ trap_Cvar_VariableStringBuffer -7 ; CG_CVAR_VARIABLESTRINGBUFFER
equ trap_Argc -8 ; CG_ARGC
equ trap_Argv -9 ; CG_ARGV
equ trap_Args -10 ; CG_ARGS
equ trap_FS_FOpenFile -11 ; CG_FS_FOPENFILE
equ trap_FS_Read -12 ; CG_FS_READ
equ trap_FS_Write -13 ; CG_FS_WRITE
equ trap_FS_FCloseFile -14 ; CG_FS_FCLOSEFILE
equ trap_SendConsoleCommand -15 ; CG_SENDCONSOLECOMMAND
equ trap_AddCommand -16 ; CG_ADDCOMMAND
equ trap_RemoveCommand -17 ; CG_REMOVECOMMAND
equ trap_SendClientCommand -18 ; CG_SENDCLIENTCOMMAND
equ trap_UpdateScreen -19 ; CG_UPDATESCREEN
equ trap_CM_LoadMap -20 ; CG_CM_LOADMAP
equ trap_CM_NumInlineModels -21 ; CG_CM_NUMINLINEMODELS
equ trap_CM_InlineModel -22 ; CG_CM_INLINEMODEL
equ trap_CM_TempBoxModel -23 ; CG_CM_TEMPBOXMODEL
equ trap_CM_TempCapsuleModel -24 ; CG_CM_TEMPCAPSULEMODEL
equ trap_CM_PointContents -25 ; CG_CM_POINTCONTENTS
equ trap_CM_TransformedPointContents -26 ; CG_CM_TRANSFORMEDPOINTCONTENTS
equ trap_CM_BoxTrace -27 ; CG_CM_BOXTRACE
equ trap_CM_CapsuleTrace -28 ; CG_CM_CAPSULETRACE
equ trap_CM_TransformedBoxTrace -29 ; CG_CM_TRANSFORMEDBOXTRACE
equ trap_CM_TransformedCapsuleTrace -30 ; CG_CM_TRANSFORMEDCAPSULETRACE
equ trap_CM_MarkFragments -31 ; CG_CM_MARKFRAGMENTS
equ trap_S_MuteSound -32 ; CG_S_MUTESOUND
equ trap_S_StartSound -33 ; CG_S_STARTSOUND
equ trap_S_StartLocalSound -34 ; CG_S_STARTLOCALSOUND
equ trap_S_ClearLoopingSounds -35 ; CG_S_CLEARLOOPINGSOUNDS
equ trap_S_AddLoopingSound -36 ; CG_S_ADDLOOPINGSOUND
equ trap_S_UpdateEntityPosition -37 ; CG_S_UPDATEENTITYPOSITION
equ trap_S_AddRealLoopingSound -38 ; CG_S_ADDREALLOOPINGSOUND
equ trap_S_StopLoopingSound -39 ; CG_S_STOPLOOPINGSOUND
equ trap_S_Respatialize -40 ; CG_S_RESPATIALIZE
equ trap_S_RegisterSound -41 ; CG_S_REGISTERSOUND
equ trap_S_StartBackgroundTrack -42 ; CG_S_STARTBACKGROUNDTRACK
equ trap_R_LoadWorldMap -43 ; CG_R_LOADWORLDMAP
equ trap_R_RegisterModel -44 ; CG_R_REGISTERMODEL
equ trap_R_RegisterSkin -45 ; CG_R_REGISTERSKIN
equ trap_R_RegisterShader -46 ; CG_R_REGISTERSHADER
equ trap_R_RegisterShaderNoMip -47 ; CG_R_REGISTERSHADERNOMIP
equ trap_R_RegisterFont -48 ; CG_R_REGISTERFONT
equ trap_R_Font_StrLenPixels -49 ; CG_R_FONT_STRLENPIXELS
equ trap_R_Font_StrLenChars -50 ; CG_R_FONT_STRLENCHARS
equ trap_R_Font_HeightPixels -51 ; CG_R_FONT_STRHEIGHTPIXELS
equ trap_R_Font_DrawString -52 ; CG_R_FONT_DRAWSTRING
equ trap_AnyLanguage_ReadCharFromString -53 ; CG_ANYLANGUAGE_READCHARFROMSTRING
equ trap_R_ClearScene -201 ; CG_R_CLEARSCENE
equ trap_R_AddRefEntityToScene -202 ; CG_R_ADDREFENTITYTOSCENE
equ trap_R_AddPolyToScene -203 ; CG_R_ADDPOLYTOSCENE
equ trap_R_AddPolysToScene -204 ; CG_R_ADDPOLYSTOSCENE
equ trap_R_LightForPoint -205 ; CG_R_LIGHTFORPOINT
equ trap_R_AddLightToScene -206 ; CG_R_ADDLIGHTTOSCENE
equ trap_R_AddAdditiveLightToScene -207 ; CG_R_ADDADDITIVELIGHTTOSCENE
equ trap_R_RenderScene -208 ; CG_R_RENDERSCENE
equ trap_R_SetColor -209 ; CG_R_SETCOLOR
equ trap_R_DrawStretchPic -210 ; CG_R_DRAWSTRETCHPIC
equ trap_R_ModelBounds -211 ; CG_R_MODELBOUNDS
equ trap_R_LerpTag -212 ; CG_R_LERPTAG
equ trap_R_DrawRotatePic -213 ; CG_R_DRAWROTATEPIC
equ trap_R_DrawRotatePic2 -214 ; CG_R_DRAWROTATEPIC2
equ trap_R_RemapShader -215 ; CG_R_REMAP_SHADER
equ trap_R_GetLightStyle -216 ; CG_R_GET_LIGHT_STYLE
equ trap_R_SetLightStyle -217 ; CG_R_SET_LIGHT_STYLE
equ trap_R_GetBModelVerts -218 ; CG_R_GET_BMODEL_VERTS
equ trap_FX_AddLine -219 ; CG_FX_ADDLINE
equ trap_GetGlconfig -220 ; CG_GETGLCONFIG
equ trap_GetGameState -221 ; CG_GETGAMESTATE
equ trap_GetCurrentSnapshotNumber -222 ; CG_GETCURRENTSNAPSHOTNUMBER
equ trap_GetSnapshot -223 ; CG_GETSNAPSHOT
equ trap_GetServerCommand -224 ; CG_GETSERVERCOMMAND
equ trap_GetCurrentCmdNumber -225 ; CG_GETCURRENTCMDNUMBER
equ trap_GetUserCmd -226 ; CG_GETUSERCMD
equ trap_SetUserCmdValue -227 ; CG_SETUSERCMDVALUE
equ trap_SetClientForceAngle -228 ; CG_SETCLIENTFORCEANGLE
equ trap_SetClientTurnExtent -229 ; CG_SETCLIENTTURNEXTENT
equ trap_OpenUIMenu -230 ; CG_OPENUIMENU
equ trap_MemoryRemaining -233 ; CG_MEMORY_REMAINING
equ trap_Key_IsDown -234 ; CG_KEY_ISDOWN
equ trap_Key_GetCatcher -235 ; CG_KEY_GETCATCHER
equ trap_Key_SetCatcher -236 ; CG_KEY_SETCATCHER
equ trap_Key_GetKey -237 ; CG_KEY_GETKEY
equ trap_PC_AddGlobalDefine -238 ; CG_PC_ADD_GLOBAL_DEFINE
equ trap_PC_LoadSource -239 ; CG_PC_LOAD_SOURCE
equ trap_PC_FreeSource -240 ; CG_PC_FREE_SOURCE
equ trap_PC_ReadToken -241 ; CG_PC_READ_TOKEN
equ trap_PC_SourceFileAndLine -242 ; CG_PC_SOURCE_FILE_AND_LINE
equ trap_PC_LoadGlobalDefines -243 ; CG_PC_LOAD_GLOBAL_DEFINES
equ trap_PC_RemoveAllGlobalDefines -244 ; CG_PC_REMOVE_ALL_GLOBAL_DEFINES
equ trap_S_StopBackgroundTrack -245 ; CG_S_STOPBACKGROUNDTRACK
equ trap_RealTime -246 ; CG_REAL_TIME
equ trap_SnapVector -247 ; CG_SNAPVECTOR
equ trap_CIN_PlayCinematic -248 ; CG_CIN_PLAYCINEMATIC
equ trap_CIN_StopCinematic -249 ; CG_CIN_STOPCINEMATIC
equ trap_CIN_RunCinematic -250 ; CG_CIN_RUNCINEMATIC
equ trap_CIN_DrawCinematic -251 ; CG_CIN_DRAWCINEMATIC
equ trap_CIN_SetExtents -252 ; CG_CIN_SETEXTENTS
equ trap_GetEntityToken -253 ; CG_GET_ENTITY_TOKEN
equ trap_R_inPVS -254 ; CG_R_INPVS
equ trap_FX_RegisterEffect -255 ; CG_FX_REGISTER_EFFECT
equ trap_FX_PlaySimpleEffect -256 ; CG_FX_PLAY_SIMPLE_EFFECT
equ trap_FX_PlayEffect -257 ; CG_FX_PLAY_EFFECT
equ trap_FX_PlayEntityEffect -258 ; CG_FX_PLAY_ENTITY_EFFECT
equ trap_FX_PlaySimpleEffectID -259 ; CG_FX_PLAY_SIMPLE_EFFECT_ID
equ trap_FX_PlayEffectID -260 ; CG_FX_PLAY_EFFECT_ID
equ trap_FX_PlayEntityEffectID -261 ; CG_FX_PLAY_ENTITY_EFFECT_ID
equ trap_FX_PlayBoltedEffectID -262 ; CG_FX_PLAY_BOLTED_EFFECT_ID
equ trap_FX_AddScheduledEffects -263 ; CG_FX_ADD_SCHEDULED_EFFECTS
equ trap_FX_InitSystem -264 ; CG_FX_INIT_SYSTEM
equ trap_FX_FreeSystem -265 ; CG_FX_FREE_SYSTEM
equ trap_FX_AdjustTime -266 ; CG_FX_ADJUST_TIME
equ trap_FX_AddPoly -267 ; CG_FX_ADDPOLY
equ trap_FX_AddBezier -268 ; CG_FX_ADDBEZIER
equ trap_FX_AddPrimitive -269 ; CG_FX_ADDPRIMITIVE
equ trap_FX_AddSprite -270 ; CG_FX_ADDSPRITE
equ trap_SP_Print -271 ; CG_SP_PRINT
equ trap_SP_GetStringTextString -272 ; CG_SP_GETSTRINGTEXTSTRING
equ trap_SP_Register -273 ; CG_SP_REGISTER
equ trap_ROFF_Clean -274 ; CG_ROFF_CLEAN
equ trap_ROFF_UpdateEntities -275 ; CG_ROFF_UPDATE_ENTITIES
equ trap_ROFF_Cache -276 ; CG_ROFF_CACHE
equ trap_ROFF_Play -277 ; CG_ROFF_PLAY
equ trap_ROFF_Purge_Ent -278 ; CG_ROFF_PURGE_ENT
equ trap_G2_ListModelSurfaces -279 ; CG_G2_LISTSURFACES
equ trap_G2_ListModelBones -280 ; CG_G2_LISTBONES
equ trap_G2_SetGhoul2ModelIndexes -281 ; CG_G2_SETMODELS
equ trap_G2_HaveWeGhoul2Models -282 ; CG_G2_HAVEWEGHOULMODELS
equ trap_G2API_GiveMeVectorFromMatrix -283 ; CG_G2_GIVEMEVECTORFROMMATRIX
equ trap_G2API_GetBoltMatrix -284 ; CG_G2_GETBOLT
equ trap_G2API_GetBoltMatrix_NoReconstruct -285 ; CG_G2_GETBOLT_NOREC
equ trap_G2API_InitGhoul2Model -286 ; CG_G2_INITGHOUL2MODEL
equ trap_G2API_CleanGhoul2Models -287 ; CG_G2_CLEANMODELS
equ trap_G2API_SetBoneAngles -288 ; CG_G2_ANGLEOVERRIDE
equ trap_G2API_SetBoneAnim -289 ; CG_G2_PLAYANIM
equ trap_G2API_GetGLAName -290 ; CG_G2_GETGLANAME
equ trap_G2API_CopyGhoul2Instance -291 ; CG_G2_COPYGHOUL2INSTANCE
equ trap_G2API_CopySpecificGhoul2Model -292 ; CG_G2_COPYSPECIFICGHOUL2MODEL
equ trap_G2API_DuplicateGhoul2Instance -293 ; CG_G2_DUPLICATEGHOUL2INSTANCE
equ trap_G2API_HasGhoul2ModelOnIndex -294 ; CG_G2_HASGHOUL2MODELONINDEX
equ trap_G2API_RemoveGhoul2Model -295 ; CG_G2_REMOVEGHOUL2MODEL
equ trap_G2API_AddBolt -296 ; CG_G2_ADDBOLT
equ trap_G2API_SetBoltInfo -297 ; CG_G2_SETBOLTON
equ trap_G2API_SetRootSurface -298 ; CG_G2_SETROOTSURFACE
equ trap_G2API_SetSurfaceOnOff -299 ; CG_G2_SETSURFACEONOFF
equ trap_G2API_SetNewOrigin -300 ; CG_G2_SETNEWORIGIN
equ trap_CG_RegisterSharedMemory -301 ; CG_SET_SHARED_BUFFER
; hardcoded functions
equ memset -101 ; CGAME_MEMSET
equ memcpy -102 ; CGAME_MEMCPY
equ strncpy -103 ; CGAME_STRNCPY
equ sin -104 ; CGAME_SIN
equ cos -105 ; CGAME_COS
equ atan2 -106 ; CGAME_ATAN2
equ sqrt -107 ; CGAME_SQRT
equ matrixmultiply -108 ; CGAME_MATRIXMULTIPLY
equ anglevectors -109 ; CGAME_ANGLEVECTORS
equ perpendicularvector -110 ; CGAME_PERPENDICULARVECTOR
equ floor -111 ; CGAME_FLOOR
equ ceil -112 ; CGAME_CEIL
equ acos -113 ; CGAME_ACOS
equ asin -114 ; CGAME_ASIN

View file

@ -553,9 +553,9 @@ qboolean trap_FX_FreeSystem( void )
return syscall( CG_FX_FREE_SYSTEM ); return syscall( CG_FX_FREE_SYSTEM );
} }
void trap_FX_AdjustTime( int time ) void trap_FX_AdjustTime( int time, vec3_t vieworg, vec3_t viewaxis[3] )
{ {
syscall( CG_FX_ADJUST_TIME, time ); syscall( CG_FX_ADJUST_TIME, time, vieworg, viewaxis );
} }
void trap_FX_AddPoly( addpolyArgStruct_t *p ) void trap_FX_AddPoly( addpolyArgStruct_t *p )
@ -588,9 +588,9 @@ int trap_SP_GetStringTextString(const char *text, char *buffer, int bufferLength
return syscall( CG_SP_GETSTRINGTEXTSTRING, text, buffer, bufferLength ); return syscall( CG_SP_GETSTRINGTEXTSTRING, text, buffer, bufferLength );
} }
void trap_SP_Register(char *file ) qboolean trap_SP_Register(char *file )
{ {
syscall( CG_SP_REGISTER,file ); return syscall( CG_SP_REGISTER,file );
} }
qboolean trap_ROFF_Clean( void ) qboolean trap_ROFF_Clean( void )

View file

@ -8,6 +8,10 @@
#include "cg_lights.h" #include "cg_lights.h"
#endif #endif
#define MASK_CAMERACLIP (MASK_SOLID|CONTENTS_PLAYERCLIP)
#define CAMERA_SIZE 4
/* /*
============================================================================= =============================================================================
@ -212,8 +216,8 @@ static void CG_StepOffset( void ) {
#define CAMERA_DAMP_INTERVAL 50 #define CAMERA_DAMP_INTERVAL 50
static vec3_t cameramins = { -4, -4, -4 }; static vec3_t cameramins = { -CAMERA_SIZE, -CAMERA_SIZE, -CAMERA_SIZE };
static vec3_t cameramaxs = { 4, 4, 4 }; static vec3_t cameramaxs = { CAMERA_SIZE, CAMERA_SIZE, CAMERA_SIZE };
vec3_t camerafwd, cameraup; vec3_t camerafwd, cameraup;
vec3_t cameraFocusAngles, cameraFocusLoc; vec3_t cameraFocusAngles, cameraFocusLoc;
@ -222,6 +226,9 @@ vec3_t cameraCurTarget={0,0,0}, cameraCurLoc={0,0,0};
vec3_t cameraOldLoc={0,0,0}, cameraNewLoc={0,0,0}; vec3_t cameraOldLoc={0,0,0}, cameraNewLoc={0,0,0};
int cameraLastFrame=0; int cameraLastFrame=0;
float cameraLastYaw=0;
float cameraStiffFactor=0.0f;
/* /*
=============== ===============
Notes on the camera viewpoint in and out... Notes on the camera viewpoint in and out...
@ -236,6 +243,9 @@ cg.refdefViewAngles
=============== ===============
*/ */
extern qboolean gCGHasFallVector;
extern vec3_t gCGFallVector;
/* /*
=============== ===============
CG_CalcTargetThirdPersonViewLocation CG_CalcTargetThirdPersonViewLocation
@ -252,7 +262,14 @@ static void CG_CalcIdealThirdPersonViewTarget(void)
} }
// Initialize IdealTarget // Initialize IdealTarget
VectorCopy(cg.refdef.vieworg, cameraFocusLoc); if (gCGHasFallVector)
{
VectorCopy(gCGFallVector, cameraFocusLoc);
}
else
{
VectorCopy(cg.refdef.vieworg, cameraFocusLoc);
}
// Add in the new viewheight // Add in the new viewheight
cameraFocusLoc[2] += cg.snap->ps.viewheight; cameraFocusLoc[2] += cg.snap->ps.viewheight;
@ -315,20 +332,22 @@ static void CG_ResetThirdPersonViewDamp(void)
VectorCopy(cameraIdealTarget, cameraCurTarget); VectorCopy(cameraIdealTarget, cameraCurTarget);
// First thing we do is trace from the first person viewpoint out to the new target location. // First thing we do is trace from the first person viewpoint out to the new target location.
CG_Trace(&trace, cameraFocusLoc, cameramins, cameramaxs, cameraCurTarget, cg.snap->ps.clientNum, MASK_SOLID|CONTENTS_PLAYERCLIP); CG_Trace(&trace, cameraFocusLoc, cameramins, cameramaxs, cameraCurTarget, cg.snap->ps.clientNum, MASK_CAMERACLIP);
if (trace.fraction <= 1.0) if (trace.fraction <= 1.0)
{ {
VectorCopy(trace.endpos, cameraCurTarget); VectorCopy(trace.endpos, cameraCurTarget);
} }
// Now we trace from the new target location to the new view location, to make sure there is nothing in the way. // Now we trace from the new target location to the new view location, to make sure there is nothing in the way.
CG_Trace(&trace, cameraCurTarget, cameramins, cameramaxs, cameraCurLoc, cg.snap->ps.clientNum, MASK_SOLID|CONTENTS_PLAYERCLIP); CG_Trace(&trace, cameraCurTarget, cameramins, cameramaxs, cameraCurLoc, cg.snap->ps.clientNum, MASK_CAMERACLIP);
if (trace.fraction <= 1.0) if (trace.fraction <= 1.0)
{ {
VectorCopy(trace.endpos, cameraCurLoc); VectorCopy(trace.endpos, cameraCurLoc);
} }
cameraLastFrame = cg.time; cameraLastFrame = cg.time;
cameraLastYaw = cameraFocusAngles[YAW];
cameraStiffFactor = 0.0f;
} }
// This is called every frame. // This is called every frame.
@ -368,7 +387,7 @@ static void CG_UpdateThirdPersonTargetDamp(void)
// Now we trace to see if the new location is cool or not. // Now we trace to see if the new location is cool or not.
// First thing we do is trace from the first person viewpoint out to the new target location. // First thing we do is trace from the first person viewpoint out to the new target location.
CG_Trace(&trace, cameraFocusLoc, cameramins, cameramaxs, cameraCurTarget, cg.snap->ps.clientNum, MASK_SOLID|CONTENTS_PLAYERCLIP); CG_Trace(&trace, cameraFocusLoc, cameramins, cameramaxs, cameraCurTarget, cg.snap->ps.clientNum, MASK_CAMERACLIP);
if (trace.fraction < 1.0) if (trace.fraction < 1.0)
{ {
VectorCopy(trace.endpos, cameraCurTarget); VectorCopy(trace.endpos, cameraCurTarget);
@ -405,6 +424,12 @@ static void CG_UpdateThirdPersonCameraDamp(void)
dampfactor = (1.0-cg_thirdPersonCameraDamp.value)*(pitch*pitch); dampfactor = (1.0-cg_thirdPersonCameraDamp.value)*(pitch*pitch);
dampfactor += cg_thirdPersonCameraDamp.value; dampfactor += cg_thirdPersonCameraDamp.value;
// Now we also multiply in the stiff factor, so that faster yaw changes are stiffer.
if (cameraStiffFactor > 0.0f)
{ // The cameraStiffFactor is how much of the remaining damp below 1 should be shaved off, i.e. approach 1 as stiffening increases.
dampfactor += (1.0-dampfactor)*cameraStiffFactor;
}
} }
if (dampfactor>=1.0) if (dampfactor>=1.0)
@ -431,10 +456,12 @@ static void CG_UpdateThirdPersonCameraDamp(void)
} }
// Now we trace from the new target location to the new view location, to make sure there is nothing in the way. // Now we trace from the new target location to the new view location, to make sure there is nothing in the way.
CG_Trace(&trace, cameraCurTarget, cameramins, cameramaxs, cameraCurLoc, cg.snap->ps.clientNum, MASK_SOLID|CONTENTS_PLAYERCLIP); CG_Trace(&trace, cameraCurTarget, cameramins, cameramaxs, cameraCurLoc, cg.snap->ps.clientNum, MASK_CAMERACLIP);
if (trace.fraction < 1.0) if (trace.fraction < 1.0)
{ {
VectorCopy( trace.endpos, cameraCurLoc ); VectorCopy( trace.endpos, cameraCurLoc );
//FIXME: when the trace hits movers, it gets very very jaggy... ? //FIXME: when the trace hits movers, it gets very very jaggy... ?
/* /*
//this doesn't actually help any //this doesn't actually help any
@ -475,6 +502,9 @@ static void CG_OffsetThirdPersonView( void )
{ {
vec3_t diff; vec3_t diff;
float thirdPersonHorzOffset = cg_thirdPersonHorzOffset.value; float thirdPersonHorzOffset = cg_thirdPersonHorzOffset.value;
float deltayaw;
cameraStiffFactor = 0.0;
// Set camera viewing direction. // Set camera viewing direction.
VectorCopy( cg.refdefViewAngles, cameraFocusAngles ); VectorCopy( cg.refdefViewAngles, cameraFocusAngles );
@ -511,6 +541,26 @@ static void CG_OffsetThirdPersonView( void )
AngleVectors(cameraFocusAngles, camerafwd, NULL, cameraup); AngleVectors(cameraFocusAngles, camerafwd, NULL, cameraup);
deltayaw = fabs(cameraFocusAngles[YAW] - cameraLastYaw);
if (deltayaw > 180.0f)
{ // Normalize this angle so that it is between 0 and 180.
deltayaw = fabs(deltayaw - 360.0f);
}
cameraStiffFactor = deltayaw / (float)(cg.time-cameraLastFrame);
if (cameraStiffFactor < 1.0)
{
cameraStiffFactor = 0.0;
}
else if (cameraStiffFactor > 2.5)
{
cameraStiffFactor = 0.75;
}
else
{ // 1 to 2 scales from 0.0 to 0.5
cameraStiffFactor = (cameraStiffFactor-1.0f)*0.5f;
}
cameraLastYaw = cameraFocusAngles[YAW];
// Move the target to the new location. // Move the target to the new location.
CG_UpdateThirdPersonTargetDamp(); CG_UpdateThirdPersonTargetDamp();
CG_UpdateThirdPersonCameraDamp(); CG_UpdateThirdPersonCameraDamp();
@ -601,7 +651,7 @@ static void CG_OffsetThirdPersonView( void ) {
// in a solid block. Use an 8 by 8 block to prevent the view from near clipping anything // in a solid block. Use an 8 by 8 block to prevent the view from near clipping anything
if (!cg_cameraMode.integer) { if (!cg_cameraMode.integer) {
CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_SOLID ); CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_CAMERACLIP);
if ( trace.fraction != 1.0 ) { if ( trace.fraction != 1.0 ) {
VectorCopy( trace.endpos, view ); VectorCopy( trace.endpos, view );
@ -609,7 +659,7 @@ static void CG_OffsetThirdPersonView( void ) {
// try another trace to this position, because a tunnel may have the ceiling // try another trace to this position, because a tunnel may have the ceiling
// close enogh that this is poking out // close enogh that this is poking out
CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_SOLID ); CG_Trace( &trace, cg.refdef.vieworg, mins, maxs, view, cg.predictedPlayerState.clientNum, MASK_CAMERACLIP);
VectorCopy( trace.endpos, view ); VectorCopy( trace.endpos, view );
} }
} }
@ -872,6 +922,16 @@ static int CG_CalcFov( void ) {
float fov_x, fov_y; float fov_x, fov_y;
float f; float f;
int inwater; int inwater;
float cgFov = cg_fov.value;
if (cgFov < 1)
{
cgFov = 1;
}
if (cgFov > 97)
{
cgFov = 97;
}
if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) { if ( cg.predictedPlayerState.pm_type == PM_INTERMISSION ) {
// if in intermission, use a fixed value // if in intermission, use a fixed value
@ -882,7 +942,7 @@ static int CG_CalcFov( void ) {
// dmflag to prevent wide fov for all clients // dmflag to prevent wide fov for all clients
fov_x = 80;//90; fov_x = 80;//90;
} else { } else {
fov_x = cg_fov.value; fov_x = cgFov;
if ( fov_x < 1 ) { if ( fov_x < 1 ) {
fov_x = 1; fov_x = 1;
} else if ( fov_x > 160 ) { } else if ( fov_x > 160 ) {
@ -900,9 +960,9 @@ static int CG_CalcFov( void ) {
{ {
zoomFov = 40.0f; zoomFov = 40.0f;
} }
else if (zoomFov > cg_fov.value) else if (zoomFov > cgFov)
{ {
zoomFov = cg_fov.value; zoomFov = cgFov;
} }
} }
@ -922,9 +982,9 @@ static int CG_CalcFov( void ) {
{ {
zoomFov = MAX_ZOOM_FOV; zoomFov = MAX_ZOOM_FOV;
} }
else if (zoomFov > cg_fov.value) else if (zoomFov > cgFov)
{ {
zoomFov = cg_fov.value; zoomFov = cgFov;
} }
else else
{ // Still zooming { // Still zooming
@ -980,7 +1040,7 @@ static int CG_CalcFov( void ) {
if (cg.predictedPlayerState.zoomMode) if (cg.predictedPlayerState.zoomMode)
{ {
cg.zoomSensitivity = zoomFov/cg_fov.value; cg.zoomSensitivity = zoomFov/cgFov;
} }
else if ( !cg.zoomed ) { else if ( !cg.zoomed ) {
cg.zoomSensitivity = 1; cg.zoomSensitivity = 1;
@ -1023,12 +1083,31 @@ static void CG_DamageBlendBlob( void )
VectorMA( ent.origin, cg.damageY * 8, cg.refdef.viewaxis[2], ent.origin ); VectorMA( ent.origin, cg.damageY * 8, cg.refdef.viewaxis[2], ent.origin );
ent.radius = cg.damageValue * 3 * ( 1.0 - ((float)t / maxTime) ); ent.radius = cg.damageValue * 3 * ( 1.0 - ((float)t / maxTime) );
ent.customShader = cgs.media.viewPainShader;
ent.shaderRGBA[0] = 180 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[1] = 50 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[2] = 50 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[3] = 255;
if (cg.snap->ps.damageType == 0)
{ //pure health
ent.customShader = cgs.media.viewPainShader;
ent.shaderRGBA[0] = 180 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[1] = 50 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[2] = 50 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[3] = 255;
}
else if (cg.snap->ps.damageType == 1)
{ //pure shields
ent.customShader = cgs.media.viewPainShader_Shields;
ent.shaderRGBA[0] = 50 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[1] = 180 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[2] = 50 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[3] = 255;
}
else
{ //shields and health
ent.customShader = cgs.media.viewPainShader_ShieldsAndHealth;
ent.shaderRGBA[0] = 180 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[1] = 180 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[2] = 50 * ( 1.0 - ((float)t / maxTime) );
ent.shaderRGBA[3] = 255;
}
trap_R_AddRefEntityToScene( &ent ); trap_R_AddRefEntityToScene( &ent );
} }
@ -1132,6 +1211,11 @@ static int CG_CalcViewValues( void ) {
cg.xyspeed = sqrt( ps->velocity[0] * ps->velocity[0] + cg.xyspeed = sqrt( ps->velocity[0] * ps->velocity[0] +
ps->velocity[1] * ps->velocity[1] ); ps->velocity[1] * ps->velocity[1] );
if (cg.xyspeed > 270)
{
cg.xyspeed = 270;
}
VectorCopy( ps->origin, cg.refdef.vieworg ); VectorCopy( ps->origin, cg.refdef.vieworg );
VectorCopy( ps->viewangles, cg.refdefViewAngles ); VectorCopy( ps->viewangles, cg.refdefViewAngles );
@ -1306,16 +1390,63 @@ void CG_SE_UpdateShake( vec3_t origin, vec3_t angles )
VectorAdd( angles, moveDir, angles ); VectorAdd( angles, moveDir, angles );
} }
void CG_SE_UpdateMusic(void)
{
if (cgScreenEffects.music_volume_multiplier < 0.1)
{
cgScreenEffects.music_volume_multiplier = 1.0;
return;
}
if (cgScreenEffects.music_volume_time < cg.time)
{
if (cgScreenEffects.music_volume_multiplier != 1.0 || cgScreenEffects.music_volume_set)
{
char musMultStr[512];
cgScreenEffects.music_volume_multiplier += 0.1;
if (cgScreenEffects.music_volume_multiplier > 1.0)
{
cgScreenEffects.music_volume_multiplier = 1.0;
}
Com_sprintf(musMultStr, sizeof(musMultStr), "%f", cgScreenEffects.music_volume_multiplier);
trap_Cvar_Set("s_musicMult", musMultStr);
if (cgScreenEffects.music_volume_multiplier == 1.0)
{
cgScreenEffects.music_volume_set = qfalse;
}
else
{
cgScreenEffects.music_volume_time = cg.time + 200;
}
}
return;
}
if (!cgScreenEffects.music_volume_set)
{ //if the volume_time is >= cg.time, we should have a volume multiplier set
char musMultStr[512];
Com_sprintf(musMultStr, sizeof(musMultStr), "%f", cgScreenEffects.music_volume_multiplier);
trap_Cvar_Set("s_musicMult", musMultStr);
cgScreenEffects.music_volume_set = qtrue;
}
}
/* /*
================= =================
CG_CalcScreenEffects CG_CalcScreenEffects
Currently just for screen shaking Currently just for screen shaking (and music volume management)
================= =================
*/ */
void CG_CalcScreenEffects(void) void CG_CalcScreenEffects(void)
{ {
CG_SE_UpdateShake(cg.refdef.vieworg, cg.refdefViewAngles); CG_SE_UpdateShake(cg.refdef.vieworg, cg.refdefViewAngles);
CG_SE_UpdateMusic();
} }
void CGCam_Shake( float intensity, int duration ) void CGCam_Shake( float intensity, int duration )
@ -1327,6 +1458,24 @@ void CGCam_Shake( float intensity, int duration )
cgScreenEffects.shake_duration = duration; cgScreenEffects.shake_duration = duration;
cgScreenEffects.shake_start = cg.time; cgScreenEffects.shake_start = cg.time;
} }
void CGCam_SetMusicMult( float multiplier, int duration )
{
if (multiplier < 0.1f)
{
multiplier = 0.1f;
}
if (multiplier > 1.0f)
{
multiplier = 1.0f;
}
cgScreenEffects.music_volume_multiplier = multiplier;
cgScreenEffects.music_volume_time = cg.time + duration;
cgScreenEffects.music_volume_set = qfalse;
}
/* /*
================================ ================================
Screen Effect stuff ends here Screen Effect stuff ends here
@ -1346,6 +1495,11 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
cg.time = serverTime; cg.time = serverTime;
cg.demoPlayback = demoPlayback; cg.demoPlayback = demoPlayback;
if (cg.snap && ui_myteam.integer != cg.snap->ps.persistant[PERS_TEAM])
{
trap_Cvar_Set ( "ui_myteam", va("%i", cg.snap->ps.persistant[PERS_TEAM]) );
}
// update cvars // update cvars
CG_UpdateCvars(); CG_UpdateCvars();
@ -1356,7 +1510,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
return; return;
} }
trap_FX_AdjustTime( cg.time ); trap_FX_AdjustTime( cg.time, cg.refdef.vieworg, cg.refdef.viewaxis );
CG_RunLightStyles(); CG_RunLightStyles();
@ -1403,7 +1557,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
cg.renderingThirdPerson = cg_thirdPerson.integer || (cg.snap->ps.stats[STAT_HEALTH] <= 0); cg.renderingThirdPerson = cg_thirdPerson.integer || (cg.snap->ps.stats[STAT_HEALTH] <= 0);
if (cg.snap->ps.stats[STAT_HEALTH] > 0 && (cg.predictedPlayerState.weapon == WP_SABER || cg.predictedPlayerState.usingATST || if (cg.snap->ps.stats[STAT_HEALTH] > 0 && (cg.predictedPlayerState.weapon == WP_SABER || cg.predictedPlayerState.usingATST ||
cg.predictedPlayerState.forceHandExtend == HANDEXTEND_KNOCKDOWN)) cg.predictedPlayerState.forceHandExtend == HANDEXTEND_KNOCKDOWN || cg.predictedPlayerState.fallingToDeath))
{ {
cg.renderingThirdPerson = 1; cg.renderingThirdPerson = 1;
} }
@ -1431,7 +1585,7 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
} }
CG_AddViewWeapon( &cg.predictedPlayerState ); CG_AddViewWeapon( &cg.predictedPlayerState );
if ( !cg.hyperspace ) if ( !cg.hyperspace)
{ {
trap_FX_AddScheduledEffects(); trap_FX_AddScheduledEffects();
} }
@ -1455,6 +1609,18 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo
// if there are any entities flagged as sound trackers and attached to other entities, update their sound pos // if there are any entities flagged as sound trackers and attached to other entities, update their sound pos
CG_UpdateSoundTrackers(); CG_UpdateSoundTrackers();
if (gCGHasFallVector)
{
vec3_t lookAng;
VectorSubtract(cg.snap->ps.origin, cg.refdef.vieworg, lookAng);
VectorNormalize(lookAng);
vectoangles(lookAng, lookAng);
VectorCopy(gCGFallVector, cg.refdef.vieworg);
AnglesToAxis(lookAng, cg.refdef.viewaxis);
}
// update audio positions // update audio positions
trap_S_Respatialize( cg.snap->ps.clientNum, cg.refdef.vieworg, cg.refdef.viewaxis, inwater ); trap_S_Respatialize( cg.snap->ps.clientNum, cg.refdef.vieworg, cg.refdef.viewaxis, inwater );

View file

@ -80,6 +80,12 @@ void CG_RegisterWeapon( int weaponNum) {
strcat( path, "_barrel.md3" ); strcat( path, "_barrel.md3" );
weaponInfo->barrelModel = trap_R_RegisterModel( path ); weaponInfo->barrelModel = trap_R_RegisterModel( path );
} }
else if (weaponNum == WP_STUN_BATON)
{ //only weapon with more than 1 barrel..
trap_R_RegisterModel("models/weapons2/stun_baton/baton_barrel.md3");
trap_R_RegisterModel("models/weapons2/stun_baton/baton_barrel2.md3");
trap_R_RegisterModel("models/weapons2/stun_baton/baton_barrel3.md3");
}
else else
{ {
weaponInfo->barrelModel = 0; weaponInfo->barrelModel = 0;
@ -114,19 +120,22 @@ void CG_RegisterWeapon( int weaponNum) {
weaponInfo->firingSound = trap_S_RegisterSound( "sound/weapons/saber/saberhum.wav" ); weaponInfo->firingSound = trap_S_RegisterSound( "sound/weapons/saber/saberhum.wav" );
// weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/melee/fstatck.wav" ); // weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/melee/fstatck.wav" );
*/ */
trap_R_RegisterShader( "gfx/effects/stunPass" ); //trap_R_RegisterShader( "gfx/effects/stunPass" );
trap_R_RegisterShader( "gfx/effects/stunTest" );
trap_FX_RegisterEffect( "stunBaton/flesh_impact" ); trap_FX_RegisterEffect( "stunBaton/flesh_impact" );
//TEMP //TEMP
trap_S_RegisterSound( "sound/weapons/melee/punch1.mp3" ); trap_S_RegisterSound( "sound/weapons/melee/punch1.mp3" );
trap_S_RegisterSound( "sound/weapons/melee/punch2.mp3" ); trap_S_RegisterSound( "sound/weapons/melee/punch2.mp3" );
trap_S_RegisterSound( "sound/weapons/melee/punch3.mp3" ); trap_S_RegisterSound( "sound/weapons/melee/punch3.mp3" );
trap_S_RegisterSound( "sound/weapons/melee/punch4.mp3" ); trap_S_RegisterSound( "sound/weapons/melee/punch4.mp3" );
trap_S_RegisterSound( "sound/weapons/baton/idle.wav" );
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/baton/fire.mp3" );
weaponInfo->altFlashSound[0] = trap_S_RegisterSound( "sound/weapons/baton/fire.mp3" );
break; break;
case WP_SABER: case WP_SABER:
MAKERGB( weaponInfo->flashDlightColor, 0.6f, 0.6f, 1.0f ); MAKERGB( weaponInfo->flashDlightColor, 0.6f, 0.6f, 1.0f );
weaponInfo->firingSound = trap_S_RegisterSound( "sound/weapons/saber/saberhum.wav1" ); weaponInfo->firingSound = trap_S_RegisterSound( "sound/weapons/saber/saberhum1.wav" );
weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/saber/saber_w.glm" ); weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/saber/saber_w.glm" );
break; break;
@ -349,7 +358,7 @@ void CG_RegisterWeapon( int weaponNum) {
weaponInfo->firingSound = NULL_SOUND; weaponInfo->firingSound = NULL_SOUND;
weaponInfo->chargeSound = NULL_SOUND; weaponInfo->chargeSound = NULL_SOUND;
weaponInfo->muzzleEffect = trap_FX_RegisterEffect( "flechette/muzzle_flash" ); weaponInfo->muzzleEffect = trap_FX_RegisterEffect( "flechette/muzzle_flash" );
weaponInfo->missileModel = NULL_HANDLE; weaponInfo->missileModel = trap_R_RegisterModel("models/weapons2/golan_arms/projectileMain.md3");
weaponInfo->missileSound = NULL_SOUND; weaponInfo->missileSound = NULL_SOUND;
weaponInfo->missileDlight = 0; weaponInfo->missileDlight = 0;
// weaponInfo->missileDlightColor = {0,0,0}; // weaponInfo->missileDlightColor = {0,0,0};

View file

@ -56,6 +56,11 @@ void CG_RegisterItemVisuals( int itemNum ) {
{ //in CTY the flag model is different { //in CTY the flag model is different
itemInfo->models[0] = trap_R_RegisterModel( item->world_model[1] ); itemInfo->models[0] = trap_R_RegisterModel( item->world_model[1] );
} }
else if (item->giType == IT_WEAPON &&
(item->giTag == WP_THERMAL || item->giTag == WP_TRIP_MINE || item->giTag == WP_DET_PACK))
{
itemInfo->models[0] = trap_R_RegisterModel( item->world_model[1] );
}
else else
{ {
itemInfo->models[0] = trap_R_RegisterModel( item->world_model[0] ); itemInfo->models[0] = trap_R_RegisterModel( item->world_model[0] );
@ -111,6 +116,14 @@ VIEW WEAPON
======================================================================================== ========================================================================================
*/ */
#define WEAPON_FORCE_BUSY_HOLSTER
#ifdef WEAPON_FORCE_BUSY_HOLSTER
//rww - this was done as a last resort. Forgive me.
static int cgWeapFrame = 0;
static int cgWeapFrameTime = 0;
#endif
/* /*
================= =================
CG_MapTorsoToWeaponFrame CG_MapTorsoToWeaponFrame
@ -119,6 +132,36 @@ CG_MapTorsoToWeaponFrame
*/ */
static int CG_MapTorsoToWeaponFrame( clientInfo_t *ci, int frame, int animNum ) { static int CG_MapTorsoToWeaponFrame( clientInfo_t *ci, int frame, int animNum ) {
animation_t *animations = bgGlobalAnimations; animation_t *animations = bgGlobalAnimations;
#ifdef WEAPON_FORCE_BUSY_HOLSTER
if (cg.snap->ps.forceHandExtend != HANDEXTEND_NONE || cgWeapFrameTime > cg.time)
{ //the reason for the after delay is so that it doesn't snap the weapon frame to the "idle" (0) frame
//for a very quick moment
if (cgWeapFrame < 6)
{
cgWeapFrame = 6;
cgWeapFrameTime = cg.time + 10;
}
if (cgWeapFrameTime < cg.time && cgWeapFrame < 10)
{
cgWeapFrame++;
cgWeapFrameTime = cg.time + 10;
}
if (cg.snap->ps.forceHandExtend != HANDEXTEND_NONE &&
cgWeapFrame == 10)
{
cgWeapFrameTime = cg.time + 100;
}
return cgWeapFrame;
}
else
{
cgWeapFrame = 0;
cgWeapFrameTime = 0;
}
#endif
switch( animNum ) switch( animNum )
{ {
@ -135,7 +178,6 @@ static int CG_MapTorsoToWeaponFrame( clientInfo_t *ci, int frame, int animNum )
return frame - animations[animNum].firstFrame + 6 + 4; return frame - animations[animNum].firstFrame + 6 + 4;
} }
break; break;
case BOTH_ATTACK1: case BOTH_ATTACK1:
case BOTH_ATTACK2: case BOTH_ATTACK2:
case BOTH_ATTACK3: case BOTH_ATTACK3:
@ -324,40 +366,6 @@ static void CG_LightningBolt( centity_t *cent, vec3_t origin ) {
} }
/*
======================
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);
}
return angle;
}
/* /*
======================== ========================
CG_AddWeaponWithPowerups CG_AddWeaponWithPowerups
@ -453,6 +461,7 @@ Ghoul2 Insert Start
cg.snap->ps.clientNum)) cg.snap->ps.clientNum))
{ {
CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups ); //don't draw the weapon if the player is invisible CG_AddWeaponWithPowerups( &gun, cent->currentState.powerups ); //don't draw the weapon if the player is invisible
/*
if ( weaponNum == WP_STUN_BATON ) if ( weaponNum == WP_STUN_BATON )
{ {
gun.shaderRGBA[0] = gun.shaderRGBA[1] = gun.shaderRGBA[2] = 25; gun.shaderRGBA[0] = gun.shaderRGBA[1] = gun.shaderRGBA[2] = 25;
@ -461,25 +470,75 @@ Ghoul2 Insert Start
gun.renderfx = RF_RGB_TINT | RF_FIRST_PERSON | RF_DEPTHHACK; gun.renderfx = RF_RGB_TINT | RF_FIRST_PERSON | RF_DEPTHHACK;
trap_R_AddRefEntityToScene( &gun ); trap_R_AddRefEntityToScene( &gun );
} }
*/
} }
// add the spinning barrel if (weaponNum == WP_STUN_BATON)
if ( weapon->barrelModel ) { {
memset( &barrel, 0, sizeof( barrel ) ); int i = 0;
VectorCopy( parent->lightingOrigin, barrel.lightingOrigin );
barrel.shadowPlane = parent->shadowPlane;
barrel.renderfx = parent->renderfx;
barrel.hModel = weapon->barrelModel; while (i < 3)
angles[YAW] = 0; {
angles[PITCH] = 0; memset( &barrel, 0, sizeof( barrel ) );
angles[ROLL] = 0; VectorCopy( parent->lightingOrigin, barrel.lightingOrigin );
barrel.shadowPlane = parent->shadowPlane;
barrel.renderfx = parent->renderfx;
AnglesToAxis( angles, barrel.axis ); if (i == 0)
{
barrel.hModel = trap_R_RegisterModel("models/weapons2/stun_baton/baton_barrel.md3");
}
else if (i == 1)
{
barrel.hModel = trap_R_RegisterModel("models/weapons2/stun_baton/baton_barrel2.md3");
}
else
{
barrel.hModel = trap_R_RegisterModel("models/weapons2/stun_baton/baton_barrel3.md3");
}
angles[YAW] = 0;
angles[PITCH] = 0;
angles[ROLL] = 0;
CG_PositionRotatedEntityOnTag( &barrel, parent/*&gun*/, /*weapon->weaponModel*/weapon->handsModel, "tag_barrel" ); AnglesToAxis( angles, barrel.axis );
CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups ); if (i == 0)
{
CG_PositionRotatedEntityOnTag( &barrel, parent/*&gun*/, /*weapon->weaponModel*/weapon->handsModel, "tag_barrel" );
}
else if (i == 1)
{
CG_PositionRotatedEntityOnTag( &barrel, parent/*&gun*/, /*weapon->weaponModel*/weapon->handsModel, "tag_barrel2" );
}
else
{
CG_PositionRotatedEntityOnTag( &barrel, parent/*&gun*/, /*weapon->weaponModel*/weapon->handsModel, "tag_barrel3" );
}
CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups );
i++;
}
}
else
{
// 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] = 0;
AnglesToAxis( angles, barrel.axis );
CG_PositionRotatedEntityOnTag( &barrel, parent/*&gun*/, /*weapon->weaponModel*/weapon->handsModel, "tag_barrel" );
CG_AddWeaponWithPowerups( &barrel, cent->currentState.powerups );
}
} }
} }
/* /*
@ -683,6 +742,16 @@ void CG_AddViewWeapon( playerState_t *ps ) {
float fovOffset; float fovOffset;
vec3_t angles; vec3_t angles;
weaponInfo_t *weapon; weaponInfo_t *weapon;
float cgFov = cg_fov.value;
if (cgFov < 1)
{
cgFov = 1;
}
if (cgFov > 97)
{
cgFov = 97;
}
if ( ps->persistant[PERS_TEAM] == TEAM_SPECTATOR ) { if ( ps->persistant[PERS_TEAM] == TEAM_SPECTATOR ) {
return; return;
@ -717,8 +786,8 @@ void CG_AddViewWeapon( playerState_t *ps ) {
} }
// drop gun lower at higher fov // drop gun lower at higher fov
if ( cg_fov.integer > 90 ) { if ( cgFov > 90 ) {
fovOffset = -0.2 * ( cg_fov.integer - 90 ); fovOffset = -0.2 * ( cgFov - 90 );
} else { } else {
fovOffset = 0; fovOffset = 0;
} }
@ -800,6 +869,11 @@ void CG_DrawIconBackground(void)
return; return;
} }
if (cg_hudFiles.integer)
{ //simple hud
return;
}
x2 = 30; x2 = 30;
y2 = SCREEN_HEIGHT-70; y2 = SCREEN_HEIGHT-70;
@ -965,7 +1039,6 @@ void CG_DrawWeaponSelect( void ) {
int i; int i;
int bits; int bits;
int count; int count;
char *name;
int smallIconSize,bigIconSize; int smallIconSize,bigIconSize;
int holdX,x,y,pad; int holdX,x,y,pad;
int sideLeftIconCnt,sideRightIconCnt; int sideLeftIconCnt,sideRightIconCnt;
@ -1177,15 +1250,16 @@ void CG_DrawWeaponSelect( void ) {
// draw the selected name // draw the selected name
if ( cg_weapons[ cg.weaponSelect ].item ) if ( cg_weapons[ cg.weaponSelect ].item )
{ {
name = cg_weapons[ cg.weaponSelect ].item->pickup_name; vec4_t textColor = { .875f, .718f, .121f, 1.0f };
if ( name ) char text[1024];
if ( trap_SP_GetStringTextString( va("INGAME_%s",cg_weapons[ cg.weaponSelect ].item->classname), text, sizeof( text )))
{ {
vec4_t textColor = { .875f, .718f, .121f, 1.0f }; UI_DrawProportionalString(320, y+45, text, UI_CENTER|UI_SMALLFONT, textColor);
// Just doing this for now...... }
//#ifdef _DEBUG else
//CG_DrawProportionalString(320, y + 48, name, CG_CENTER | CG_SMALLFONT, colorTable[CT_ICON_BLUE]); {
UI_DrawProportionalString(320, y+48, name, UI_CENTER|UI_SMALLFONT, textColor); UI_DrawProportionalString(320, y+45, cg_weapons[ cg.weaponSelect ].item->classname, UI_CENTER|UI_SMALLFONT, textColor);
//#endif
} }
} }

102
CODE-mp/cgame/cgame.bat Normal file
View file

@ -0,0 +1,102 @@
del /q vm
mkdir vm
cd vm
set cc=lcc -DQ3_VM -DMISSIONPACK -DCGAME -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\ui %1
%cc% ../../game/bg_misc.c
@if errorlevel 1 goto quit
%cc% ../../game/bg_weapons.c
@if errorlevel 1 goto quit
%cc% ../../game/bg_panimate.c
@if errorlevel 1 goto quit
%cc% ../../game/bg_pmove.c
@if errorlevel 1 goto quit
%cc% ../../game/bg_slidemove.c
@if errorlevel 1 goto quit
%cc% ../../game/bg_lib.c
@if errorlevel 1 goto quit
%cc% ../../game/bg_saber.c
@if errorlevel 1 goto quit
%cc% ../../game/q_math.c
@if errorlevel 1 goto quit
%cc% ../../game/q_shared.c
@if errorlevel 1 goto quit
%cc% ../cg_consolecmds.c
@if errorlevel 1 goto quit
%cc% ../cg_draw.c
@if errorlevel 1 goto quit
%cc% ../cg_drawtools.c
@if errorlevel 1 goto quit
%cc% ../cg_effects.c
@if errorlevel 1 goto quit
%cc% ../cg_ents.c
@if errorlevel 1 goto quit
%cc% ../cg_event.c
@if errorlevel 1 goto quit
%cc% ../cg_info.c
@if errorlevel 1 goto quit
%cc% ../cg_light.c
@if errorlevel 1 goto quit
%cc% ../cg_localents.c
@if errorlevel 1 goto quit
%cc% ../cg_main.c
@if errorlevel 1 goto quit
%cc% ../cg_marks.c
@if errorlevel 1 goto quit
%cc% ../cg_players.c
@if errorlevel 1 goto quit
%cc% ../cg_playerstate.c
@if errorlevel 1 goto quit
%cc% ../cg_predict.c
@if errorlevel 1 goto quit
%cc% ../cg_saga.c
@if errorlevel 1 goto quit
%cc% ../cg_scoreboard.c
@if errorlevel 1 goto quit
%cc% ../cg_servercmds.c
@if errorlevel 1 goto quit
%cc% ../cg_snapshot.c
@if errorlevel 1 goto quit
%cc% ../cg_turret.c
@if errorlevel 1 goto quit
%cc% ../cg_view.c
@if errorlevel 1 goto quit
%cc% ../cg_weaponinit.c
@if errorlevel 1 goto quit
%cc% ../cg_weapons.c
@if errorlevel 1 goto quit
%cc% ../fx_blaster.c
@if errorlevel 1 goto quit
%cc% ../fx_bowcaster.c
@if errorlevel 1 goto quit
%cc% ../fx_bryarpistol.c
@if errorlevel 1 goto quit
%cc% ../fx_demp2.c
@if errorlevel 1 goto quit
%cc% ../fx_disruptor.c
@if errorlevel 1 goto quit
%cc% ../fx_flechette.c
@if errorlevel 1 goto quit
%cc% ../fx_heavyrepeater.c
@if errorlevel 1 goto quit
%cc% ../fx_rocketlauncher.c
@if errorlevel 1 goto quit
%cc% ../fx_force.c
@if errorlevel 1 goto quit
%cc% ../../ui/ui_shared.c
@if errorlevel 1 goto quit
%cc% ../cg_newDraw.c
@if errorlevel 1 goto quit
sysmaker ../cg_public.h ../cg_syscalls.c ../cg_syscalls.asm
@if errorlevel 1 goto quit
q3asm -f ../cgame
@if errorlevel 1 goto quit
mkdir "..\..\base\vm"
copy *.map "..\..\base\vm"
copy *.qvm "..\..\base\vm"
:quit
cd ..

44
CODE-mp/cgame/cgame.q3asm Normal file
View file

@ -0,0 +1,44 @@
-o "cgame"
cg_main
..\cg_syscalls
cg_consolecmds
cg_draw
cg_drawtools
cg_effects
cg_ents
cg_event
cg_info
cg_light
cg_localents
cg_marks
cg_players
cg_playerstate
cg_predict
cg_saga
cg_scoreboard
cg_servercmds
cg_snapshot
cg_turret
cg_view
cg_weaponinit
cg_weapons
fx_blaster
fx_bowcaster
fx_bryarpistol
fx_demp2
fx_disruptor
fx_flechette
fx_heavyrepeater
fx_rocketlauncher
fx_force
bg_slidemove
bg_weapons
bg_panimate
bg_pmove
bg_lib
bg_misc
bg_saber
q_math
q_shared
ui_shared
cg_newDraw

View file

@ -0,0 +1,5 @@
SCC = This is a Source Code Control file
[JK2_cgame.dsp]
SCC_Aux_Path = "\\ravend\vss_projects\jk2sof2MP"
SCC_Project_Name = "$/General/code/cgame", UPCAAAAA

View file

@ -264,6 +264,12 @@ typedef enum {
** being run right now. These are constant once the OpenGL ** being run right now. These are constant once the OpenGL
** subsystem is initialized. ** subsystem is initialized.
*/ */
typedef enum {
TC_NONE,
TC_S3TC,
TC_S3TC_DXT
} textureCompression_t;
typedef struct { typedef struct {
char renderer_string[MAX_STRING_CHARS]; char renderer_string[MAX_STRING_CHARS];
char vendor_string[MAX_STRING_CHARS]; char vendor_string[MAX_STRING_CHARS];
@ -273,22 +279,10 @@ typedef struct {
int maxTextureSize; // queried from GL int maxTextureSize; // queried from GL
int maxActiveTextures; // multitexture ability int maxActiveTextures; // multitexture ability
int tfSolidCompressed;
float tfSolidCompressedBPT;
int tfAlphaCompressed;
float tfAlphaCompressedBPT;
int tfSolidUncompressed;
float tfSolidUncompressedBPT;
int tfAlphaUncompressed;
float tfAlphaUncompressedBPT;
int tfLightmap;
float tfLightmapBPT;
int tfCinematic; // Specially for the Voodoo4 - glTexImage2D can only handle 16 bit
float tfCinematicBPT;
int colorBits, depthBits, stencilBits; int colorBits, depthBits, stencilBits;
qboolean deviceSupportsGamma; qboolean deviceSupportsGamma;
textureCompression_t textureCompression;
qboolean textureEnvAddAvailable; qboolean textureEnvAddAvailable;
qboolean textureFilterAnisotropicAvailable; qboolean textureFilterAnisotropicAvailable;
qboolean clampToEdgeAvailable; qboolean clampToEdgeAvailable;

BIN
CODE-mp/cgame/vssver.scc Normal file

Binary file not shown.

View file

@ -0,0 +1,409 @@
#pragma warning( disable : 4786)
#include "client.h"
#include <windows.h>
#include "..\smartheap\smrtheap.h"
#if !defined(__Q_SHARED_H)
#include "../game/q_shared.h"
#endif
#if !defined(_QCOMMON_H_)
#include "../qcommon/qcommon.h"
#endif
#include <stdio.h>
#include <map>
using namespace std;
#if MEM_DEBUG
#include "..\smartheap\heapagnt.h"
static const int maxStack=2048;
static int TotalMem;
static int TotalBlocks;
static int nStack;
static char StackNames[maxStack][256];
static int StackSize[maxStack];
static int StackCount[maxStack];
static int StackCache[48];
static int StackCacheAt=0;
static int CheckpointSize[1000];
static int CheckpointCount[1000];
#define _FASTRPT_
cvar_t *mem_leakfile;
cvar_t *mem_leakreport;
MEM_BOOL MEM_CALLBACK MyMemReporter2(MEM_ERROR_INFO *info)
{
static char buffer[10000];
if (!info->objectCreationInfo)
return 1;
info=info->objectCreationInfo;
int idx=info->checkpoint;
if (idx<0||idx>=1000)
{
idx=0;
}
CheckpointCount[idx]++;
CheckpointSize[idx]+=info->argSize;
//return 1;
dbgMemFormatCall(info,buffer,9999);
if (strstr(buffer,"ntdll"))
return 1;
if (strstr(buffer,"CLBCATQ"))
return 1;
int i;
TotalBlocks++;
if (TotalBlocks%1000==0)
{
char mess[1000];
sprintf(mess,"%d blocks processed\n",TotalBlocks);
OutputDebugString(mess);
}
for (i=strlen(buffer);i>0;i--)
{
if (buffer[i]=='\n')
break;
}
if (!i)
return 1;
buffer[i]=0;
char *buf=buffer;
while (*buf)
{
if (*buf=='\n')
{
buf++;
break;
}
buf++;
}
char *start=0;
while (*buf)
{
while (*buf==' ')
buf++;
start=buf;
while (*buf!=0&&*buf!='\n')
buf++;
if (*start)
{
if (*buf)
{
*buf=0;
buf++;
}
if (strlen(start)>255)
start[255]=0;
if (strstr(start,"std::"))
{
// start=0;
continue;
}
if (strstr(start,"Malloc"))
{
start=0;
continue;
}
if (strstr(start,"FS_LoadFile"))
{
start=0;
continue;
}
if (strstr(start,"CopyString"))
{
start=0;
continue;
}
break;
}
}
if (!start||!*start)
{
start="UNKNOWN";
}
for (i=0;i<48;i++)
{
if (StackCache[i]<0||StackCache[i]>=nStack)
continue;
if (!strcmpi(start,StackNames[StackCache[i]]))
break;
}
if (i<48)
{
StackSize[StackCache[i]]+=info->argSize;
StackCount[StackCache[i]]++;
}
else
{
for (i=0;i<nStack;i++)
{
if (!strcmpi(start,StackNames[i]))
break;
}
if (i<nStack)
{
StackSize[i]+=info->argSize;
StackCount[i]++;
StackCache[StackCacheAt]=i;
StackCacheAt++;
if (StackCacheAt>=48)
StackCacheAt=0;
}
else if (i<maxStack)
{
strcpy(StackNames[i],start);
StackSize[i]=info->argSize;
StackCount[i]=1;
nStack++;
}
else if (nStack<maxStack)
{
nStack++;
strcpy(StackNames[maxStack-1],"*****OTHER*****");
StackSize[maxStack-1]=info->argSize;
StackCount[maxStack-1]=1;
}
else
{
StackSize[maxStack-1]+=info->argSize;
StackCount[maxStack-1]++;
}
}
TotalMem+=info->argSize;
return 1;
}
void SH_Checking_f(void);
#endif
class Leakage
{
MEM_POOL MyPool;
public:
Leakage()
{
MyPool = MemInitDefaultPool();
// MemPoolSetSmallBlockSize(MyPool, 16);
MemPoolSetSmallBlockAllocator(MyPool,MEM_SMALL_BLOCK_SH3);
#if MEM_DEBUG
dbgMemSetGuardSize(2);
#endif
EnableChecking(100000);
}
void LeakReport(void)
{
#if MEM_DEBUG
int i;
char mess[1000];
int blocks=dbgMemTotalCount();
int mem=dbgMemTotalSize()/1024;
sprintf(mess,"Final Memory Summary %d blocks %d K\n",blocks,mem);
OutputDebugString(mess);
for (i=0;i<1000;i++)
{
CheckpointSize[i]=0;
CheckpointCount[i]=0;
}
TotalMem=0;
TotalBlocks=0;
nStack=0;
MemSetErrorHandler(MyMemReporter2);
dbgMemReportLeakage(NULL,1,1000);
MemSetErrorHandler(MemDefaultErrorHandler);
if (TotalBlocks)
{
// Sort by size.
Sleep(100);
OutputDebugString("**************************************\n");
OutputDebugString("**********Memory Leak Report**********\n");
OutputDebugString("*************** By Size **************\n");
OutputDebugString("**************************************\n");
sprintf(mess,"Actual leakage %d blocks %d K\n",TotalBlocks,TotalMem/1024);
OutputDebugString(mess);
multimap<int,pair<int,char *> > sortit;
for (i=0;i<nStack;i++)
sortit.insert(pair<int,pair<int,char *> >(-StackSize[i],pair<int,char *>(StackCount[i],StackNames[i])));
multimap<int,pair<int,char *> >::iterator j;
Sleep(5);
for (j=sortit.begin();j!=sortit.end();j++)
{
sprintf(mess,"%5d KB %6d cnt %s\n",-(*j).first/1024,(*j).second.first,(*j).second.second);
// if (!(-(*j).first/1024))
// break;
Sleep(5);
OutputDebugString(mess);
}
// Sort by count.
Sleep(100);
OutputDebugString("**************************************\n");
OutputDebugString("**********Memory Leak Report**********\n");
OutputDebugString("************** By Count **************\n");
OutputDebugString("**************************************\n");
sprintf(mess,"Actual leakage %d blocks %d K\n",TotalBlocks,TotalMem/1024);
OutputDebugString(mess);
sortit.clear();
for (i=0;i<nStack;i++)
sortit.insert(pair<int,pair<int,char *> >(-StackCount[i],pair<int,char *>(StackSize[i],StackNames[i])));
Sleep(5);
for (j=sortit.begin();j!=sortit.end();j++)
{
sprintf(mess,"%5d KB %6d cnt %s\n",(*j).second.first/1024,-(*j).first,(*j).second.second);
// if (!(-(*j).first/1024))
// break;
Sleep(5);
OutputDebugString(mess);
}
}
else
{
OutputDebugString("No Memory Leaks\n");
}
// Sort by size.
Sleep(5);
OutputDebugString("***************************************\n");
OutputDebugString("By Tag, sort: size ********************\n");
OutputDebugString("size(K) count name \n");
OutputDebugString("-----------------------\n");
Sleep(5);
multimap<int,int> sorted;
for (i=0;i<1000;i++)
{
if (CheckpointCount[i])
{
sorted.insert(pair<int,int>(-CheckpointSize[i],i));
}
}
multimap<int,int>::iterator k;
for (k=sorted.begin();k!=sorted.end();k++)
{
// sprintf(mess,"%8d %8d %s\n",CheckpointSize[(*k).second]/1024,CheckpointCount[(*k).second],(*k).second>=2?tagDefs[(*k).second-2]:"unknown");
sprintf(mess,"%8d %8d %s\n",CheckpointSize[(*k).second]/1024,CheckpointCount[(*k).second],"unknown");
Sleep(5);
OutputDebugString(mess);
}
// Sort by count.
Sleep(5);
OutputDebugString("***************************************\n");
OutputDebugString("By Tag, sort: count *******************\n");
OutputDebugString("size(K) count name \n");
OutputDebugString("-----------------------\n");
Sleep(5);
sorted.clear();
for (i=0;i<1000;i++)
{
if (CheckpointCount[i])
{
sorted.insert(pair<int,int>(-CheckpointCount[i],i));
}
}
for (k=sorted.begin();k!=sorted.end();k++)
{
// sprintf(mess,"%8d %8d %s\n",CheckpointSize[(*k).second]/1024,CheckpointCount[(*k).second],(*k).second>=2?tagDefs[(*k).second-2]:"unknown");
sprintf(mess,"%8d %8d %s\n",CheckpointSize[(*k).second]/1024,CheckpointCount[(*k).second],"unknown");
Sleep(5);
OutputDebugString(mess);
}
#endif
}
~Leakage()
{
#if MEM_DEBUG
#if 0
if (mem_leakfile && mem_leakfile->integer)
{
dbgMemSetDefaultErrorOutput(DBGMEM_OUTPUT_FILE,"leakage.out");
dbgMemReportLeakage(NULL,1,1);
dbgMemSetDefaultErrorOutput(DBGMEM_OUTPUT_PROMPT,NULL);
}
#endif
if (mem_leakreport && mem_leakreport->integer)
{
LeakReport();
}
#endif
}
#if MEM_DEBUG
void EnableChecking(int x)
{
if (x)
{
dbgMemSetSafetyLevel(MEM_SAFETY_DEBUG);
dbgMemPoolSetCheckFrequency(MyPool, x);
dbgMemSetCheckFrequency(x);
dbgMemDeferFreeing(TRUE);
if (x>50000)
{
dbgMemSetDeferQueueLen(x+5000);
}
else
{
dbgMemSetDeferQueueLen(50000);
}
}
else
{
dbgMemSetSafetyLevel(MEM_SAFETY_SOME);
dbgMemDeferFreeing(FALSE);
}
}
#endif
};
static Leakage TheLeakage;
#if MEM_DEBUG
void MEM_Checking_f(void)
{
if (Cmd_Argc() != 2)
{
Com_Printf ("mem_checking <frequency>\n");
return;
}
if (atol(Cmd_Argv(1)) > 0 && atol(Cmd_Argv(1)) < 100)
{
Com_Printf ("mem_checking frequency is too low ( < 100 )\n");
return;
}
TheLeakage.EnableChecking(atol(Cmd_Argv(1)));
}
void MEM_Report_f(void)
{
TheLeakage.LeakReport();
}
/*
void myexit(void)
{
TheLeakage.LeakReport();
}
*/
void SH_Register(void)
{
Cmd_AddCommand ("mem_checking", MEM_Checking_f);
Cmd_AddCommand ("mem_report", MEM_Report_f);
mem_leakfile = Cvar_Get( "mem_leakfile", "1", 0 );
mem_leakreport = Cvar_Get( "mem_leakreport", "1", 0 );
// atexit(myexit);
}
#endif

View file

@ -71,8 +71,8 @@ qboolean FX_FreeSystem( void )
return (qboolean)FX_Free(); return (qboolean)FX_Free();
} }
void FX_AdjustTime( int time ) void FX_AdjustTime_Pos( int time, vec3_t refdef_vieworg, vec3_t refdef_viewaxis[3] )
{ {
theFxHelper.AdjustTime(time); theFxHelper.AdjustTime_Pos( time, refdef_vieworg, refdef_viewaxis );
} }

View file

@ -18,7 +18,7 @@ void FX_AddScheduledEffects( void );
int FX_InitSystem( void ); // called in CG_Init to purge the fx system. int FX_InitSystem( void ); // called in CG_Init to purge the fx system.
qboolean FX_FreeSystem( void ); // ditches all active effects; qboolean FX_FreeSystem( void ); // ditches all active effects;
void FX_AdjustTime( int time ); void FX_AdjustTime_Pos( int time, vec3_t refdef_vieworg, vec3_t refdef_viewaxis[3] );
#endif // FX_EXPORT_H_INC #endif // FX_EXPORT_H_INC

View file

@ -8,6 +8,8 @@
#include "FxScheduler.h" #include "FxScheduler.h"
#endif #endif
#include <set>
void FX_AddPrimitive( CEffect **pEffect, CCloud *effectCloud, int killTime ); void FX_AddPrimitive( CEffect **pEffect, CCloud *effectCloud, int killTime );
// Helper function // Helper function
@ -90,8 +92,11 @@ CCloud::CCloud() :
//mRefEnt.reType = RT_ENT_CHAIN; //mRefEnt.reType = RT_ENT_CHAIN;
} }
extern set<CCloud *> OutstandClouds;
CCloud::~CCloud() CCloud::~CCloud()
{ {
OutstandClouds.erase(this);
Die(); Die();
} }
@ -326,7 +331,7 @@ bool CParticle::Cull()
float len = VectorLengthSquared( dir ); float len = VectorLengthSquared( dir );
// Can't be too close // Can't be too close
if ( len < 24 * 24 ) if ( len < 12 * 12 )
{ {
return true; return true;
} }
@ -846,7 +851,7 @@ bool COrientedParticle::Cull()
float len = VectorLengthSquared( dir ); float len = VectorLengthSquared( dir );
// Can't be too close // Can't be too close
if ( len < 24 * 24 ) if ( len < 16 * 16 )
{ {
return true; return true;
} }

View file

@ -24,6 +24,9 @@
#include "../game/q_shared.h" #include "../game/q_shared.h"
#endif #endif
#include <set>
extern set<CCloud *> OutstandClouds;
#endif // EFFECTSED #endif // EFFECTSED
@ -96,7 +99,7 @@ void CFxScheduler::Clean(bool bRemoveTemplates /*= true*/, int idToPreserve /*=
next = itr; next = itr;
next++; next++;
if ((*itr)->mParent) if ((*itr)->mParent&&OutstandClouds.find((*itr)->mParent)!=OutstandClouds.end())
{ {
(*itr)->mParent->DecreasePending(); (*itr)->mParent->DecreasePending();
} }
@ -704,10 +707,14 @@ int CFxScheduler::ParseEffect( const char *file, CGPGroup *base )
{ {
type = CameraShake; type = CameraShake;
} }
/*
// NOTE: Pat requested that flashes be disabled in MP. Since fx files are shared with SP, this is the easiest way to accomplish that....
// code will fall through and become type NONE....and therefore not parsed and added to the effect definition.
else if ( !stricmp( grpName, "flash" )) else if ( !stricmp( grpName, "flash" ))
{ {
type = ScreenFlash; type = ScreenFlash;
} }
*/
else else
{ {
type = None; type = None;
@ -1028,6 +1035,8 @@ int totalEffects = 0;
// Return: // Return:
// none // none
//------------------------------------------------------ //------------------------------------------------------
extern cvar_t *cl_autolodscale;
extern int gCLTotalClientNum;
void CFxScheduler::PlayEffect( int id, CFxBoltInterface *obj ) void CFxScheduler::PlayEffect( int id, CFxBoltInterface *obj )
{ {
SEffectTemplate *fx; SEffectTemplate *fx;
@ -1082,6 +1091,8 @@ void CFxScheduler::PlayEffect( int id, CFxBoltInterface *obj )
effectCloud = FX_AddCloud(); effectCloud = FX_AddCloud();
float cullRange, effectDistSq = DistanceSquared( origin, theFxHelper.refdef.vieworg );
// Loop through the primitives and schedule each bit // Loop through the primitives and schedule each bit
for ( i = 0; i < fx->mPrimitiveCount; i++ ) for ( i = 0; i < fx->mPrimitiveCount; i++ )
{ {
@ -1095,6 +1106,23 @@ void CFxScheduler::PlayEffect( int id, CFxBoltInterface *obj )
} }
#endif #endif
if ( prim->mCullRange )
{
cullRange = prim->mCullRange;
if ( cl_autolodscale->integer )
{
if ( gCLTotalClientNum >= 8 )
{
cullRange *= 8.0f/gCLTotalClientNum;
}
}
if ( effectDistSq > cullRange ) // cull range has already been squared
{
// is too far away, so don't add this primitive group
continue;
}
}
count = prim->mSpawnCount.GetRoundedVal(); count = prim->mSpawnCount.GetRoundedVal();
if ( prim->mCopy ) if ( prim->mCopy )
@ -1571,6 +1599,8 @@ void CFxScheduler::PlayEffect( int id, vec3_t origin, vec3_t axis[3], const int
effectCloud = FX_AddCloud(); effectCloud = FX_AddCloud();
float cullRange, effectDistSq = DistanceSquared( origin, theFxHelper.refdef.vieworg );
// Loop through the primitives and schedule each bit // Loop through the primitives and schedule each bit
for ( i = 0; i < fx->mPrimitiveCount; i++ ) for ( i = 0; i < fx->mPrimitiveCount; i++ )
{ {
@ -1584,6 +1614,23 @@ void CFxScheduler::PlayEffect( int id, vec3_t origin, vec3_t axis[3], const int
} }
#endif #endif
if ( prim->mCullRange )
{
cullRange = prim->mCullRange;
if ( cl_autolodscale->integer )
{
if ( gCLTotalClientNum >= 8 )
{
cullRange *= 8.0f/gCLTotalClientNum;
}
}
if ( effectDistSq > cullRange ) // cull range has already been squared
{
// is too far away, so don't add this primitive group
continue;
}
}
count = prim->mSpawnCount.GetRoundedVal(); count = prim->mSpawnCount.GetRoundedVal();
if ( prim->mCopy ) if ( prim->mCopy )
@ -1762,10 +1809,71 @@ void CFxScheduler::PlayEffect( const char *file, vec3_t origin, vec3_t forward )
// Return: // Return:
// none // none
//------------------------------------------------------ //------------------------------------------------------
#if _JK2
#define CHC
void CFxScheduler::AddScheduledEffects( void ) void CFxScheduler::AddScheduledEffects( void )
{ {
TScheduledEffect::iterator itr, next; TScheduledEffect::iterator itr, next;
SScheduledEffect *schedEffect = 0; SScheduledEffect *schedEffect = 0;
itr = mFxSchedule.begin();
while ( itr != mFxSchedule.end() )
{
next = itr;
next++;
schedEffect = (*itr);
if ( *(*itr) <= theFxHelper.mTime )
{
if ((*itr)->mParent && OutstandClouds.find((*itr)->mParent)!=OutstandClouds.end())
{
// ok, are we spawning a bolt on effect or a normal one?
if ( (*itr)->mEntNum != -1 )
{
// Find out where the entity currently is
vec3_t lerpOrigin;
// VM_Call( cgvm, CG_GET_LERP_ORIGIN, (*itr)->mEntNum, lerpOrigin);
TCGVectorData *data = (TCGVectorData*)cl.mSharedMemory;
data->mEntityNum = (*itr)->mEntNum;
VM_Call( cgvm, CG_GET_LERP_ORIGIN );
VectorCopy(data->mPoint, lerpOrigin);
CreateEffect( (*itr)->mpTemplate,
lerpOrigin, (*itr)->mAxis,
theFxHelper.mTime - (*itr)->mStartTime, (*itr)->mParent );
}
else
{
CreateEffect( (*itr)->mpTemplate,
(*itr)->mOrigin, (*itr)->mAxis,
theFxHelper.mTime - (*itr)->mStartTime, (*itr)->mParent );
}
// Get 'em out of there.
if ((*itr)->mParent&&OutstandClouds.find((*itr)->mParent)!=OutstandClouds.end())
{
(*itr)->mParent->DecreasePending();
}
}
delete *itr;
mFxSchedule.erase(itr);
}
itr = next;
}
// Add all active effects into the scene
FX_Add();
}
#else
void CFxScheduler::AddScheduledEffects( void )
{
TScheduledEffect::iterator itr, next;
SScheduledEffect *schedEffect = 0;
#ifndef EFFECTSED #ifndef EFFECTSED
vec3_t origin; vec3_t origin;
vec3_t axis[3]; vec3_t axis[3];
@ -1792,7 +1900,7 @@ void CFxScheduler::AddScheduledEffects( void )
theFxHelper.mTime - (*itr)->mStartTime, (*itr)->mParent ); theFxHelper.mTime - (*itr)->mStartTime, (*itr)->mParent );
} }
else else
#endif #endif // CHC
/*if ((*itr)->mBoltNum == -1)*/ /*if ((*itr)->mBoltNum == -1)*/
if (1) if (1)
{// ok, are we spawning a bolt on effect or a normal one? {// ok, are we spawning a bolt on effect or a normal one?
@ -1813,7 +1921,7 @@ void CFxScheduler::AddScheduledEffects( void )
} }
else else
{ {
#endif #endif // EFFECTSED
CreateEffect( (*itr)->mpTemplate, CreateEffect( (*itr)->mpTemplate,
(*itr)->mOrigin, (*itr)->mAxis, (*itr)->mOrigin, (*itr)->mAxis,
theFxHelper.mTime - (*itr)->mStartTime, (*itr)->mParent ); theFxHelper.mTime - (*itr)->mStartTime, (*itr)->mParent );
@ -1907,6 +2015,8 @@ void CFxScheduler::AddScheduledEffects( void )
FX_Add(); FX_Add();
} }
#endif // #if1
//------------------------------------------------------ //------------------------------------------------------
// CreateEffect // CreateEffect
// Creates the specified fx taking into account the // Creates the specified fx taking into account the
@ -1930,7 +2040,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
trace_t tr; trace_t tr;
int emitterModel; int emitterModel;
CFxBoltInterface *fxBoltInterface = NULL; CFxBoltInterface *fxBoltInterface = NULL;
VectorCopy(origin, origin_certain); VectorCopy(origin, origin_certain);
if (effectCloud->IsBoltInterfaceValid()) if (effectCloud->IsBoltInterfaceValid())
@ -2149,7 +2258,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
VectorSet( eRGB, fx->mRedEnd.GetVal(), fx->mGreenEnd.GetVal(), fx->mBlueEnd.GetVal() ); VectorSet( eRGB, fx->mRedEnd.GetVal(), fx->mGreenEnd.GetVal(), fx->mBlueEnd.GetVal() );
} }
} }
// Now create the appropriate effect entity // Now create the appropriate effect entity
//------------------------ //------------------------
switch( fx->mType ) switch( fx->mType )
@ -2157,7 +2265,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
//--------- //---------
case Particle: case Particle:
//--------- //---------
FX_AddParticle( effectCloud, org, vel, accel, FX_AddParticle( effectCloud, org, vel, accel,
fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(), fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(),
fx->mAlphaStart.GetVal(), fx->mAlphaEnd.GetVal(), fx->mAlphaParm.GetVal(), fx->mAlphaStart.GetVal(), fx->mAlphaEnd.GetVal(), fx->mAlphaParm.GetVal(),
@ -2171,7 +2278,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
//--------- //---------
case Line: case Line:
//--------- //---------
FX_AddLine( effectCloud, org, org2, FX_AddLine( effectCloud, org, org2,
fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(), fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(),
fx->mAlphaStart.GetVal(), fx->mAlphaEnd.GetVal(), fx->mAlphaParm.GetVal(), fx->mAlphaStart.GetVal(), fx->mAlphaEnd.GetVal(), fx->mAlphaParm.GetVal(),
@ -2182,7 +2288,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
//--------- //---------
case Tail: case Tail:
//--------- //---------
FX_AddTail( effectCloud, org, vel, accel, FX_AddTail( effectCloud, org, vel, accel,
fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(), fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(),
fx->mLengthStart.GetVal(), fx->mLengthEnd.GetVal(), fx->mLengthParm.GetVal(), fx->mLengthStart.GetVal(), fx->mLengthEnd.GetVal(), fx->mLengthParm.GetVal(),
@ -2196,7 +2301,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
//---------------- //----------------
case Electricity: case Electricity:
//---------------- //----------------
FX_AddElectricity( effectCloud, org, org2, FX_AddElectricity( effectCloud, org, org2,
fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(), fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(),
fx->mAlphaStart.GetVal(), fx->mAlphaEnd.GetVal(), fx->mAlphaParm.GetVal(), fx->mAlphaStart.GetVal(), fx->mAlphaEnd.GetVal(), fx->mAlphaParm.GetVal(),
@ -2207,7 +2311,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
//--------- //---------
case Cylinder: case Cylinder:
//--------- //---------
FX_AddCylinder( effectCloud, org, ax[0], FX_AddCylinder( effectCloud, org, ax[0],
fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(), fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(),
fx->mSize2Start.GetVal(), fx->mSize2End.GetVal(), fx->mSize2Parm.GetVal(), fx->mSize2Start.GetVal(), fx->mSize2End.GetVal(), fx->mSize2Parm.GetVal(),
@ -2220,7 +2323,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
//--------- //---------
case Emitter: case Emitter:
//--------- //---------
// for chunk angles, you don't really need much control over the end result...you just want variation.. // for chunk angles, you don't really need much control over the end result...you just want variation..
VectorSet( ang, VectorSet( ang,
fx->mAngle1.GetVal(), fx->mAngle1.GetVal(),
@ -2259,7 +2361,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
/*CG_ImpactMark( fx->mMediaHandles.GetHandle(), org, ax[0], fx->mRotation.GetVal(), /*CG_ImpactMark( fx->mMediaHandles.GetHandle(), org, ax[0], fx->mRotation.GetVal(),
sRGB[0], sRGB[1], sRGB[2], fx->mAlphaStart.GetVal(), sRGB[0], sRGB[1], sRGB[2], fx->mAlphaStart.GetVal(),
qtrue, fx->mSizeStart.GetVal(), qfalse );*/ qtrue, fx->mSizeStart.GetVal(), qfalse );*/
//VM_Call(cgvm, CG_IMPACT_MARK, fx->mMediaHandles.GetHandle(), org, ax[0], (int)fx->mRotation.GetVal(), //VM_Call(cgvm, CG_IMPACT_MARK, fx->mMediaHandles.GetHandle(), org, ax[0], (int)fx->mRotation.GetVal(),
// (int)sRGB[0], (int)sRGB[1], (int)sRGB[2], (int)fx->mAlphaStart.GetVal(), (int)fx->mSizeStart.GetVal()); // (int)sRGB[0], (int)sRGB[1], (int)sRGB[2], (int)fx->mAlphaStart.GetVal(), (int)fx->mSizeStart.GetVal());
TCGImpactMark *data = (TCGImpactMark *)cl.mSharedMemory; TCGImpactMark *data = (TCGImpactMark *)cl.mSharedMemory;
@ -2280,7 +2381,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
//------------------- //-------------------
case OrientedParticle: case OrientedParticle:
//------------------- //-------------------
FX_AddOrientedParticle( effectCloud, org, ax[0], vel, accel, FX_AddOrientedParticle( effectCloud, org, ax[0], vel, accel,
fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(), fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(),
fx->mAlphaStart.GetVal(), fx->mAlphaEnd.GetVal(), fx->mAlphaParm.GetVal(), fx->mAlphaStart.GetVal(), fx->mAlphaEnd.GetVal(), fx->mAlphaParm.GetVal(),
@ -2294,21 +2394,18 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
//--------- //---------
case Sound: case Sound:
//--------- //---------
theFxHelper.PlaySound( org, ENTITYNUM_NONE, CHAN_AUTO, fx->mMediaHandles.GetHandle() ); theFxHelper.PlaySound( org, ENTITYNUM_NONE, CHAN_AUTO, fx->mMediaHandles.GetHandle() );
break; break;
//--------- //---------
case FxRunner: case FxRunner:
//--------- //---------
PlayEffect( fx->mPlayFxHandles.GetHandle(), org, ax ); PlayEffect( fx->mPlayFxHandles.GetHandle(), org, ax );
break; break;
//--------- //---------
case Light: case Light:
//--------- //---------
FX_AddLight( effectCloud, org, fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(), FX_AddLight( effectCloud, org, fx->mSizeStart.GetVal(), fx->mSizeEnd.GetVal(), fx->mSizeParm.GetVal(),
sRGB, eRGB, fx->mRGBParm.GetVal(), sRGB, eRGB, fx->mRGBParm.GetVal(),
fx->mLife.GetVal(), fx->mFlags ); fx->mLife.GetVal(), fx->mFlags );
@ -2326,7 +2423,6 @@ void CFxScheduler::CreateEffect( CPrimitiveTemplate *fx, vec3_t origin, vec3_t a
//-------------- //--------------
case ScreenFlash: case ScreenFlash:
//-------------- //--------------
FX_AddFlash( effectCloud, org, FX_AddFlash( effectCloud, org,
sRGB, eRGB, fx->mRGBParm.GetVal(), sRGB, eRGB, fx->mRGBParm.GetVal(),
fx->mLife.GetVal(), fx->mMediaHandles.GetHandle(), fx->mFlags ); fx->mLife.GetVal(), fx->mMediaHandles.GetHandle(), fx->mFlags );

View file

@ -204,6 +204,7 @@ public:
CFxRange mSpawnDelay; CFxRange mSpawnDelay;
CFxRange mSpawnCount; CFxRange mSpawnCount;
CFxRange mLife; CFxRange mLife;
int mCullRange;
CMediaHandles mMediaHandles; CMediaHandles mMediaHandles;
CMediaHandles mImpactFxHandles; CMediaHandles mImpactFxHandles;

View file

@ -45,7 +45,7 @@ void SFxHelper::Print( const char *msg, ... )
} }
//------------------------------------------------------ //------------------------------------------------------
void SFxHelper::AdjustTime( int time ) void SFxHelper::AdjustTime_Pos( int time, vec3_t refdef_vieworg, vec3_t refdef_viewaxis[3] )
{ {
if ( fx_freeze.integer ) if ( fx_freeze.integer )
{ {
@ -53,6 +53,10 @@ void SFxHelper::AdjustTime( int time )
} }
else else
{ {
VectorCopy( refdef_vieworg, refdef.vieworg );
VectorCopy( refdef_viewaxis[0], refdef.viewaxis[0] );
VectorCopy( refdef_viewaxis[1], refdef.viewaxis[1] );
VectorCopy( refdef_viewaxis[2], refdef.viewaxis[2] );
mOldTime = mTime; mOldTime = mTime;
mTime = time; mTime = time;
mFrameTime = mTime - mOldTime; mFrameTime = mTime - mOldTime;

View file

@ -69,7 +69,7 @@ public:
inline int GetFrameTime(void) { return mFrameTime; } inline int GetFrameTime(void) { return mFrameTime; }
void ReInit(void); void ReInit(void);
void AdjustTime( int time ); void AdjustTime_Pos( int time, vec3_t refdef_vieworg, vec3_t refdef_viewaxis[3] );
// These functions are wrapped and used by the fx system in case it makes things a bit more portable // These functions are wrapped and used by the fx system in case it makes things a bit more portable
void Print( const char *msg, ... ); void Print( const char *msg, ... );

View file

@ -27,6 +27,7 @@ CPrimitiveTemplate::CPrimitiveTemplate()
mFlags = mSpawnFlags = 0; mFlags = mSpawnFlags = 0;
mLife.SetRange( 1.0f, 1.0f ); mLife.SetRange( 1.0f, 1.0f );
mCullRange = 0;
mSpawnCount.SetRange( 1.0f, 1.0f ); mSpawnCount.SetRange( 1.0f, 1.0f );
mRadius.SetRange( 1.0f, 1.0f ); mRadius.SetRange( 1.0f, 1.0f );
mHeight.SetRange( 1.0f, 1.0f ); mHeight.SetRange( 1.0f, 1.0f );
@ -77,6 +78,7 @@ void CPrimitiveTemplate::operator=(const CPrimitiveTemplate &that)
mSpawnDelay = that.mSpawnDelay; mSpawnDelay = that.mSpawnDelay;
mSpawnCount = that.mSpawnCount; mSpawnCount = that.mSpawnCount;
mLife = that.mLife; mLife = that.mLife;
mCullRange = that.mCullRange;
mMediaHandles = that.mMediaHandles; mMediaHandles = that.mMediaHandles;
mImpactFxHandles = that.mImpactFxHandles; mImpactFxHandles = that.mImpactFxHandles;
@ -2197,6 +2199,11 @@ bool CPrimitiveTemplate::ParsePrimitive( CGPGroup *grp )
{ {
ParseLife( val ); ParseLife( val );
} }
else if ( !stricmp( key, "cullrange" ))
{
mCullRange = atoi( val );
mCullRange *= mCullRange; // Square
}
else if ( !stricmp( key, "delay" )) else if ( !stricmp( key, "delay" ))
{ {
ParseDelay( val ); ParseDelay( val );

View file

@ -1,5 +1,5 @@
#include "client.h" #include "client.h"
//#include "..\smartheap\smrtheap.h"
#if !defined(FX_SCHEDULER_H_INC) #if !defined(FX_SCHEDULER_H_INC)
#include "FxScheduler.h" #include "FxScheduler.h"
#endif #endif
@ -8,6 +8,10 @@
#include "../EffectsCoreInterface.h" #include "../EffectsCoreInterface.h"
#endif #endif
#include <set>
set<CCloud *> OutstandClouds;
vec3_t WHITE = {1.0f, 1.0f, 1.0f}; vec3_t WHITE = {1.0f, 1.0f, 1.0f};
struct SEffectList struct SEffectList
@ -275,8 +279,6 @@ void FX_AddPrimitive( CEffect **pEffect, CCloud *effectCloud, int killTime )
if (!effectCloud) if (!effectCloud)
{ {
SEffectList *item = FX_GetValidEffect(); SEffectList *item = FX_GetValidEffect();
#ifdef EFFECTSED #ifdef EFFECTSED
if (item == NULL) if (item == NULL)
{ {
@ -290,9 +292,24 @@ void FX_AddPrimitive( CEffect **pEffect, CCloud *effectCloud, int killTime )
} }
else else
{ {
effectCloud->AddEffect(*pEffect); /* dbgMemCheckAll();
DBGMEM_PTR_INFO dbg1;
if(dbgMemPtrInfo((void *)effectCloud,&dbg1))
{
assert(dbg1.isInUse);
}
DBGMEM_PTR_INFO dbg2;
if(dbgMemPtrInfo((void *)*pEffect,&dbg2))
{
assert(dbg2.isInUse);
}
*/
if (effectCloud&&OutstandClouds.find(effectCloud)!=OutstandClouds.end())
{
effectCloud->AddEffect(*pEffect);
}
// dbgMemCheckAll();
} }
(*pEffect)->SetKillTime(theFxHelper.mTime + killTime); (*pEffect)->SetKillTime(theFxHelper.mTime + killTime);
activeFx++; activeFx++;
@ -301,12 +318,12 @@ void FX_AddPrimitive( CEffect **pEffect, CCloud *effectCloud, int killTime )
(*pEffect)->SetTimeEnd( theFxHelper.mTime + killTime ); (*pEffect)->SetTimeEnd( theFxHelper.mTime + killTime );
} }
CCloud *FX_AddCloud(void) CCloud *FX_AddCloud(void)
{ {
CCloud *cloud; CCloud *cloud;
cloud = new CCloud; cloud = new CCloud;
OutstandClouds.insert(cloud);
FX_AddPrimitive((CEffect **)&cloud, 0, 99999); FX_AddPrimitive((CEffect **)&cloud, 0, 99999);
return cloud; return cloud;

View file

@ -14,6 +14,10 @@
#include "../qcommon/ROFFSystem.h" #include "../qcommon/ROFFSystem.h"
#endif #endif
#ifdef _DONETPROFILE_
#include "../qcommon/INetProfile.h"
#endif
/* /*
Ghoul2 Insert Start Ghoul2 Insert Start
*/ */
@ -220,6 +224,24 @@ void CL_CgameError( const char *string ) {
} }
int gCLTotalClientNum = 0;
//keep track of the total number of clients
extern cvar_t *cl_autolodscale;
//if we want to do autolodscaling
void CL_DoAutoLODScale(void)
{
float finalLODScaleFactor = 0;
if ( gCLTotalClientNum >= 8 )
{
finalLODScaleFactor = (gCLTotalClientNum/-8.0f);
}
Cvar_Set( "r_autolodscalevalue", va("%f", finalLODScaleFactor) );
}
/* /*
===================== =====================
CL_ConfigstringModified CL_ConfigstringModified
@ -274,6 +296,36 @@ void CL_ConfigstringModified( void ) {
cl.gameState.dataCount += len + 1; cl.gameState.dataCount += len + 1;
} }
if (cl_autolodscale && cl_autolodscale->integer)
{
if (index >= CS_PLAYERS &&
index < CS_CHARSKINS)
{ //this means that a client was updated in some way. Go through and count the clients.
int clientCount = 0;
i = CS_PLAYERS;
while (i < CS_CHARSKINS)
{
s = cl.gameState.stringData + cl.gameState.stringOffsets[ i ];
if (s && s[0])
{
clientCount++;
}
i++;
}
gCLTotalClientNum = clientCount;
#ifdef _DEBUG
Com_DPrintf("%i clients\n", gCLTotalClientNum);
#endif
CL_DoAutoLODScale();
}
}
if ( index == CS_SYSTEMINFO ) { if ( index == CS_SYSTEMINFO ) {
// parse serverId and other cvars // parse serverId and other cvars
CL_SystemInfoChanged(); CL_SystemInfoChanged();
@ -319,7 +371,7 @@ rescan:
cmd = Cmd_Argv(0); cmd = Cmd_Argv(0);
if ( !strcmp( cmd, "disconnect" ) ) { if ( !strcmp( cmd, "disconnect" ) ) {
Com_Error (ERR_SERVERDISCONNECT,"Server disconnected\n"); Com_Error (ERR_SERVERDISCONNECT, SP_GetStringTextString("SVINGAME_SERVER_DISCONNECTED"));//"Server disconnected\n");
} }
if ( !strcmp( cmd, "bcs0" ) ) { if ( !strcmp( cmd, "bcs0" ) ) {
@ -416,6 +468,9 @@ void CL_ShutdownCGame( void ) {
VM_Call( cgvm, CG_SHUTDOWN ); VM_Call( cgvm, CG_SHUTDOWN );
VM_Free( cgvm ); VM_Free( cgvm );
cgvm = NULL; cgvm = NULL;
#ifdef _DONETPROFILE_
ClReadProf().ShowTotals();
#endif
} }
static int FloatAsInt( float f ) { static int FloatAsInt( float f ) {
@ -435,6 +490,7 @@ The cgame module is making a system call
*/ */
#define VMA(x) VM_ArgPtr(args[x]) #define VMA(x) VM_ArgPtr(args[x])
#define VMF(x) ((float *)args)[x] #define VMF(x) ((float *)args)[x]
extern bool RicksCrazyOnServer;
int CL_CgameSystemCalls( int *args ) { int CL_CgameSystemCalls( int *args ) {
switch( args[0] ) { switch( args[0] ) {
case CG_PRINT: case CG_PRINT:
@ -814,7 +870,7 @@ int CL_CgameSystemCalls( int *args ) {
return FX_FreeSystem(); return FX_FreeSystem();
case CG_FX_ADJUST_TIME: case CG_FX_ADJUST_TIME:
FX_AdjustTime(args[1]); FX_AdjustTime_Pos(args[1],(float *)VMA(2),(vec3_t *)VMA(3));
return 0; return 0;
case CG_FX_ADDPOLY: case CG_FX_ADDPOLY:
@ -939,6 +995,7 @@ Ghoul2 Insert Start
return G2API_GetBoltMatrix(*((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9)); return G2API_GetBoltMatrix(*((CGhoul2Info_v *)args[1]), args[2], args[3], (mdxaBone_t *)VMA(4), (const float *)VMA(5),(const float *)VMA(6), args[7], (qhandle_t *)VMA(8), (float *)VMA(9));
case CG_G2_INITGHOUL2MODEL: case CG_G2_INITGHOUL2MODEL:
RicksCrazyOnServer=false;
return G2API_InitGhoul2Model((CGhoul2Info_v **)VMA(1), (const char *)VMA(2), args[3], (qhandle_t) args[4], return G2API_InitGhoul2Model((CGhoul2Info_v **)VMA(1), (const char *)VMA(2), args[3], (qhandle_t) args[4],
(qhandle_t) args[5], args[6], args[7]); (qhandle_t) args[5], args[6], args[7]);
@ -1047,8 +1104,7 @@ Ghoul2 Insert End
break; break;
case CG_SP_REGISTER: case CG_SP_REGISTER:
SP_Register((const char *)VMA(1),SP_REGISTER_CLIENT); return !!SP_Register((const char *)VMA(1),SP_REGISTER_CLIENT);
return 0;
case CG_SET_SHARED_BUFFER: case CG_SET_SHARED_BUFFER:
cl.mSharedMemory = ((char *)VMA(1)); cl.mSharedMemory = ((char *)VMA(1));
@ -1117,12 +1173,16 @@ void CL_InitCGame( void ) {
re.EndRegistration(); re.EndRegistration();
// make sure everything is paged in // make sure everything is paged in
if (!Sys_LowPhysicalMemory()) { // if (!Sys_LowPhysicalMemory())
{
Com_TouchMemory(); Com_TouchMemory();
} }
// clear anything that got printed // clear anything that got printed
Con_ClearNotify (); Con_ClearNotify ();
#ifdef _DONETPROFILE_
ClReadProf().Reset();
#endif
} }

View file

@ -144,8 +144,6 @@ static int CIN_HandleForVideo(void) {
} }
extern int CL_ScaledMilliseconds(void);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// RllSetupTable // RllSetupTable
// //
@ -594,27 +592,6 @@ static void ROQ_GenYUVTables( void )
*d++ = *b; \ *d++ = *b; \
a++; b++; } a++; b++; }
/******************************************************************************
*
* Function:
*
* Description:
*
******************************************************************************/
static unsigned short yuv_to_rgb( long y, long u, long v )
{
long r,g,b,YY = (long)(ROQ_YY_tab[(y)]);
r = (YY + ROQ_VR_tab[v]) >> 9;
g = (YY + ROQ_UG_tab[u] + ROQ_VG_tab[v]) >> 8;
b = (YY + ROQ_UB_tab[u]) >> 9;
if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0;
if (r > 31) r = 31; if (g > 63) g = 63; if (b > 31) b = 31;
return (unsigned short)((r<<11)+(g<<5)+(b));
}
/****************************************************************************** /******************************************************************************
* *
@ -990,7 +967,7 @@ redump:
case ZA_SOUND_MONO: case ZA_SOUND_MONO:
if (!cinTable[currentHandle].silent) { if (!cinTable[currentHandle].silent) {
ssize = RllDecodeMonoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags); ssize = RllDecodeMonoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags);
S_RawSamples( ssize, 22050, 2, 1, (byte *)sbuf, 1.0f ); S_RawSamples( ssize, 22050, 2, 1, (byte *)sbuf, s_volume->value );
} }
break; break;
case ZA_SOUND_STEREO: case ZA_SOUND_STEREO:
@ -1000,15 +977,14 @@ redump:
s_rawend = s_soundtime; s_rawend = s_soundtime;
} }
ssize = RllDecodeStereoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags); ssize = RllDecodeStereoToStereo( framedata, sbuf, cinTable[currentHandle].RoQFrameSize, 0, (unsigned short)cinTable[currentHandle].roq_flags);
S_RawSamples( ssize, 22050, 2, 2, (byte *)sbuf, 1.0f ); S_RawSamples( ssize, 22050, 2, 2, (byte *)sbuf, s_volume->value );
} }
break; break;
case ROQ_QUAD_INFO: case ROQ_QUAD_INFO:
if (cinTable[currentHandle].numQuads == -1) { if (cinTable[currentHandle].numQuads == -1) {
readQuadInfo( framedata ); readQuadInfo( framedata );
setupQuad( 0, 0 ); setupQuad( 0, 0 );
// we need to use CL_ScaledMilliseconds because of the smp mode calls from the renderer cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = Sys_Milliseconds()*com_timescale->value;
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = CL_ScaledMilliseconds()*com_timescale->value;
} }
if (cinTable[currentHandle].numQuads != 1) cinTable[currentHandle].numQuads = 0; if (cinTable[currentHandle].numQuads != 1) cinTable[currentHandle].numQuads = 0;
break; break;
@ -1080,8 +1056,7 @@ redump:
static void RoQ_init( void ) static void RoQ_init( void )
{ {
// we need to use CL_ScaledMilliseconds because of the smp mode calls from the renderer cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = Sys_Milliseconds()*com_timescale->value;
cinTable[currentHandle].startTime = cinTable[currentHandle].lastTime = CL_ScaledMilliseconds()*com_timescale->value;
cinTable[currentHandle].RoQPlayed = 24; cinTable[currentHandle].RoQPlayed = 24;
@ -1213,13 +1188,11 @@ e_status CIN_RunCinematic (int handle)
return cinTable[currentHandle].status; return cinTable[currentHandle].status;
} }
// we need to use CL_ScaledMilliseconds because of the smp mode calls from the renderer thisTime = Sys_Milliseconds()*com_timescale->value;
thisTime = CL_ScaledMilliseconds()*com_timescale->value;
if (cinTable[currentHandle].shader && (abs(thisTime - cinTable[currentHandle].lastTime))>100) { if (cinTable[currentHandle].shader && (abs(thisTime - cinTable[currentHandle].lastTime))>100) {
cinTable[currentHandle].startTime += thisTime - cinTable[currentHandle].lastTime; cinTable[currentHandle].startTime += thisTime - cinTable[currentHandle].lastTime;
} }
// we need to use CL_ScaledMilliseconds because of the smp mode calls from the renderer cinTable[currentHandle].tfps = ((((Sys_Milliseconds()*com_timescale->value) - cinTable[currentHandle].startTime)*cinTable[currentHandle].roqFPS)/1000);
cinTable[currentHandle].tfps = ((((CL_ScaledMilliseconds()*com_timescale->value) - cinTable[currentHandle].startTime)*3)/100);
start = cinTable[currentHandle].startTime; start = cinTable[currentHandle].startTime;
while( (cinTable[currentHandle].tfps != cinTable[currentHandle].numQuads) while( (cinTable[currentHandle].tfps != cinTable[currentHandle].numQuads)
@ -1227,9 +1200,8 @@ e_status CIN_RunCinematic (int handle)
{ {
RoQInterrupt(); RoQInterrupt();
if (start != cinTable[currentHandle].startTime) { if (start != cinTable[currentHandle].startTime) {
// we need to use CL_ScaledMilliseconds because of the smp mode calls from the renderer cinTable[currentHandle].tfps = ((((Sys_Milliseconds()*com_timescale->value)
cinTable[currentHandle].tfps = ((((CL_ScaledMilliseconds()*com_timescale->value) - cinTable[currentHandle].startTime)*cinTable[currentHandle].roqFPS)/1000);
- cinTable[currentHandle].startTime)*3)/100);
start = cinTable[currentHandle].startTime; start = cinTable[currentHandle].startTime;
} }
} }
@ -1288,7 +1260,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue); cinTable[currentHandle].ROQSize = FS_FOpenFileRead (cinTable[currentHandle].fileName, &cinTable[currentHandle].iFile, qtrue);
if (cinTable[currentHandle].ROQSize<=0) { if (cinTable[currentHandle].ROQSize<=0) {
Com_Printf("cinematic failed to open %s\n", arg); Com_DPrintf("cinematic failed to open %s\n", arg);
cinTable[currentHandle].fileName[0] = 0; cinTable[currentHandle].fileName[0] = 0;
return -1; return -1;
} }

View file

@ -3,13 +3,11 @@
#include "client.h" #include "client.h"
#include "..\strings\con_text.h" #include "..\strings\con_text.h"
#include "..\qcommon\strip.h" #include "..\qcommon\strip.h"
#include "../qcommon/game_version.h"
int g_console_field_width = 78; int g_console_field_width = 78;
extern console_t con;
console_t con; console_t con;
cvar_t *con_conspeed; cvar_t *con_conspeed;
@ -44,7 +42,7 @@ void Con_ToggleConsole_f (void) {
Con_MessageMode_f Con_MessageMode_f
================ ================
*/ */
void Con_MessageMode_f (void) { void Con_MessageMode_f (void) { //yell
chat_playerNum = -1; chat_playerNum = -1;
chat_team = qfalse; chat_team = qfalse;
Field_Clear( &chatField ); Field_Clear( &chatField );
@ -58,7 +56,7 @@ void Con_MessageMode_f (void) {
Con_MessageMode2_f Con_MessageMode2_f
================ ================
*/ */
void Con_MessageMode2_f (void) { void Con_MessageMode2_f (void) { //team chat
chat_playerNum = -1; chat_playerNum = -1;
chat_team = qtrue; chat_team = qtrue;
Field_Clear( &chatField ); Field_Clear( &chatField );
@ -71,7 +69,7 @@ void Con_MessageMode2_f (void) {
Con_MessageMode3_f Con_MessageMode3_f
================ ================
*/ */
void Con_MessageMode3_f (void) { void Con_MessageMode3_f (void) { //target chat
chat_playerNum = VM_Call( cgvm, CG_CROSSHAIR_PLAYER ); chat_playerNum = VM_Call( cgvm, CG_CROSSHAIR_PLAYER );
if ( chat_playerNum < 0 || chat_playerNum >= MAX_CLIENTS ) { if ( chat_playerNum < 0 || chat_playerNum >= MAX_CLIENTS ) {
chat_playerNum = -1; chat_playerNum = -1;
@ -88,7 +86,7 @@ void Con_MessageMode3_f (void) {
Con_MessageMode4_f Con_MessageMode4_f
================ ================
*/ */
void Con_MessageMode4_f (void) { void Con_MessageMode4_f (void) { //attacker
chat_playerNum = VM_Call( cgvm, CG_LAST_ATTACKER ); chat_playerNum = VM_Call( cgvm, CG_LAST_ATTACKER );
if ( chat_playerNum < 0 || chat_playerNum >= MAX_CLIENTS ) { if ( chat_playerNum < 0 || chat_playerNum >= MAX_CLIENTS ) {
chat_playerNum = -1; chat_playerNum = -1;
@ -132,7 +130,7 @@ void Con_Dump_f (void)
if (Cmd_Argc() != 2) if (Cmd_Argc() != 2)
{ {
Com_Printf(SP_GetStringText(CON_TEXT_DUMP_USAGE)); Com_Printf (SP_GetStringText(CON_TEXT_DUMP_USAGE));
return; return;
} }
@ -141,7 +139,7 @@ void Con_Dump_f (void)
f = FS_FOpenFileWrite( Cmd_Argv( 1 ) ); f = FS_FOpenFileWrite( Cmd_Argv( 1 ) );
if (!f) if (!f)
{ {
Com_Printf ("ERROR: couldn't open.\n"); Com_Printf (S_COLOR_RED"ERROR: couldn't open.\n");
return; return;
} }
@ -205,22 +203,31 @@ void Con_CheckResize (void)
int i, j, width, oldwidth, oldtotallines, numlines, numchars; int i, j, width, oldwidth, oldtotallines, numlines, numchars;
MAC_STATIC short tbuf[CON_TEXTSIZE]; MAC_STATIC short tbuf[CON_TEXTSIZE];
width = (SCREEN_WIDTH / SMALLCHAR_WIDTH) - 2; // width = (SCREEN_WIDTH / SMALLCHAR_WIDTH) - 2;
width = (cls.glconfig.vidWidth / SMALLCHAR_WIDTH) - 2;
if (width == con.linewidth) if (width == con.linewidth)
return; return;
if (width < 1) // video hasn't been initialized yet if (width < 1) // video hasn't been initialized yet
{ {
con.xadjust = 1;
con.yadjust = 1;
width = DEFAULT_CONSOLE_WIDTH; width = DEFAULT_CONSOLE_WIDTH;
con.linewidth = width; con.linewidth = width;
con.totallines = CON_TEXTSIZE / con.linewidth; con.totallines = CON_TEXTSIZE / con.linewidth;
for(i=0; i<CON_TEXTSIZE; i++) for(i=0; i<CON_TEXTSIZE; i++)
{
con.text[i] = (ColorIndex(COLOR_WHITE)<<8) | ' '; con.text[i] = (ColorIndex(COLOR_WHITE)<<8) | ' ';
}
} }
else else
{ {
// on wide screens, we will center the text
con.xadjust = 640.0f / cls.glconfig.vidWidth;
con.yadjust = 480.0f / cls.glconfig.vidHeight;
oldwidth = con.linewidth; oldwidth = con.linewidth;
con.linewidth = width; con.linewidth = width;
oldtotallines = con.totallines; oldtotallines = con.totallines;
@ -338,19 +345,6 @@ void CL_ConsolePrint( char *txt ) {
con.linewidth = -1; con.linewidth = -1;
Con_CheckResize (); Con_CheckResize ();
con.initialized = qtrue; con.initialized = qtrue;
con.xadjust = 0;
con.yadjust = 0;
}
if (!con.xadjust && !con.yadjust &&
cls.glconfig.vidWidth && cls.glconfig.vidHeight)
{
//Our adjust values are still 0 and we now have proper glconfig height/width values (we don't on init always),
//so fill the values in.
con.xadjust = 640.0f / cls.glconfig.vidWidth;
con.yadjust = 480.0f / cls.glconfig.vidHeight;
} }
color = ColorIndex(COLOR_WHITE); color = ColorIndex(COLOR_WHITE);
@ -546,10 +540,6 @@ void Con_DrawSolidConsole( float frac ) {
if (lines > cls.glconfig.vidHeight ) if (lines > cls.glconfig.vidHeight )
lines = cls.glconfig.vidHeight; lines = cls.glconfig.vidHeight;
// on wide screens, we will center the text
con.xadjust = 640.0f / cls.glconfig.vidWidth;
con.yadjust = 480.0f / cls.glconfig.vidHeight;
// draw the background // draw the background
y = (int) (frac * SCREEN_HEIGHT - 2); y = (int) (frac * SCREEN_HEIGHT - 2);
if ( y < 1 ) { if ( y < 1 ) {

View file

@ -418,7 +418,7 @@ void CL_KeyMove( usercmd_t *cmd ) {
cmd->buttons &= ~BUTTON_WALKING; cmd->buttons &= ~BUTTON_WALKING;
} else { } else {
cmd->buttons |= BUTTON_WALKING; cmd->buttons |= BUTTON_WALKING;
movespeed = 32; movespeed = 46;
} }
forward = 0; forward = 0;

View file

@ -1,5 +1,5 @@
#include "client.h" #include "client.h"
#include "../qcommon/strip.h"
/* /*
key up events are sent even if in console mode key up events are sent even if in console mode
@ -158,6 +158,381 @@ keyname_t keynames[] =
{NULL,0} {NULL,0}
}; };
//english printed keynames, for when we want what's printed to be different
//from the "technical" bind label
keyname_t keynames_e[] =
{
{"TAB", K_TAB},
{"ENTER", K_ENTER},
{"ESCAPE", K_ESCAPE},
{"SPACE", K_SPACE},
{"BACKSPACE", K_BACKSPACE},
{"UP", K_UPARROW},
{"DOWN", K_DOWNARROW},
{"LEFT", K_LEFTARROW},
{"RIGHT", K_RIGHTARROW},
{"ALT", K_ALT},
{"CTRL", K_CTRL},
{"SHIFT", K_SHIFT},
{"COMMAND", K_COMMAND},
{"CAPSLOCK", K_CAPSLOCK},
{"F1", K_F1},
{"F2", K_F2},
{"F3", K_F3},
{"F4", K_F4},
{"F5", K_F5},
{"F6", K_F6},
{"F7", K_F7},
{"F8", K_F8},
{"F9", K_F9},
{"F10", K_F10},
{"F11", K_F11},
{"F12", K_F12},
{"INS", K_INS},
{"DEL", K_DEL},
{"PGDN", K_PGDN},
{"PGUP", K_PGUP},
{"HOME", K_HOME},
{"END", K_END},
{"MOUSE1", K_MOUSE1},
{"MOUSE2", K_MOUSE2},
{"MOUSE3", K_MOUSE3},
{"MOUSE4", K_MOUSE4},
{"MOUSE5", K_MOUSE5},
{"MWHEELUP", K_MWHEELUP },
{"MWHEELDOWN", K_MWHEELDOWN },
{"JOY1", K_JOY1},
{"JOY2", K_JOY2},
{"JOY3", K_JOY3},
{"JOY4", K_JOY4},
{"JOY5", K_JOY5},
{"JOY6", K_JOY6},
{"JOY7", K_JOY7},
{"JOY8", K_JOY8},
{"JOY9", K_JOY9},
{"JOY10", K_JOY10},
{"JOY11", K_JOY11},
{"JOY12", K_JOY12},
{"JOY13", K_JOY13},
{"JOY14", K_JOY14},
{"JOY15", K_JOY15},
{"JOY16", K_JOY16},
{"JOY17", K_JOY17},
{"JOY18", K_JOY18},
{"JOY19", K_JOY19},
{"JOY20", K_JOY20},
{"JOY21", K_JOY21},
{"JOY22", K_JOY22},
{"JOY23", K_JOY23},
{"JOY24", K_JOY24},
{"JOY25", K_JOY25},
{"JOY26", K_JOY26},
{"JOY27", K_JOY27},
{"JOY28", K_JOY28},
{"JOY29", K_JOY29},
{"JOY30", K_JOY30},
{"JOY31", K_JOY31},
{"JOY32", K_JOY32},
{"AUX1", K_AUX1},
{"AUX2", K_AUX2},
{"AUX3", K_AUX3},
{"AUX4", K_AUX4},
{"AUX5", K_AUX5},
{"AUX6", K_AUX6},
{"AUX7", K_AUX7},
{"AUX8", K_AUX8},
{"AUX9", K_AUX9},
{"AUX10", K_AUX10},
{"AUX11", K_AUX11},
{"AUX12", K_AUX12},
{"AUX13", K_AUX13},
{"AUX14", K_AUX14},
{"AUX15", K_AUX15},
{"AUX16", K_AUX16},
{"KP_HOME", K_KP_HOME },
{"KP_UP", K_KP_UPARROW },
{"KP_PGUP", K_KP_PGUP },
{"KP_LEFT", K_KP_LEFTARROW },
{"KP_5", K_KP_5 },
{"KP_RIGHT", K_KP_RIGHTARROW },
{"KP_END", K_KP_END },
{"KP_DOWN", K_KP_DOWNARROW },
{"KP_PGDN", K_KP_PGDN },
{"KP_ENTER", K_KP_ENTER },
{"KP_INS", K_KP_INS },
{"KP_DEL", K_KP_DEL },
{"KP_SLASH", K_KP_SLASH },
{"KP_MINUS", K_KP_MINUS },
{"KP_PLUS", K_KP_PLUS },
{"KP_NUMLOCK", K_KP_NUMLOCK },
{"KP_STAR", K_KP_STAR },
{"KP_EQUALS", K_KP_EQUALS },
{"PAUSE", K_PAUSE},
{"SEMICOLON", ';'}, // because a raw semicolon seperates commands
{NULL,0}
};
keyname_t keynames_d[] = //deutsch
{
{"TAB", K_TAB},
{"EINGABETASTE", K_ENTER},
{"ESC", K_ESCAPE},
{"LEERTASTE", K_SPACE},
{"RÜCKTASTE", K_BACKSPACE},
{"PFEILT.AUF", K_UPARROW},
{"PFEILT.UNTEN", K_DOWNARROW},
{"PFEILT.LINKS", K_LEFTARROW},
{"PFEILT.RECHTS", K_RIGHTARROW},
{"ALT", K_ALT},
{"STRG", K_CTRL},
{"UMSCHALT", K_SHIFT},
{"FESTSTELLT", K_CAPSLOCK},
{"F1", K_F1},
{"F2", K_F2},
{"F3", K_F3},
{"F4", K_F4},
{"F5", K_F5},
{"F6", K_F6},
{"F7", K_F7},
{"F8", K_F8},
{"F9", K_F9},
{"F10", K_F10},
{"F11", K_F11},
{"F12", K_F12},
{"EINFG", K_INS},
{"ENTF", K_DEL},
{"BILD-AB", K_PGDN},
{"BILD-AUF", K_PGUP},
{"POS1", K_HOME},
{"ENDE", K_END},
{"MAUS1", K_MOUSE1},
{"MAUS2", K_MOUSE2},
{"MAUS3", K_MOUSE3},
{"MAUS4", K_MOUSE4},
{"MAUS5", K_MOUSE5},
{"MRADOBEN", K_MWHEELUP },
{"MRADUNTEN", K_MWHEELDOWN },
{"JOY1", K_JOY1},
{"JOY2", K_JOY2},
{"JOY3", K_JOY3},
{"JOY4", K_JOY4},
{"JOY5", K_JOY5},
{"JOY6", K_JOY6},
{"JOY7", K_JOY7},
{"JOY8", K_JOY8},
{"JOY9", K_JOY9},
{"JOY10", K_JOY10},
{"JOY11", K_JOY11},
{"JOY12", K_JOY12},
{"JOY13", K_JOY13},
{"JOY14", K_JOY14},
{"JOY15", K_JOY15},
{"JOY16", K_JOY16},
{"JOY17", K_JOY17},
{"JOY18", K_JOY18},
{"JOY19", K_JOY19},
{"JOY20", K_JOY20},
{"JOY21", K_JOY21},
{"JOY22", K_JOY22},
{"JOY23", K_JOY23},
{"JOY24", K_JOY24},
{"JOY25", K_JOY25},
{"JOY26", K_JOY26},
{"JOY27", K_JOY27},
{"JOY28", K_JOY28},
{"JOY29", K_JOY29},
{"JOY30", K_JOY30},
{"JOY31", K_JOY31},
{"JOY32", K_JOY32},
{"AUX1", K_AUX1},
{"AUX2", K_AUX2},
{"AUX3", K_AUX3},
{"AUX4", K_AUX4},
{"AUX5", K_AUX5},
{"AUX6", K_AUX6},
{"AUX7", K_AUX7},
{"AUX8", K_AUX8},
{"AUX9", K_AUX9},
{"AUX10", K_AUX10},
{"AUX11", K_AUX11},
{"AUX12", K_AUX12},
{"AUX13", K_AUX13},
{"AUX14", K_AUX14},
{"AUX15", K_AUX15},
{"AUX16", K_AUX16},
{"ZB_POS1", K_KP_HOME },
{"ZB_PFEILT.AUF", K_KP_UPARROW },
{"ZB_BILD-AUF", K_KP_PGUP },
{"ZB_PFEILT.LINKS", K_KP_LEFTARROW },
{"ZB_5", K_KP_5 },
{"ZB_PFEILT.RECHTS",K_KP_RIGHTARROW },
{"ZB_ENDE", K_KP_END },
{"ZB_PFEILT.UNTEN", K_KP_DOWNARROW },
{"ZB_BILD-AB", K_KP_PGDN },
{"ZB_ENTER", K_KP_ENTER },
{"ZB_EINFG", K_KP_INS },
{"ZB_ENTF", K_KP_DEL },
{"ZB_SLASH", K_KP_SLASH },
{"ZB_MINUS", K_KP_MINUS },
{"ZB_PLUS", K_KP_PLUS },
{"ZB_NUM", K_KP_NUMLOCK },
{"ZB_*", K_KP_STAR },
{"ZB_EQUALS", K_KP_EQUALS },
{"PAUSE", K_PAUSE},
{"COMMAND", K_COMMAND}, //mac
{NULL,0}
}; //end german
keyname_t keynames_f[] = //french
{
{"TAB", K_TAB},
{"ENTREE", K_ENTER},
{"ECHAP", K_ESCAPE},
{"ESPACE", K_SPACE},
{"RETOUR", K_BACKSPACE},
{"HAUT", K_UPARROW},
{"BAS", K_DOWNARROW},
{"GAUCHE", K_LEFTARROW},
{"DROITE", K_RIGHTARROW},
{"ALT", K_ALT},
{"CTRL", K_CTRL},
{"MAJ", K_SHIFT},
{"VERRMAJ", K_CAPSLOCK},
{"F1", K_F1},
{"F2", K_F2},
{"F3", K_F3},
{"F4", K_F4},
{"F5", K_F5},
{"F6", K_F6},
{"F7", K_F7},
{"F8", K_F8},
{"F9", K_F9},
{"F10", K_F10},
{"F11", K_F11},
{"F12", K_F12},
{"INSER", K_INS},
{"SUPPR", K_DEL},
{"PGBAS", K_PGDN},
{"PGHAUT", K_PGUP},
{"ORIGINE", K_HOME},
{"FIN", K_END},
{"SOURIS1", K_MOUSE1},
{"SOURIS2", K_MOUSE2},
{"SOURIS3", K_MOUSE3},
{"SOURIS4", K_MOUSE4},
{"SOURIS5", K_MOUSE5},
{"MOLETTEHT.", K_MWHEELUP },
{"MOLETTEBAS", K_MWHEELDOWN },
{"JOY1", K_JOY1},
{"JOY2", K_JOY2},
{"JOY3", K_JOY3},
{"JOY4", K_JOY4},
{"JOY5", K_JOY5},
{"JOY6", K_JOY6},
{"JOY7", K_JOY7},
{"JOY8", K_JOY8},
{"JOY9", K_JOY9},
{"JOY10", K_JOY10},
{"JOY11", K_JOY11},
{"JOY12", K_JOY12},
{"JOY13", K_JOY13},
{"JOY14", K_JOY14},
{"JOY15", K_JOY15},
{"JOY16", K_JOY16},
{"JOY17", K_JOY17},
{"JOY18", K_JOY18},
{"JOY19", K_JOY19},
{"JOY20", K_JOY20},
{"JOY21", K_JOY21},
{"JOY22", K_JOY22},
{"JOY23", K_JOY23},
{"JOY24", K_JOY24},
{"JOY25", K_JOY25},
{"JOY26", K_JOY26},
{"JOY27", K_JOY27},
{"JOY28", K_JOY28},
{"JOY29", K_JOY29},
{"JOY30", K_JOY30},
{"JOY31", K_JOY31},
{"JOY32", K_JOY32},
{"AUX1", K_AUX1},
{"AUX2", K_AUX2},
{"AUX3", K_AUX3},
{"AUX4", K_AUX4},
{"AUX5", K_AUX5},
{"AUX6", K_AUX6},
{"AUX7", K_AUX7},
{"AUX8", K_AUX8},
{"AUX9", K_AUX9},
{"AUX10", K_AUX10},
{"AUX11", K_AUX11},
{"AUX12", K_AUX12},
{"AUX13", K_AUX13},
{"AUX14", K_AUX14},
{"AUX15", K_AUX15},
{"AUX16", K_AUX16},
{"PN_ORIGINE", K_KP_HOME },
{"PN_HAUT", K_KP_UPARROW },
{"PN_PGBAS", K_KP_PGUP },
{"PN_GAUCHE", K_KP_LEFTARROW },
{"PN_5", K_KP_5 },
{"PN_DROITE", K_KP_RIGHTARROW },
{"PN_FIN", K_KP_END },
{"PN_BAS", K_KP_DOWNARROW },
{"PN_PGBAS", K_KP_PGDN },
{"PN_ENTR", K_KP_ENTER },
{"PN_INSER", K_KP_INS },
{"PN_SUPPR", K_KP_DEL },
{"PN_SLASH", K_KP_SLASH },
{"PN_MOINS", K_KP_MINUS },
{"PN_PLUS", K_KP_PLUS },
{"PN_VERRNUM", K_KP_NUMLOCK },
{"PN_*", K_KP_STAR },
{"PN_EQUALS", K_KP_EQUALS },
{"PAUSE", K_PAUSE},
{"COMMAND", K_COMMAND}, //mac
{"POINT-VIRGULE", ';' }, // because a raw semicolon seperates commands
{NULL,0}
}; //end french
/* /*
============================================================================= =============================================================================
@ -855,7 +1230,9 @@ Returns a string (either a single ascii char, a K_* name, or a 0x11 hex string)
given keynum. given keynum.
=================== ===================
*/ */
char *Key_KeynumToString( int keynum ) { extern cvar_t *sp_language;
char *Key_KeynumToString( int keynum, qboolean bTranslate ) //note: translate is only called for menu display not configs
{
keyname_t *kn; keyname_t *kn;
static char tinystr[5]; static char tinystr[5];
int i, j; int i, j;
@ -875,8 +1252,21 @@ char *Key_KeynumToString( int keynum ) {
return tinystr; return tinystr;
} }
kn=keynames; //init to english
if (bTranslate) {
if ( sp_language->integer == SP_LANGUAGE_GERMAN ) {
kn=keynames_d; //use german
} else if ( sp_language->integer == SP_LANGUAGE_FRENCH ) {
kn=keynames_f; //use french
}
else //rww - this is actually English and doesn't need to be "translated".
{ //however, certain key names are too long to display right, this does the trick.
kn=keynames_e;
}
}
// check for a key string // check for a key string
for ( kn=keynames ; kn->name ; kn++ ) { for ( ; kn->name ; kn++ ) {
if (keynum == kn->keynum) { if (keynum == kn->keynum) {
return kn->name; return kn->name;
} }
@ -1051,7 +1441,7 @@ void Key_WriteBindings( fileHandle_t f ) {
for (i=0 ; i<256 ; i++) { for (i=0 ; i<256 ; i++) {
if (keys[i].binding && keys[i].binding[0] ) { if (keys[i].binding && keys[i].binding[0] ) {
FS_Printf (f, "bind %s \"%s\"\n", Key_KeynumToString(i), keys[i].binding); FS_Printf (f, "bind %s \"%s\"\n", Key_KeynumToString(i, qfalse), keys[i].binding);
} }
@ -1070,7 +1460,7 @@ void Key_Bindlist_f( void ) {
for ( i = 0 ; i < 256 ; i++ ) { for ( i = 0 ; i < 256 ; i++ ) {
if ( keys[i].binding && keys[i].binding[0] ) { if ( keys[i].binding && keys[i].binding[0] ) {
Com_Printf( "%s \"%s\"\n", Key_KeynumToString(i), keys[i].binding ); Com_Printf( "%s \"%s\"\n", Key_KeynumToString(i, qfalse), keys[i].binding );
} }
} }
} }
@ -1259,7 +1649,7 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
if ( !kb ) { if ( !kb ) {
if (key >= 200) { if (key >= 200) {
Com_Printf ("%s is unbound, use controls menu to set.\n" Com_Printf ("%s is unbound, use controls menu to set.\n"
, Key_KeynumToString( key ) ); , Key_KeynumToString( key, qfalse ) );
} }
} else if (kb[0] == '+') { } else if (kb[0] == '+') {
int i; int i;

View file

@ -9,6 +9,10 @@
#include "..\ghoul2\G2_local.h" #include "..\ghoul2\G2_local.h"
#endif #endif
#ifdef _DONETPROFILE_
#include "../qcommon/INetProfile.h"
#endif
cvar_t *cl_nodelta; cvar_t *cl_nodelta;
cvar_t *cl_debugMove; cvar_t *cl_debugMove;
@ -55,6 +59,8 @@ cvar_t *cl_serverStatusResendTime;
cvar_t *cl_trn; cvar_t *cl_trn;
cvar_t *cl_framerate; cvar_t *cl_framerate;
cvar_t *cl_autolodscale;
vec3_t cl_windVec; vec3_t cl_windVec;
#ifdef USE_CD_KEY #ifdef USE_CD_KEY
@ -508,7 +514,13 @@ void CL_PlayDemo_f( void ) {
if (!clc.demofile) { if (!clc.demofile) {
if (!Q_stricmp(arg, "(null)")) if (!Q_stricmp(arg, "(null)"))
{ {
Com_Error( ERR_DROP, "No demo selected.", name); extern cvar_t *sp_language;
switch (sp_language->integer)
{
case SP_LANGUAGE_GERMAN: Com_Error( ERR_DROP, "Kein demo ausgewählt." ); break;
case SP_LANGUAGE_FRENCH: Com_Error( ERR_DROP, "Aucun demo choisi." ); break;
default: Com_Error( ERR_DROP, "No demo selected." ); break;
}
} }
else else
{ {
@ -579,11 +591,8 @@ void CL_NextDemo( void ) {
CL_ShutdownAll CL_ShutdownAll
===================== =====================
*/ */
extern void CM_ShutdownShaderProperties(void);
void CL_ShutdownAll(void) { void CL_ShutdownAll(void) {
CM_ShutdownShaderProperties();
// clear sounds // clear sounds
S_DisableSounds(); S_DisableSounds();
// shutdown CGame // shutdown CGame
@ -611,6 +620,8 @@ ways a client gets into a game
Also called by Com_Error Also called by Com_Error
================= =================
*/ */
extern void FixGhoul2InfoLeaks(bool,bool);
void CL_FlushMemory( void ) { void CL_FlushMemory( void ) {
// shutdown all the client stuff // shutdown all the client stuff
@ -618,10 +629,11 @@ void CL_FlushMemory( void ) {
// if not running a server clear the whole hunk // if not running a server clear the whole hunk
if ( !com_sv_running->integer ) { if ( !com_sv_running->integer ) {
// clear collision map data
FixGhoul2InfoLeaks(true,false);
CM_ClearMap();
// clear the whole hunk // clear the whole hunk
Hunk_Clear(); Hunk_Clear();
// clear collision map data
CM_ClearMap();
} }
else { else {
// clear all the client data on the hunk // clear all the client data on the hunk
@ -645,6 +657,9 @@ void CL_MapLoading( void ) {
return; return;
} }
// Set this to localhost.
Cvar_Set( "cl_currentServerAddress", "Localhost");
Con_Close(); Con_Close();
cls.keyCatchers = 0; cls.keyCatchers = 0;
@ -743,9 +758,6 @@ void CL_Disconnect( qboolean showMainMenu ) {
cls.state = CA_DISCONNECTED; cls.state = CA_DISCONNECTED;
// allow cheats locally
Cvar_Set( "sv_cheats", "1" );
// not connected to a pure server anymore // not connected to a pure server anymore
cl_connectedToPureServer = qfalse; cl_connectedToPureServer = qfalse;
} }
@ -806,12 +818,25 @@ void CL_RequestMotd( void ) {
BigShort( cls.updateServer.port ) ); BigShort( cls.updateServer.port ) );
info[0] = 0; info[0] = 0;
Com_sprintf( cls.updateChallenge, sizeof( cls.updateChallenge ), "%i", rand() ); // NOTE TTimo xoring against Com_Milliseconds, otherwise we may not have a true randomization
// only srand I could catch before here is tr_noise.c l:26 srand(1001)
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=382
// NOTE: the Com_Milliseconds xoring only affects the lower 16-bit word,
// but I decided it was enough randomization
Com_sprintf( cls.updateChallenge, sizeof( cls.updateChallenge ), "%i", ((rand() << 16) ^ rand()) ^ Com_Milliseconds());
Info_SetValueForKey( info, "challenge", cls.updateChallenge ); Info_SetValueForKey( info, "challenge", cls.updateChallenge );
Info_SetValueForKey( info, "renderer", cls.glconfig.renderer_string ); Info_SetValueForKey( info, "renderer", cls.glconfig.renderer_string );
Info_SetValueForKey( info, "version", com_version->string ); Info_SetValueForKey( info, "version", com_version->string );
Info_SetValueForKey( info, "cputype", Cvar_VariableString("sys_cpustring") );
Info_SetValueForKey( info, "mhz", Cvar_VariableString("sys_cpuspeed") );
Info_SetValueForKey( info, "memory", Cvar_VariableString("sys_memory") );
Info_SetValueForKey( info, "joystick", Cvar_VariableString("in_joystick") );
Info_SetValueForKey( info, "colorbits", va("%d",cls.glconfig.colorBits) );
NET_OutOfBandPrint( NS_CLIENT, cls.updateServer, "getmotd \"%s\"\n", info ); NET_OutOfBandPrint( NS_CLIENT, cls.updateServer, "getmotd \"%s\"\n", info );
} }
@ -1003,6 +1028,11 @@ CL_Connect_f
void CL_Connect_f( void ) { void CL_Connect_f( void ) {
char *server; char *server;
if ( !Cvar_VariableValue("fs_restrict") && !Sys_CheckCD() )
{
Com_Error( ERR_NEED_CD, SP_GetStringTextString("CON_TEXT_NEED_CD") ); //"Game CD not in drive" );
}
if ( Cmd_Argc() != 2 ) { if ( Cmd_Argc() != 2 ) {
Com_Printf( "usage: connect [server]\n"); Com_Printf( "usage: connect [server]\n");
return; return;
@ -1166,7 +1196,6 @@ void CL_Vid_Restart_f( void ) {
// don't let them loop during the restart // don't let them loop during the restart
S_StopAllSounds(); S_StopAllSounds();
S_BeginRegistration(); // CHC did this
// shutdown the UI // shutdown the UI
CL_ShutdownUI(); CL_ShutdownUI();
// shutdown the CGame // shutdown the CGame
@ -1190,6 +1219,7 @@ void CL_Vid_Restart_f( void ) {
// if not running a server clear the whole hunk // if not running a server clear the whole hunk
if ( !com_sv_running->integer ) { if ( !com_sv_running->integer ) {
CM_ClearMap();
// clear the whole hunk // clear the whole hunk
Hunk_Clear(); Hunk_Clear();
} }
@ -1440,19 +1470,34 @@ and determine if we need to download them
================= =================
*/ */
void CL_InitDownloads(void) { void CL_InitDownloads(void) {
char missingfiles[1024];
if ( cl_allowDownload->integer &&
FS_ComparePaks( clc.downloadList, sizeof( clc.downloadList ) ) ) { if ( !cl_allowDownload->integer )
{
// autodownload is disabled on the client
// but it's possible that some referenced files on the server are missing
if (FS_ComparePaks( missingfiles, sizeof( missingfiles ), qfalse ) )
{
// NOTE TTimo I would rather have that printed as a modal message box
// but at this point while joining the game we don't know wether we will successfully join or not
Com_Printf( "\nWARNING: You are missing some files referenced by the server:\n%s"
"You might not be able to join the game\n"
"Go to the setting menu to turn on autodownload, or get the file elsewhere\n\n", missingfiles );
}
}
else if ( FS_ComparePaks( clc.downloadList, sizeof( clc.downloadList ) , qtrue ) ) {
Com_Printf("Need paks: %s\n", clc.downloadList );
if ( *clc.downloadList ) { if ( *clc.downloadList ) {
// if autodownloading is not enabled on the server // if autodownloading is not enabled on the server
cls.state = CA_CONNECTED; cls.state = CA_CONNECTED;
CL_NextDownload(); CL_NextDownload();
return; return;
} }
}
}
CL_DownloadsComplete(); CL_DownloadsComplete();
} }
@ -1464,7 +1509,7 @@ Resend a connect message if the last one has timed out
================= =================
*/ */
void CL_CheckForResend( void ) { void CL_CheckForResend( void ) {
int port, i; int port;
char info[MAX_INFO_STRING]; char info[MAX_INFO_STRING];
char data[MAX_INFO_STRING]; char data[MAX_INFO_STRING];
@ -1505,15 +1550,9 @@ void CL_CheckForResend( void ) {
Info_SetValueForKey( info, "protocol", va("%i", PROTOCOL_VERSION ) ); Info_SetValueForKey( info, "protocol", va("%i", PROTOCOL_VERSION ) );
Info_SetValueForKey( info, "qport", va("%i", port ) ); Info_SetValueForKey( info, "qport", va("%i", port ) );
Info_SetValueForKey( info, "challenge", va("%i", clc.challenge ) ); Info_SetValueForKey( info, "challenge", va("%i", clc.challenge ) );
sprintf(data, "connect \"%s\"", info );
strcpy(data, "connect "); NET_OutOfBandData( NS_CLIENT, clc.serverAddress, (unsigned char *)data, strlen(data) );
for(i=0;i<(int)strlen(info);i++) {
data[8+i] = info[i]; // + (clc.challenge)&0x3;
}
data[8+i] = 0;
NET_OutOfBandData( NS_CLIENT, clc.serverAddress, (unsigned char *)data, i+8 );
// the most current userinfo has been sent, so watch for any // the most current userinfo has been sent, so watch for any
// newer changes to userinfo variables // newer changes to userinfo variables
cvar_modifiedFlags &= ~CVAR_USERINFO; cvar_modifiedFlags &= ~CVAR_USERINFO;
@ -1732,6 +1771,79 @@ void CL_ServersResponsePacket( netadr_t from, msg_t *msg ) {
Com_Printf("%d servers parsed (total %d)\n", numservers, total); Com_Printf("%d servers parsed (total %d)\n", numservers, total);
} }
#ifndef MAX_STRIPED_SV_STRING
#define MAX_STRIPED_SV_STRING 1024
#endif
static void CL_CheckSVStripEdRef(char *buf, const char *str)
{ //I don't really like doing this. But it utilizes the system that was already in place.
int i = 0;
int b = 0;
int strLen = 0;
qboolean gotStrip = qfalse;
if (!str || !str[0])
{
if (str)
{
strcpy(buf, str);
}
return;
}
strcpy(buf, str);
strLen = strlen(str);
if (strLen >= MAX_STRIPED_SV_STRING)
{
return;
}
while (i < strLen && str[i])
{
gotStrip = qfalse;
if (str[i] == '@' && (i+1) < strLen)
{
if (str[i+1] == '@' && (i+2) < strLen)
{
if (str[i+2] == '@' && (i+3) < strLen)
{ //@@@ should mean to insert a striped reference here, so insert it into buf at the current place
char stripRef[MAX_STRIPED_SV_STRING];
int r = 0;
while (i < strLen && str[i] == '@')
{
i++;
}
while (i < strLen && str[i] && str[i] != ' ' && str[i] != ':' && str[i] != '.' && str[i] != '\n')
{
stripRef[r] = str[i];
r++;
i++;
}
stripRef[r] = 0;
buf[b] = 0;
Q_strcat(buf, MAX_STRIPED_SV_STRING, SP_GetStringTextString(va("SVINGAME_%s", stripRef)));
b = strlen(buf);
}
}
}
if (!gotStrip)
{
buf[b] = str[i];
b++;
}
i++;
}
buf[b] = 0;
}
/* /*
================= =================
CL_ConnectionlessPacket CL_ConnectionlessPacket
@ -1768,7 +1880,7 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
// take this address as the new server address. This allows // take this address as the new server address. This allows
// a server proxy to hand off connections to multiple servers // a server proxy to hand off connections to multiple servers
clc.serverAddress = from; clc.serverAddress = from;
Com_DPrintf ("challenge: %d\n", clc.challenge); Com_DPrintf ("challengeResponse: %d\n", clc.challenge);
} }
return; return;
} }
@ -1833,15 +1945,20 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
} }
// echo request from server // echo request from server
if ( !Q_stricmp(c, "print") ) { if ( !Q_stricmp(c, "print") )
{
char sTemp[MAX_STRIPED_SV_STRING];
s = MSG_ReadString( msg ); s = MSG_ReadString( msg );
Q_strncpyz( clc.serverMessage, s, sizeof( clc.serverMessage ) ); CL_CheckSVStripEdRef(sTemp, s);
Com_Printf( "%s", s ); Q_strncpyz( clc.serverMessage, sTemp, sizeof( clc.serverMessage ) );
Com_Printf( "%s", sTemp );
return; return;
} }
// echo request from server // echo request from server
if ( !Q_stricmp(c, "getserversResponse\\") ) { // if ( !Q_stricmp(c, "getserversResponse\\") ) {
if ( !Q_strncmp(c, "getserversResponse", 18) ) {
CL_ServersResponsePacket( from, msg ); CL_ServersResponsePacket( from, msg );
return; return;
} }
@ -1924,8 +2041,9 @@ void CL_CheckTimeout( void ) {
&& cls.state >= CA_CONNECTED && cls.state != CA_CINEMATIC && cls.state >= CA_CONNECTED && cls.state != CA_CINEMATIC
&& cls.realtime - clc.lastPacketTime > cl_timeout->value*1000) { && cls.realtime - clc.lastPacketTime > cl_timeout->value*1000) {
if (++cl.timeoutcount > 5) { // timeoutcount saves debugger if (++cl.timeoutcount > 5) { // timeoutcount saves debugger
Com_Printf ("\nServer connection timed out.\n"); const char *psTimedOut = SP_GetStringTextString("SVINGAME_SERVER_CONNECTION_TIMED_OUT");
Com_Error(ERR_DROP, "Server connection timed out."); Com_Printf ("\n%s\n",psTimedOut);
Com_Error(ERR_DROP, psTimedOut);
//CL_Disconnect( qtrue ); //CL_Disconnect( qtrue );
return; return;
} }
@ -1968,12 +2086,16 @@ CL_Frame
*/ */
static unsigned int frameCount; static unsigned int frameCount;
static float avgFrametime=0.0; static float avgFrametime=0.0;
extern void SP_CheckForLanguageUpdates(void);
void CL_Frame ( int msec ) { void CL_Frame ( int msec ) {
if ( !com_cl_running->integer ) { if ( !com_cl_running->integer ) {
return; return;
} }
SP_CheckForLanguageUpdates(); // will take zero time to execute unless language changes, then will reload strings.
// of course this still doesn't work for menus...
if ( cls.state == CA_DISCONNECTED && !( cls.keyCatchers & KEYCATCH_UI ) if ( cls.state == CA_DISCONNECTED && !( cls.keyCatchers & KEYCATCH_UI )
&& !com_sv_running->integer ) { && !com_sv_running->integer ) {
// if disconnected, bring up the menu // if disconnected, bring up the menu
@ -2017,6 +2139,13 @@ void CL_Frame ( int msec ) {
cls.realtime += cls.frametime; cls.realtime += cls.frametime;
#ifdef _DONETPROFILE_
if(cls.state==CA_ACTIVE)
{
ClReadProf().IncTime(cls.frametime);
}
#endif
if ( cl_timegraph->integer ) { if ( cl_timegraph->integer ) {
SCR_DebugGraph ( cls.realFrametime * 0.25, 0 ); SCR_DebugGraph ( cls.realFrametime * 0.25, 0 );
} }
@ -2244,7 +2373,6 @@ void CL_SetModel_f( void ) {
arg = Cmd_Argv( 1 ); arg = Cmd_Argv( 1 );
if (arg[0]) { if (arg[0]) {
Cvar_Set( "model", arg ); Cvar_Set( "model", arg );
Cvar_Set( "headmodel", arg );
} else { } else {
Cvar_VariableStringBuffer( "model", name, sizeof(name) ); Cvar_VariableStringBuffer( "model", name, sizeof(name) );
Com_Printf("model is set to %s\n", name); Com_Printf("model is set to %s\n", name);
@ -2262,8 +2390,10 @@ Register_StringPackets
*/ */
void Register_StringPackets (void) void Register_StringPackets (void)
{ {
SP_Register("con_text", SP_REGISTER_REQUIRED); SP_Register("con_text", SP_REGISTER_REQUIRED); //reference is CON_TEXT
SP_Register("mp_ingame",SP_REGISTER_REQUIRED); SP_Register("mp_ingame",SP_REGISTER_REQUIRED); //reference is INGAMETEXT
SP_Register("mp_svgame",SP_REGISTER_REQUIRED); //reference is SVINGAME
SP_Register("sp_ingame",SP_REGISTER_REQUIRED); //reference is INGAME , needed for item pickups
} }
@ -2311,7 +2441,7 @@ void CL_Init( void ) {
cl_yawspeed = Cvar_Get ("cl_yawspeed", "140", CVAR_ARCHIVE); cl_yawspeed = Cvar_Get ("cl_yawspeed", "140", CVAR_ARCHIVE);
cl_pitchspeed = Cvar_Get ("cl_pitchspeed", "140", CVAR_ARCHIVE); cl_pitchspeed = Cvar_Get ("cl_pitchspeed", "140", CVAR_ARCHIVE);
cl_anglespeedkey = Cvar_Get ("cl_anglespeedkey", "1.5", 0); cl_anglespeedkey = Cvar_Get ("cl_anglespeedkey", "1.5", CVAR_ARCHIVE);
cl_maxpackets = Cvar_Get ("cl_maxpackets", "30", CVAR_ARCHIVE ); cl_maxpackets = Cvar_Get ("cl_maxpackets", "30", CVAR_ARCHIVE );
cl_packetdup = Cvar_Get ("cl_packetdup", "1", CVAR_ARCHIVE ); cl_packetdup = Cvar_Get ("cl_packetdup", "1", CVAR_ARCHIVE );
@ -2325,6 +2455,8 @@ void CL_Init( void ) {
cl_framerate = Cvar_Get ("cl_framerate", "0", CVAR_TEMP); cl_framerate = Cvar_Get ("cl_framerate", "0", CVAR_TEMP);
cl_allowDownload = Cvar_Get ("cl_allowDownload", "0", CVAR_ARCHIVE); cl_allowDownload = Cvar_Get ("cl_allowDownload", "0", CVAR_ARCHIVE);
cl_autolodscale = Cvar_Get( "cl_autolodscale", "1", CVAR_ARCHIVE );
cl_conXOffset = Cvar_Get ("cl_conXOffset", "0", 0); cl_conXOffset = Cvar_Get ("cl_conXOffset", "0", 0);
#ifdef MACOS_X #ifdef MACOS_X
// In game video is REALLY slow in Mac OS X right now due to driver slowness // In game video is REALLY slow in Mac OS X right now due to driver slowness
@ -2356,14 +2488,14 @@ void CL_Init( void ) {
// userinfo // userinfo
Cvar_Get ("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("name", "Padawan", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("rate", "3000", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("rate", "4000", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("snaps", "20", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("snaps", "20", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("model", "kyle", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("model", "kyle/default", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("headmodel", "kyle", CVAR_USERINFO | CVAR_ARCHIVE ); // Cvar_Get ("headmodel", "kyle/default", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("team_model", "kyle", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("team_model", "kyle/default", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("team_headmodel", "kyle", CVAR_USERINFO | CVAR_ARCHIVE ); // Cvar_Get ("team_headmodel", "kyle/default", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("forcepowers", "5-1-000000000000000000", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("forcepowers", "7-1-032330000000001333", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("g_redTeam", "Empire", CVAR_SERVERINFO | CVAR_ARCHIVE); Cvar_Get ("g_redTeam", "Empire", CVAR_SERVERINFO | CVAR_ARCHIVE);
Cvar_Get ("g_blueTeam", "Rebellion", CVAR_SERVERINFO | CVAR_ARCHIVE); Cvar_Get ("g_blueTeam", "Rebellion", CVAR_SERVERINFO | CVAR_ARCHIVE);
Cvar_Get ("color1", "4", CVAR_USERINFO | CVAR_ARCHIVE ); Cvar_Get ("color1", "4", CVAR_USERINFO | CVAR_ARCHIVE );
@ -2438,13 +2570,13 @@ void CL_Shutdown( void ) {
CL_Disconnect( qtrue ); CL_Disconnect( qtrue );
CL_ShutdownRef(); //must be before shutdown all so the images get dumped in RE_Shutdown
// RJ: added the shutdown all to close down the cgame (to free up some memory, such as in the fx system) // RJ: added the shutdown all to close down the cgame (to free up some memory, such as in the fx system)
CL_ShutdownAll(); CL_ShutdownAll();
S_Shutdown(); S_Shutdown();
CL_ShutdownRef(); //CL_ShutdownUI();
CL_ShutdownUI();
Cmd_RemoveCommand ("cmd"); Cmd_RemoveCommand ("cmd");
Cmd_RemoveCommand ("configstrings"); Cmd_RemoveCommand ("configstrings");

View file

@ -3,6 +3,9 @@
#include "client.h" #include "client.h"
#include "..\qcommon\strip.h" #include "..\qcommon\strip.h"
#include "../ghoul2/g2_local.h" #include "../ghoul2/g2_local.h"
#ifdef _DONETPROFILE_
#include "../qcommon/INetProfile.h"
#endif
char *svc_strings[256] = { char *svc_strings[256] = {
"svc_bad", "svc_bad",
@ -233,7 +236,7 @@ void CL_ParseSnapshot( msg_t *msg ) {
// is too old, so we can't reconstruct it properly. // is too old, so we can't reconstruct it properly.
Com_Printf ("Delta frame too old.\n"); Com_Printf ("Delta frame too old.\n");
} else if ( cl.parseEntitiesNum - old->parseEntitiesNum > MAX_PARSE_ENTITIES-128 ) { } else if ( cl.parseEntitiesNum - old->parseEntitiesNum > MAX_PARSE_ENTITIES-128 ) {
Com_Printf ("Delta parseEntitiesNum too old.\n"); Com_DPrintf ("Delta parseEntitiesNum too old.\n");
} else { } else {
newSnap.valid = qtrue; // valid delta parse newSnap.valid = qtrue; // valid delta parse
} }
@ -326,7 +329,8 @@ void CL_SystemInfoChanged( void ) {
} }
s = Info_ValueForKey( systemInfo, "sv_cheats" ); s = Info_ValueForKey( systemInfo, "sv_cheats" );
if ( atoi(s) == 0 ) { if ( atoi(s) == 0 )
{
Cvar_SetCheatState(); Cvar_SetCheatState();
} }
@ -381,6 +385,11 @@ void CL_ParseGamestate( msg_t *msg ) {
// wipe local client state // wipe local client state
CL_ClearState(); CL_ClearState();
#ifdef _DONETPROFILE_
int startBytes,endBytes;
startBytes=msg->readcount;
#endif
// a gamestate always marks a server command sequence // a gamestate always marks a server command sequence
clc.serverCommandSequence = MSG_ReadLong( msg ); clc.serverCommandSequence = MSG_ReadLong( msg );
@ -428,6 +437,11 @@ void CL_ParseGamestate( msg_t *msg ) {
// read the checksum feed // read the checksum feed
clc.checksumFeed = MSG_ReadLong( msg ); clc.checksumFeed = MSG_ReadLong( msg );
#ifdef _DONETPROFILE_
endBytes=msg->readcount;
// ClReadProf().AddField("svc_gamestate",endBytes-startBytes);
#endif
// parse serverId and other cvars // parse serverId and other cvars
CL_SystemInfoChanged(); CL_SystemInfoChanged();
@ -555,9 +569,16 @@ void CL_ParseCommandString( msg_t *msg ) {
int seq; int seq;
int index; int index;
#ifdef _DONETPROFILE_
int startBytes,endBytes;
startBytes=msg->readcount;
#endif
seq = MSG_ReadLong( msg ); seq = MSG_ReadLong( msg );
s = MSG_ReadString( msg ); s = MSG_ReadString( msg );
#ifdef _DONETPROFILE_
endBytes=msg->readcount;
ClReadProf().AddField("svc_serverCommand",endBytes-startBytes);
#endif
// see if we have already executed stored it off // see if we have already executed stored it off
if ( clc.serverCommandSequence >= seq ) { if ( clc.serverCommandSequence >= seq ) {
return; return;

View file

@ -641,7 +641,7 @@ Key_KeynumToStringBuf
==================== ====================
*/ */
static void Key_KeynumToStringBuf( int keynum, char *buf, int buflen ) { static void Key_KeynumToStringBuf( int keynum, char *buf, int buflen ) {
Q_strncpyz( buf, Key_KeynumToString( keynum ), buflen ); Q_strncpyz( buf, Key_KeynumToString( keynum, qtrue ), buflen );
} }
/* /*
@ -1131,8 +1131,7 @@ int CL_UISystemCalls( int *args ) {
#endif // USE_CD_KEY #endif // USE_CD_KEY
case UI_SP_REGISTER: case UI_SP_REGISTER:
SP_Register((const char *)VMA(1),SP_REGISTER_MENU); return !!SP_Register((const char *)VMA(1),SP_REGISTER_MENU);
return 0;
case UI_SP_GETSTRINGTEXTSTRING: case UI_SP_GETSTRINGTEXTSTRING:
const char* text; const char* text;

View file

@ -437,7 +437,7 @@ void IN_CenterView (void);
void CL_VerifyCode( void ); void CL_VerifyCode( void );
float CL_KeyState (kbutton_t *key); float CL_KeyState (kbutton_t *key);
char *Key_KeynumToString (int keynum); char *Key_KeynumToString( int keynum, qboolean bTranslate ); //note: translate is only called for menu display not configs
// //
// cl_parse.c // cl_parse.c

View file

@ -135,6 +135,7 @@ cvar_t *s_show;
cvar_t *s_mixahead; cvar_t *s_mixahead;
cvar_t *s_mixPreStep; cvar_t *s_mixPreStep;
cvar_t *s_musicVolume; cvar_t *s_musicVolume;
cvar_t *s_musicMult;
cvar_t *s_separation; cvar_t *s_separation;
cvar_t *s_doppler; cvar_t *s_doppler;
cvar_t *s_CPUType; cvar_t *s_CPUType;
@ -211,7 +212,11 @@ void S_Init( void ) {
Com_Printf("\n------- sound initialization -------\n"); Com_Printf("\n------- sound initialization -------\n");
s_volume = Cvar_Get ("s_volume", "0.8", CVAR_ARCHIVE); s_volume = Cvar_Get ("s_volume", "0.8", CVAR_ARCHIVE);
s_musicVolume = Cvar_Get ("s_musicvolume", "0.25", CVAR_ARCHIVE); s_musicVolume = Cvar_Get ("s_musicvolume", "0.5", CVAR_ARCHIVE);
//rww - multiply s_musicVolume by this value. Set in cgame when necessary.
s_musicMult = Cvar_Get ("s_musicMult", "1", 0);
s_separation = Cvar_Get ("s_separation", "0.5", CVAR_ARCHIVE); s_separation = Cvar_Get ("s_separation", "0.5", CVAR_ARCHIVE);
s_doppler = Cvar_Get ("s_doppler", "1", CVAR_ARCHIVE); s_doppler = Cvar_Get ("s_doppler", "1", CVAR_ARCHIVE);
s_khz = Cvar_Get ("s_khz", "22", CVAR_ARCHIVE); s_khz = Cvar_Get ("s_khz", "22", CVAR_ARCHIVE);
@ -543,9 +548,7 @@ sfxHandle_t S_RegisterSound( const char *name)
if ( sfx->bDefaultSound ) { if ( sfx->bDefaultSound ) {
// Suppress error for inline sounds // Suppress error for inline sounds
if(Q_stricmp(sfx->sSoundName, DEFAULT_SOUND_NAME)){ if(Q_stricmp(sfx->sSoundName, DEFAULT_SOUND_NAME)){
#ifdef _DEBUG Com_DPrintf( S_COLOR_YELLOW "WARNING: could not find %s - using default\n", sfx->sSoundName );
Com_Printf( S_COLOR_YELLOW "WARNING: could not find %s - using default\n", sfx->sSoundName );
#endif
} }
return 0; return 0;
} }
@ -2050,7 +2053,7 @@ static qboolean S_UpdateBackgroundTrack_Actual( MusicInfo_t *pMusicInfo )
int fileBytes; int fileBytes;
int r; int r;
float fMasterVol = s_musicVolume->value; float fMasterVol = (s_musicVolume->value*s_musicMult->value);
static float musicVolume = 0.25f; static float musicVolume = 0.25f;
@ -2213,6 +2216,10 @@ cvar_t *s_soundpoolmegs = NULL;
void SND_setup() void SND_setup()
{ {
s_soundpoolmegs = Cvar_Get("s_soundpoolmegs", "25", CVAR_ARCHIVE); s_soundpoolmegs = Cvar_Get("s_soundpoolmegs", "25", CVAR_ARCHIVE);
if (Sys_LowPhysicalMemory() )
{
Cvar_Set("s_soundpoolmegs", "0");
}
Com_Printf("Sound memory manager started\n"); Com_Printf("Sound memory manager started\n");
} }
@ -2373,7 +2380,7 @@ qboolean SND_RegisterAudio_LevelLoadEnd(qboolean bDeleteEverythingNotUsedThisLev
else else
{ {
int iLoadedAudioBytes = Z_MemSize ( TAG_SND_RAWDATA ) + Z_MemSize( TAG_SND_MP3STREAMHDR ); int iLoadedAudioBytes = Z_MemSize ( TAG_SND_RAWDATA ) + Z_MemSize( TAG_SND_MP3STREAMHDR );
const int iMaxAudioBytes = (!Sys_LowPhysicalMemory() && s_soundpoolmegs) ? (s_soundpoolmegs->integer * 1024 * 1024) : 0; const int iMaxAudioBytes = s_soundpoolmegs->integer * 1024 * 1024;
for (int i=1; i<s_numSfx && ( iLoadedAudioBytes > iMaxAudioBytes || bDeleteEverythingNotUsedThisLevel) ; i++) // i=1 so we never page out default sound for (int i=1; i<s_numSfx && ( iLoadedAudioBytes > iMaxAudioBytes || bDeleteEverythingNotUsedThisLevel) ; i++) // i=1 so we never page out default sound
{ {

View file

@ -219,11 +219,44 @@ void S_LoadSound_Finalize(wavinfo_t *info, sfx_t *sfx, byte *data)
// //
// returns qfalse if failed to load, else fills in *pData // returns qfalse if failed to load, else fills in *pData
// //
extern cvar_t *com_buildScript;
static qboolean S_LoadSound_FileLoadAndNameAdjuster(char *psFilename, byte **pData, int *piSize, int iNameStrlen) static qboolean S_LoadSound_FileLoadAndNameAdjuster(char *psFilename, byte **pData, int *piSize, int iNameStrlen)
{ {
char *psVoice = strstr(psFilename,"chars"); char *psVoice = strstr(psFilename,"chars");
if (psVoice) if (psVoice)
{ {
// cache foreign voices...
//
if (com_buildScript->integer)
{
fileHandle_t hFile;
strncpy(psVoice,"chr_d",5); // same number of letters as "chars"
FS_FOpenFileRead(psFilename, &hFile, qfalse); //cache this file
if (!hFile)
{
strcpy(&psFilename[iNameStrlen-3],"mp3"); //not there try mp3
FS_FOpenFileRead(psFilename, &hFile, qfalse); //cache this file
}
if (hFile)
{
FS_FCloseFile(hFile);
}
strcpy(&psFilename[iNameStrlen-3],"wav");
strncpy(psVoice,"chr_f",5); // same number of letters as "chars"
FS_FOpenFileRead(psFilename, &hFile, qfalse); //cahce this file
if (!hFile)
{
strcpy(&psFilename[iNameStrlen-3],"mp3"); //not there try mp3
FS_FOpenFileRead(psFilename, &hFile, qfalse); //cache this file
}
if (hFile)
{
FS_FCloseFile(hFile);
}
strncpy(psVoice,"chars",5); //put it back to chars
}
// account for foreign voices... // account for foreign voices...
// //
extern cvar_t* s_language; extern cvar_t* s_language;

BIN
CODE-mp/client/vssver.scc Normal file

Binary file not shown.

View file

@ -258,8 +258,8 @@ bool cEncryptedFile::GetKey(char *KeyUser, char *KeyPassword)
extern int Sys_GetProcessorId( void ); extern int Sys_GetProcessorId( void );
Connection->Print("Info: procId: 0x%x\r\n", Sys_GetProcessorId() ); Connection->Print("Info: procId: 0x%x\r\n", Sys_GetProcessorId() );
//#include "../qcommon/stv_version.h" #include "../qcommon/game_version.h"
// Connection->Print("Info: Version '" Q3_VERSION " " __DATE__ "'\r\n"); Connection->Print("Info: Version '" Q3_VERSION " " __DATE__ "'\r\n");
Connection->Print("\r\n"); Connection->Print("\r\n");
while(!Connection->Handle()) while(!Connection->Handle())

Binary file not shown.

View file

@ -0,0 +1,3 @@
EXPORTS
dllEntry
vmMain

View file

@ -552,6 +552,14 @@ void BotInputToUserCommand(bot_input_t *bi, usercmd_t *ucmd, int delta_angles[3]
if (bi->actionflags & ACTION_FOLLOWME) ucmd->buttons |= BUTTON_FOLLOWME; if (bi->actionflags & ACTION_FOLLOWME) ucmd->buttons |= BUTTON_FOLLOWME;
#endif //0 #endif //0
if (bi->weapon == WP_NONE)
{
#ifdef _DEBUG
// Com_Printf("WARNING: Bot tried to use WP_NONE!\n");
#endif
bi->weapon = WP_BRYAR_PISTOL;
}
// //
ucmd->weapon = bi->weapon; ucmd->weapon = bi->weapon;
//set the view angles //set the view angles
@ -1276,8 +1284,12 @@ void WPConstantRoutine(bot_state_t *bs)
if (heightDif > 40 && (bs->cur_ps.fd.forcePowersKnown & (1 << FP_LEVITATION)) && (bs->cur_ps.fd.forceJumpCharge < (forceJumpStrength[bs->cur_ps.fd.forcePowerLevel[FP_LEVITATION]]-100) || bs->cur_ps.groundEntityNum == ENTITYNUM_NONE)) if (heightDif > 40 && (bs->cur_ps.fd.forcePowersKnown & (1 << FP_LEVITATION)) && (bs->cur_ps.fd.forceJumpCharge < (forceJumpStrength[bs->cur_ps.fd.forcePowerLevel[FP_LEVITATION]]-100) || bs->cur_ps.groundEntityNum == ENTITYNUM_NONE))
{ {
bs->forceJumpChargeTime = level.time + 300; bs->forceJumpChargeTime = level.time + 1000;
bs->beStill = level.time + 100; if (bs->cur_ps.groundEntityNum != ENTITYNUM_NONE && bs->jumpPrep < (level.time-300))
{
bs->jumpPrep = level.time + 700;
}
bs->beStill = level.time + 300;
bs->jumpTime = 0; bs->jumpTime = 0;
if (bs->wpSeenTime < (level.time + 600)) if (bs->wpSeenTime < (level.time + 600))
@ -1541,7 +1553,7 @@ int BotTrace_Jump(bot_state_t *bs, vec3_t traceto)
mins[0] = -15; mins[0] = -15;
mins[1] = -15; mins[1] = -15;
mins[2] = -15; mins[2] = -18;
maxs[0] = 15; maxs[0] = 15;
maxs[1] = 15; maxs[1] = 15;
maxs[2] = 32; maxs[2] = 32;
@ -1726,6 +1738,25 @@ int PassStandardEnemyChecks(bot_state_t *bs, gentity_t *en)
return 0; return 0;
} }
if (g_gametype.integer == GT_JEDIMASTER && !en->client->ps.isJediMaster && !bs->cur_ps.isJediMaster)
{ //rules for attacking non-JM in JM mode
vec3_t vs;
float vLen = 0;
if (!g_friendlyFire.integer)
{ //can't harm non-JM in JM mode if FF is off
return 0;
}
VectorSubtract(bs->origin, en->client->ps.origin, vs);
vLen = VectorLength(vs);
if (vLen > 350)
{
return 0;
}
}
/* /*
if (en->client && en->client->pers.connected != CON_CONNECTED) if (en->client && en->client->pers.connected != CON_CONNECTED)
{ {
@ -1992,6 +2023,8 @@ int PassLovedOneCheck(bot_state_t *bs, gentity_t *ent)
return 1; return 1;
} }
qboolean G_ThereIsAMaster(void);
int ScanForEnemies(bot_state_t *bs) int ScanForEnemies(bot_state_t *bs)
{ {
vec3_t a; vec3_t a;
@ -2000,6 +2033,7 @@ int ScanForEnemies(bot_state_t *bs)
int bestindex; int bestindex;
int i; int i;
float hasEnemyDist = 0; float hasEnemyDist = 0;
qboolean noAttackNonJM = qfalse;
closest = 999999; closest = 999999;
i = 0; i = 0;
@ -2016,6 +2050,21 @@ int ScanForEnemies(bot_state_t *bs)
return -1; return -1;
} }
if (g_gametype.integer == GT_JEDIMASTER)
{
if (G_ThereIsAMaster() && !bs->cur_ps.isJediMaster)
{
if (!g_friendlyFire.integer)
{
noAttackNonJM = qtrue;
}
else
{
closest = 128; //only get mad at people if they get close enough to you to anger you, or hurt you
}
}
}
while (i <= MAX_CLIENTS) while (i <= MAX_CLIENTS)
{ {
if (i != bs->client && g_entities[i].client && !OnSameTeam(&g_entities[bs->client], &g_entities[i]) && PassStandardEnemyChecks(bs, &g_entities[i]) && trap_InPVS(g_entities[i].client->ps.origin, bs->eye) && PassLovedOneCheck(bs, &g_entities[i])) if (i != bs->client && g_entities[i].client && !OnSameTeam(&g_entities[bs->client], &g_entities[i]) && PassStandardEnemyChecks(bs, &g_entities[i]) && trap_InPVS(g_entities[i].client->ps.origin, bs->eye) && PassLovedOneCheck(bs, &g_entities[i]))
@ -2037,8 +2086,11 @@ int ScanForEnemies(bot_state_t *bs)
{ {
if (!hasEnemyDist || distcheck < (hasEnemyDist - 128)) if (!hasEnemyDist || distcheck < (hasEnemyDist - 128))
{ //if we have an enemy, only switch to closer if he is 128+ closer to avoid flipping out { //if we have an enemy, only switch to closer if he is 128+ closer to avoid flipping out
closest = distcheck; if (!noAttackNonJM || g_entities[i].client->ps.isJediMaster)
bestindex = i; {
closest = distcheck;
bestindex = i;
}
} }
} }
} }
@ -2046,8 +2098,11 @@ int ScanForEnemies(bot_state_t *bs)
{ {
if (!hasEnemyDist || distcheck < (hasEnemyDist - 128)) if (!hasEnemyDist || distcheck < (hasEnemyDist - 128))
{ //if we have an enemy, only switch to closer if he is 128+ closer to avoid flipping out { //if we have an enemy, only switch to closer if he is 128+ closer to avoid flipping out
closest = distcheck; if (!noAttackNonJM || g_entities[i].client->ps.isJediMaster)
bestindex = i; {
closest = distcheck;
bestindex = i;
}
} }
} }
} }
@ -2137,6 +2192,11 @@ int BotIsAChickenWuss(bot_state_t *bs)
{ {
int bWRange; int bWRange;
if (gLevelFlags & LEVELFLAG_IMUSTNTRUNAWAY)
{
return 0;
}
if (g_gametype.integer == GT_JEDIMASTER && !bs->cur_ps.isJediMaster) if (g_gametype.integer == GT_JEDIMASTER && !bs->cur_ps.isJediMaster)
{ //Then you may know no fear. { //Then you may know no fear.
//Well, unless he's strong. //Well, unless he's strong.
@ -4839,6 +4899,17 @@ int BotTryAnotherWeapon(bot_state_t *bs)
return 0; return 0;
} }
qboolean BotWeaponSelectable(bot_state_t *bs, int weapon)
{
if (bs->cur_ps.ammo[weaponData[weapon].ammoIndex] >= weaponData[weapon].energyPerShot &&
(bs->cur_ps.stats[STAT_WEAPONS] & (1 << weapon)))
{
return qtrue;
}
return qfalse;
}
int BotSelectIdealWeapon(bot_state_t *bs) int BotSelectIdealWeapon(bot_state_t *bs)
{ {
int i; int i;
@ -4871,7 +4942,7 @@ int BotSelectIdealWeapon(bot_state_t *bs)
i++; i++;
} }
if ( bs->currentEnemy && bs->frame_Enemy_Len < 512 && if ( bs->currentEnemy && bs->frame_Enemy_Len < 300 &&
(bestweapon == WP_BRYAR_PISTOL || bestweapon == WP_BLASTER || bestweapon == WP_BOWCASTER) && (bestweapon == WP_BRYAR_PISTOL || bestweapon == WP_BLASTER || bestweapon == WP_BOWCASTER) &&
(bs->cur_ps.stats[STAT_WEAPONS] & (1 << WP_SABER)) ) (bs->cur_ps.stats[STAT_WEAPONS] & (1 << WP_SABER)) )
{ {
@ -4879,6 +4950,42 @@ int BotSelectIdealWeapon(bot_state_t *bs)
bestweight = 1; bestweight = 1;
} }
if ( bs->currentEnemy && bs->frame_Enemy_Len > 300 &&
bs->currentEnemy->client && bs->currentEnemy->client->ps.weapon != WP_SABER &&
(bestweapon == WP_SABER) )
{ //if the enemy is far away, and we have our saber selected, see if we have any good distance weapons instead
if (BotWeaponSelectable(bs, WP_DISRUPTOR))
{
bestweapon = WP_DISRUPTOR;
bestweight = 1;
}
else if (BotWeaponSelectable(bs, WP_ROCKET_LAUNCHER))
{
bestweapon = WP_ROCKET_LAUNCHER;
bestweight = 1;
}
else if (BotWeaponSelectable(bs, WP_BOWCASTER))
{
bestweapon = WP_BOWCASTER;
bestweight = 1;
}
else if (BotWeaponSelectable(bs, WP_BLASTER))
{
bestweapon = WP_BLASTER;
bestweight = 1;
}
else if (BotWeaponSelectable(bs, WP_REPEATER))
{
bestweapon = WP_REPEATER;
bestweight = 1;
}
else if (BotWeaponSelectable(bs, WP_DEMP2))
{
bestweapon = WP_DEMP2;
bestweight = 1;
}
}
if (bestweight != -1 && bs->cur_ps.weapon != bestweapon && bs->virtualWeapon != bestweapon) if (bestweight != -1 && bs->cur_ps.weapon != bestweapon && bs->virtualWeapon != bestweapon)
{ {
bs->virtualWeapon = bestweapon; bs->virtualWeapon = bestweapon;
@ -5937,6 +6044,7 @@ void StandardBotAI(bot_state_t *bs, float thinktime)
} }
} }
/*
if (bs->currentEnemy && bs->currentEnemy->client && if (bs->currentEnemy && bs->currentEnemy->client &&
bs->cur_ps.weapon == WP_SABER && bs->cur_ps.weapon == WP_SABER &&
g_privateDuel.integer && g_privateDuel.integer &&
@ -5971,6 +6079,9 @@ void StandardBotAI(bot_state_t *bs, float thinktime)
bs->beStill = level.time + 100; bs->beStill = level.time + 100;
} }
} }
*/
//Apparently this "allows you to cheese" when fighting against bots. I'm not sure why you'd want to con bots
//into an easy kill, since they're bots and all. But whatever.
if (!bs->wpCurrent) if (!bs->wpCurrent)
{ {
@ -6605,6 +6716,11 @@ void StandardBotAI(bot_state_t *bs, float thinktime)
} }
#endif #endif
if (bs->jumpPrep > level.time)
{
bs->forceJumpChargeTime = 0;
}
if (bs->forceJumpChargeTime > level.time) if (bs->forceJumpChargeTime > level.time)
{ {
bs->jumpHoldTime = ((bs->forceJumpChargeTime - level.time)/2) + level.time; bs->jumpHoldTime = ((bs->forceJumpChargeTime - level.time)/2) + level.time;
@ -6621,7 +6737,17 @@ void StandardBotAI(bot_state_t *bs, float thinktime)
if (bs->jumpHoldTime > level.time) if (bs->jumpHoldTime > level.time)
{ {
trap_EA_Jump(bs->client); trap_EA_Jump(bs->client);
trap_EA_MoveForward(bs->client); if (bs->wpCurrent)
{
if ((bs->wpCurrent->origin[2] - bs->origin[2]) < 64)
{
trap_EA_MoveForward(bs->client);
}
}
else
{
trap_EA_MoveForward(bs->client);
}
if (g_entities[bs->client].client->ps.groundEntityNum == ENTITYNUM_NONE) if (g_entities[bs->client].client->ps.groundEntityNum == ENTITYNUM_NONE)
{ {
g_entities[bs->client].client->ps.pm_flags |= PMF_JUMP_HELD; g_entities[bs->client].client->ps.pm_flags |= PMF_JUMP_HELD;
@ -6788,7 +6914,7 @@ void StandardBotAI(bot_state_t *bs, float thinktime)
else else
{ {
#endif #endif
if (bot_forcepowers.integer) if (bot_forcepowers.integer && !g_forcePowerDisable.integer)
{ {
trap_EA_ForcePower(bs->client); trap_EA_ForcePower(bs->client);
} }

View file

@ -38,6 +38,7 @@
#define LEVELFLAG_NOPOINTPREDICTION 1 //don't take waypoint beyond current into account when adjusting path view angles #define LEVELFLAG_NOPOINTPREDICTION 1 //don't take waypoint beyond current into account when adjusting path view angles
#define LEVELFLAG_IGNOREINFALLBACK 2 //ignore enemies when in a fallback navigation routine #define LEVELFLAG_IGNOREINFALLBACK 2 //ignore enemies when in a fallback navigation routine
#define LEVELFLAG_IMUSTNTRUNAWAY 4 //don't be scared
#define WP_KEEP_FLAG_DIST 128 #define WP_KEEP_FLAG_DIST 128
@ -241,6 +242,7 @@ typedef struct bot_state_s
float duckTime; float duckTime;
float jumpTime; float jumpTime;
float jumpHoldTime; float jumpHoldTime;
float jumpPrep;
float forceJumping; float forceJumping;
float jDelay; float jDelay;

View file

@ -347,6 +347,11 @@ int BotDoChat(bot_state_t *bs, char *section, int always)
return 0; return 0;
} }
if (trap_Cvar_VariableIntegerValue("sp_language"))
{ //no chatting unless English.
return 0;
}
if (Q_irand(1, 10) > bs->chatFrequency && !always) if (Q_irand(1, 10) > bs->chatFrequency && !always)
{ {
return 0; return 0;

View file

@ -210,7 +210,7 @@ void G_TestLine(vec3_t start, vec3_t end, int color, int time)
te = G_TempEntity( start, EV_TESTLINE ); te = G_TempEntity( start, EV_TESTLINE );
VectorCopy(start, te->s.origin); VectorCopy(start, te->s.origin);
VectorCopy(end, te->s.origin2); VectorCopy(end, te->s.origin2);
te->s.trickedentindex = time; te->s.time2 = time;
te->s.weapon = color; te->s.weapon = color;
te->r.svFlags |= SVF_BROADCAST; te->r.svFlags |= SVF_BROADCAST;
} }

View file

@ -1231,7 +1231,6 @@ typedef enum //# animNumber_e
FACE_SMILE, //# FACE_SMILE, //#
FACE_FROWN, //# FACE_FROWN, //#
FACE_DEAD, //# FACE_DEAD, //#
FACE_GALAK, //# This has to be last for Galak Mech to talk
//# #eol //# #eol
MAX_ANIMATIONS, MAX_ANIMATIONS,

View file

@ -19,16 +19,19 @@
#endif #endif
#endif #endif
//rww - not putting @ in front of these because
//we don't need them in a cgame striped lookup.
//Let me know if this causes problems, pat.
char *forceMasteryLevels[NUM_FORCE_MASTERY_LEVELS] = char *forceMasteryLevels[NUM_FORCE_MASTERY_LEVELS] =
{ {
"Uninitiated", // FORCE_MASTERY_UNINITIATED, "MASTERY0", //"Uninitiated", // FORCE_MASTERY_UNINITIATED,
"@MASTERY1", //"Initiate", // FORCE_MASTERY_INITIATE, "MASTERY1", //"Initiate", // FORCE_MASTERY_INITIATE,
"@MASTERY2", //"Padawan", // FORCE_MASTERY_PADAWAN, "MASTERY2", //"Padawan", // FORCE_MASTERY_PADAWAN,
"@MASTERY3", //"Disciple", // FORCE_MASTERY_DISCIPLE, "MASTERY3", //"Jedi", // FORCE_MASTERY_JEDI,
"@MASTERY4", //"Jedi", // FORCE_MASTERY_JEDI, "MASTERY4", //"Jedi Adept", // FORCE_MASTERY_JEDI_GUARDIAN,
"@MASTERY5", //"Jedi Adept", // FORCE_MASTERY_JEDI_ADEPT, "MASTERY5", //"Jedi Guardian", // FORCE_MASTERY_JEDI_ADEPT,
"@MASTERY6", //"Jedi Master", // FORCE_MASTERY_JEDI_MASTER, "MASTERY6", //"Jedi Knight", // FORCE_MASTERY_JEDI_KNIGHT,
"@MASTERY7", //"Jedi Lord" // FORCE_MASTERY_JEDI_LORD, "MASTERY7", //"Jedi Master" // FORCE_MASTERY_JEDI_MASTER,
}; };
int forceMasteryPoints[NUM_FORCE_MASTERY_LEVELS] = int forceMasteryPoints[NUM_FORCE_MASTERY_LEVELS] =
@ -36,13 +39,35 @@ int forceMasteryPoints[NUM_FORCE_MASTERY_LEVELS] =
0, // FORCE_MASTERY_UNINITIATED, 0, // FORCE_MASTERY_UNINITIATED,
5, // FORCE_MASTERY_INITIATE, 5, // FORCE_MASTERY_INITIATE,
10, // FORCE_MASTERY_PADAWAN, 10, // FORCE_MASTERY_PADAWAN,
15, // FORCE_MASTERY_DISCIPLE,
20, // FORCE_MASTERY_JEDI, 20, // FORCE_MASTERY_JEDI,
25, // FORCE_MASTERY_JEDI_ADEPT, 30, // FORCE_MASTERY_JEDI_GUARDIAN,
30, // FORCE_MASTERY_JEDI_MASTER, 50, // FORCE_MASTERY_JEDI_ADEPT,
40 // FORCE_MASTERY_JEDI_LORD, 75, // FORCE_MASTERY_JEDI_KNIGHT,
100 // FORCE_MASTERY_JEDI_MASTER,
}; };
int bgForcePowerCost[NUM_FORCE_POWERS][NUM_FORCE_POWER_LEVELS] = //0 == neutral
{
{ 0, 2, 4, 6 }, // Heal // FP_HEAL
{ 0, 0, 2, 6 }, // Jump //FP_LEVITATION,//hold/duration
{ 0, 2, 4, 6 }, // Speed //FP_SPEED,//duration
{ 0, 1, 3, 6 }, // Push //FP_PUSH,//hold/duration
{ 0, 1, 3, 6 }, // Pull //FP_PULL,//hold/duration
{ 0, 4, 6, 8 }, // Mind Trick //FP_TELEPATHY,//instant
{ 0, 1, 3, 6 }, // Grip //FP_GRIP,//hold/duration
{ 0, 2, 5, 8 }, // Lightning //FP_LIGHTNING,//hold/duration
{ 0, 4, 6, 8 }, // Dark Rage //FP_RAGE,//duration
{ 0, 2, 5, 8 }, // Protection //FP_PROTECT,//duration
{ 0, 1, 3, 6 }, // Absorb //FP_ABSORB,//duration
{ 0, 1, 3, 6 }, // Team Heal //FP_TEAM_HEAL,//instant
{ 0, 1, 3, 6 }, // Team Force //FP_TEAM_FORCE,//instant
{ 0, 2, 4, 6 }, // Drain //FP_DRAIN,//hold/duration
{ 0, 2, 5, 8 }, // Sight //FP_SEE,//duration
{ 0, 1, 5, 8 }, // Saber Attack //FP_SABERATTACK,
{ 0, 1, 5, 8 }, // Saber Defend //FP_SABERDEFEND,
{ 0, 4, 6, 8 } // Saber Throw //FP_SABERTHROW,
//NUM_FORCE_POWERS
};
int forcePowerSorted[NUM_FORCE_POWERS] = int forcePowerSorted[NUM_FORCE_POWERS] =
{ //rww - always use this order when drawing force powers for any reason { //rww - always use this order when drawing force powers for any reason
@ -135,6 +160,289 @@ int WeaponAttackAnim[WP_NUM_WEAPONS] =
BOTH_ATTACK1//WP_TURRET, BOTH_ATTACK1//WP_TURRET,
}; };
//The magical function to end all functions.
//This will take the force power string in powerOut and parse through it, then legalize
//it based on the supposed rank and spit it into powerOut, returning true if it was legal
//to begin with and false if not.
//fpDisabled is actually only expected (needed) from the server, because the ui disables
//force power selection anyway when force powers are disabled on the server.
qboolean BG_LegalizedForcePowers(char *powerOut, int maxRank, qboolean freeSaber, int teamForce, int gametype, int fpDisabled)
{
char powerBuf[128];
char readBuf[128];
qboolean maintainsValidity = qtrue;
int powerLen = strlen(powerOut);
int i = 0;
int c = 0;
int allowedPoints = 0;
int usedPoints = 0;
int countDown = 0;
int final_Side;
int final_Powers[NUM_FORCE_POWERS];
if (powerLen >= 128)
{ //This should not happen. If it does, this is obviously a bogus string.
//They can have this string. Because I said so.
strcpy(powerBuf, "7-1-032330000000001333");
maintainsValidity = qfalse;
}
else
{
strcpy(powerBuf, powerOut); //copy it as the original
}
//first of all, print the max rank into the string as the rank
strcpy(powerOut, va("%i-", maxRank));
while (i < 128 && powerBuf[i] && powerBuf[i] != '-')
{
i++;
}
i++;
while (i < 128 && powerBuf[i] && powerBuf[i] != '-')
{
readBuf[c] = powerBuf[i];
c++;
i++;
}
readBuf[c] = 0;
i++;
//at this point, readBuf contains the intended side
final_Side = atoi(readBuf);
if (final_Side != FORCE_LIGHTSIDE &&
final_Side != FORCE_DARKSIDE)
{ //Not a valid side. You will be dark. Because I said so. (this is something that should never actually happen unless you purposely feed in an invalid config)
final_Side = FORCE_DARKSIDE;
maintainsValidity = qfalse;
}
if (teamForce)
{ //If we are under force-aligned teams, make sure we're on the right side.
if (final_Side != teamForce)
{
final_Side = teamForce;
//maintainsValidity = qfalse;
//Not doing this, for now. Let them join the team with their filtered powers.
}
}
//Now we have established a valid rank, and a valid side.
//Read the force powers in, and cut them down based on the various rules supplied.
c = 0;
while (i < 128 && powerBuf[i] && powerBuf[i] != '\n' && c < NUM_FORCE_POWERS)
{
readBuf[0] = powerBuf[i];
readBuf[1] = 0;
final_Powers[c] = atoi(readBuf);
c++;
i++;
}
//final_Powers now contains all the stuff from the string
//Set the maximum allowed points used based on the max rank level, and count the points actually used.
allowedPoints = forceMasteryPoints[maxRank];
i = 0;
while (i < NUM_FORCE_POWERS)
{ //if this power doesn't match the side we're on, then 0 it now.
if (final_Powers[i] &&
forcePowerDarkLight[i] &&
forcePowerDarkLight[i] != final_Side)
{
final_Powers[i] = 0;
//This is only likely to happen with g_forceBasedTeams. Let it slide.
//maintainsValidity = 0;
}
if ( final_Powers[i] &&
(fpDisabled & (1 << i)) )
{ //if this power is disabled on the server via said server option, then we don't get it.
final_Powers[i] = 0;
}
i++;
}
if (gametype < GT_TEAM)
{ //don't bother with team powers then
final_Powers[FP_TEAM_HEAL] = 0;
final_Powers[FP_TEAM_FORCE] = 0;
}
usedPoints = 0;
i = 0;
while (i < NUM_FORCE_POWERS)
{
countDown = 0;
countDown = final_Powers[i];
while (countDown > 0)
{
usedPoints += bgForcePowerCost[i][countDown]; //[fp index][fp level]
//if this is jump, or we have a free saber and it's offense or defense, take the level back down on level 1
if ( countDown == 1 &&
((i == FP_LEVITATION) ||
(i == FP_SABERATTACK && freeSaber) ||
(i == FP_SABERDEFEND && freeSaber)) )
{
usedPoints -= bgForcePowerCost[i][countDown];
}
countDown--;
}
i++;
}
if (usedPoints > allowedPoints)
{ //Time to do the fancy stuff. (meaning, slowly cut parts off while taking a guess at what is most or least important in the config)
int attemptedCycles = 0;
int powerCycle = 2;
int minPow = 0;
if (freeSaber)
{
minPow = 1;
}
maintainsValidity = qfalse;
while (usedPoints > allowedPoints)
{
c = 0;
while (c < NUM_FORCE_POWERS && usedPoints > allowedPoints)
{
if (final_Powers[c] && final_Powers[c] < powerCycle)
{ //kill in order of lowest powers, because the higher powers are probably more important
if (c == FP_SABERATTACK &&
(final_Powers[FP_SABERDEFEND] > minPow || final_Powers[FP_SABERTHROW] > 0))
{ //if we're on saber attack, only suck it down if we have no def or throw either
int whichOne = FP_SABERTHROW; //first try throw
if (!final_Powers[whichOne])
{
whichOne = FP_SABERDEFEND; //if no throw, drain defense
}
while (final_Powers[whichOne] > 0 && usedPoints > allowedPoints)
{
if ( final_Powers[whichOne] > 1 ||
( (whichOne != FP_SABERATTACK || !freeSaber) &&
(whichOne != FP_SABERDEFEND || !freeSaber) ) )
{ //don't take attack or defend down on level 1 still, if it's free
usedPoints -= bgForcePowerCost[whichOne][final_Powers[whichOne]];
final_Powers[whichOne]--;
}
else
{
break;
}
}
}
else
{
while (final_Powers[c] > 0 && usedPoints > allowedPoints)
{
if ( final_Powers[c] > 1 ||
((c != FP_LEVITATION) &&
(c != FP_SABERATTACK || !freeSaber) &&
(c != FP_SABERDEFEND || !freeSaber)) )
{
usedPoints -= bgForcePowerCost[c][final_Powers[c]];
final_Powers[c]--;
}
else
{
break;
}
}
}
}
c++;
}
powerCycle++;
attemptedCycles++;
if (attemptedCycles > NUM_FORCE_POWERS)
{ //I think this should be impossible. But just in case.
break;
}
}
if (usedPoints > allowedPoints)
{ //Still? Fine then.. we will kill all of your powers, except the freebies.
i = 0;
while (i < NUM_FORCE_POWERS)
{
final_Powers[i] = 0;
if (i == FP_LEVITATION ||
(i == FP_SABERATTACK && freeSaber) ||
(i == FP_SABERDEFEND && freeSaber))
{
final_Powers[i] = 1;
}
i++;
}
usedPoints = 0;
}
}
if (final_Powers[FP_SABERATTACK] < 1)
{
final_Powers[FP_SABERDEFEND] = 0;
final_Powers[FP_SABERTHROW] = 0;
}
if (freeSaber)
{
if (final_Powers[FP_SABERATTACK] < 1)
{
final_Powers[FP_SABERATTACK] = 1;
}
if (final_Powers[FP_SABERDEFEND] < 1)
{
final_Powers[FP_SABERDEFEND] = 1;
}
}
if (final_Powers[FP_LEVITATION] < 1)
{
final_Powers[FP_LEVITATION] = 1;
}
if (fpDisabled)
{
final_Powers[FP_LEVITATION] = 1;
final_Powers[FP_SABERATTACK] = 3;
final_Powers[FP_SABERDEFEND] = 3;
final_Powers[FP_SABERTHROW] = 0;
}
//We finally have all the force powers legalized and stored locally.
//Put them all into the string and return the result. We already have
//the rank there, so print the side and the powers now.
Q_strcat(powerOut, 128, va("%i-", final_Side));
i = strlen(powerOut);
c = 0;
while (c < NUM_FORCE_POWERS)
{
strcpy(readBuf, va("%i", final_Powers[c]));
powerOut[i] = readBuf[0];
c++;
i++;
}
powerOut[i] = 0;
return maintainsValidity;
}
/*QUAKED item_***** ( 0 0 0 ) (-16 -16 -16) (16 16 16) suspended /*QUAKED item_***** ( 0 0 0 ) (-16 -16 -16) (16 16 16) suspended
DO NOT USE THIS CLASS, IT JUST HOLDS GENERAL INFORMATION. DO NOT USE THIS CLASS, IT JUST HOLDS GENERAL INFORMATION.
The suspended flag will allow items to hang in the air, otherwise they are dropped to the next surface. The suspended flag will allow items to hang in the air, otherwise they are dropped to the next surface.
@ -151,6 +459,14 @@ An item fires all of its targets when it is picked up. If the toucher can't car
"count" override quantity or duration on most items. "count" override quantity or duration on most items.
*/ */
/*QUAKED misc_shield_floor_unit (1 0 0) (-16 -16 0) (16 16 40)
#MODELNAME="/models/items/a_shield_converter.md3"
Gives shield energy when used.
"count" - max charge value (default 50)
"chargerate" - rechage 1 point every this many milliseconds (default 3000)
*/
gitem_t bg_itemlist[] = gitem_t bg_itemlist[] =
{ {
{ {
@ -161,7 +477,7 @@ gitem_t bg_itemlist[] =
0, 0} , // world_model[2],[3] 0, 0} , // world_model[2],[3]
NULL, // view_model NULL, // view_model
/* icon */ NULL, // icon /* icon */ NULL, // icon
/* pickup */ NULL, // pickup_name /* pickup */ //NULL, // pickup_name
0, // quantity 0, // quantity
0, // giType (IT_*) 0, // giType (IT_*)
0, // giTag 0, // giTag
@ -183,7 +499,7 @@ Instant shield pickup, restores 25
0, 0, 0}, 0, 0, 0},
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/mp/small_shield", /* icon */ "gfx/mp/small_shield",
/* pickup */ "Shield Small", /* pickup */// "Shield Small",
25, 25,
IT_ARMOR, IT_ARMOR,
1, //special for shield - max on pickup is maxhealth*tag, thus small shield goes up to 100 shield 1, //special for shield - max on pickup is maxhealth*tag, thus small shield goes up to 100 shield
@ -201,7 +517,7 @@ Instant shield pickup, restores 100
0, 0, 0}, 0, 0, 0},
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/mp/large_shield", /* icon */ "gfx/mp/large_shield",
/* pickup */ "Shield Large", /* pickup */// "Shield Large",
100, 100,
IT_ARMOR, IT_ARMOR,
2, //special for shield - max on pickup is maxhealth*tag, thus large shield goes up to 200 shield 2, //special for shield - max on pickup is maxhealth*tag, thus large shield goes up to 200 shield
@ -219,7 +535,7 @@ Instant medpack pickup, heals 25
0, 0, 0 }, 0, 0, 0 },
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/i_icon_medkit", /* icon */ "gfx/hud/i_icon_medkit",
/* pickup */ "Medpack", /* pickup */// "Medpack",
25, 25,
IT_HEALTH, IT_HEALTH,
0, 0,
@ -242,7 +558,7 @@ Instant medpack pickup, heals 25
0, 0, 0} , 0, 0, 0} ,
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/i_icon_seeker", /* icon */ "gfx/hud/i_icon_seeker",
/* pickup */ "Seeker Drone", /* pickup */// "Seeker Drone",
120, 120,
IT_HOLDABLE, IT_HOLDABLE,
HI_SEEKER, HI_SEEKER,
@ -260,7 +576,7 @@ Portable shield
0, 0, 0} , 0, 0, 0} ,
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/i_icon_shieldwall", /* icon */ "gfx/hud/i_icon_shieldwall",
/* pickup */ "Forcefield", /* pickup */// "Forcefield",
120, 120,
IT_HOLDABLE, IT_HOLDABLE,
HI_SHIELD, HI_SHIELD,
@ -272,13 +588,13 @@ Portable shield
Bacta canister pickup, heals 25 on use Bacta canister pickup, heals 25 on use
*/ */
{ {
"item_medpac", "item_medpac", //should be item_bacta
"sound/weapons/w_pkup.wav", "sound/weapons/w_pkup.wav",
{ "models/map_objects/mp/bacta.md3", { "models/map_objects/mp/bacta.md3",
0, 0, 0} , 0, 0, 0} ,
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/i_icon_bacta", /* icon */ "gfx/hud/i_icon_bacta",
/* pickup */ "Bacta Canister", /* pickup */// "Bacta Canister",
25, 25,
IT_HOLDABLE, IT_HOLDABLE,
HI_MEDPAC, HI_MEDPAC,
@ -296,7 +612,7 @@ Do not place this.
0, 0, 0} , 0, 0, 0} ,
/* view */ NULL, /* view */ NULL,
/* icon */ NULL, /* icon */ NULL,
/* pickup */ "Datapad", /* pickup */// "Datapad",
1, 1,
IT_HOLDABLE, IT_HOLDABLE,
HI_DATAPAD, HI_DATAPAD,
@ -314,7 +630,7 @@ These will be standard equipment on the player - DO NOT PLACE
0, 0, 0} , 0, 0, 0} ,
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/i_icon_zoom", /* icon */ "gfx/hud/i_icon_zoom",
/* pickup */ "Binoculars", /* pickup */// "Binoculars",
60, 60,
IT_HOLDABLE, IT_HOLDABLE,
HI_BINOCULARS, HI_BINOCULARS,
@ -332,7 +648,7 @@ Sentry gun inventory pickup.
0, 0, 0} , 0, 0, 0} ,
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/i_icon_sentrygun", /* icon */ "gfx/hud/i_icon_sentrygun",
/* pickup */ "Sentry Gun", /* pickup */// "Sentry Gun",
120, 120,
IT_HOLDABLE, IT_HOLDABLE,
HI_SENTRY_GUN, HI_SENTRY_GUN,
@ -350,7 +666,7 @@ Adds one rank to all Force powers temporarily. Only light jedi can use.
0, 0, 0} , 0, 0, 0} ,
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/mpi_jlight", /* icon */ "gfx/hud/mpi_jlight",
/* pickup */ "Light Force Enlightenment", /* pickup */// "Light Force Enlightenment",
25, 25,
IT_POWERUP, IT_POWERUP,
PW_FORCE_ENLIGHTENED_LIGHT, PW_FORCE_ENLIGHTENED_LIGHT,
@ -368,7 +684,7 @@ Adds one rank to all Force powers temporarily. Only dark jedi can use.
0, 0, 0} , 0, 0, 0} ,
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/mpi_dklight", /* icon */ "gfx/hud/mpi_dklight",
/* pickup */ "Dark Force Enlightenment", /* pickup */// "Dark Force Enlightenment",
25, 25,
IT_POWERUP, IT_POWERUP,
PW_FORCE_ENLIGHTENED_DARK, PW_FORCE_ENLIGHTENED_DARK,
@ -386,7 +702,7 @@ Unlimited Force Pool for a short time.
0, 0, 0} , 0, 0, 0} ,
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/mpi_fboon", /* icon */ "gfx/hud/mpi_fboon",
/* pickup */ "Force Boon", /* pickup */// "Force Boon",
25, 25,
IT_POWERUP, IT_POWERUP,
PW_FORCE_BOON, PW_FORCE_BOON,
@ -404,10 +720,10 @@ A small lizard carried on the player, which prevents the possessor from using an
0, 0, 0} , 0, 0, 0} ,
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/mpi_ysamari", /* icon */ "gfx/hud/mpi_ysamari",
/* pickup */ "Ysalimari", /* pickup */// "Ysalamiri",
25, 25,
IT_POWERUP, IT_POWERUP,
PW_YSALIMARI, PW_YSALAMIRI,
/* precache */ "", /* precache */ "",
/* sounds */ "" /* sounds */ ""
}, },
@ -426,8 +742,8 @@ Don't place this
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/stun_baton/baton.md3", /* view */ "models/weapons2/stun_baton/baton.md3",
/* icon */ "gfx/hud/w_icon_stunbaton", /* icon */ "gfx/hud/w_icon_stunbaton",
/* pickup */ "Stun Baton", /* pickup */// "Stun Baton",
50, 100,
IT_WEAPON, IT_WEAPON,
WP_STUN_BATON, WP_STUN_BATON,
/* precache */ "", /* precache */ "",
@ -444,8 +760,8 @@ Don't place this
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/saber/saber_w.md3", /* view */ "models/weapons2/saber/saber_w.md3",
/* icon */ "gfx/hud/w_icon_lightsaber", /* icon */ "gfx/hud/w_icon_lightsaber",
/* pickup */ "Lightsaber", /* pickup */// "Lightsaber",
50, 100,
IT_WEAPON, IT_WEAPON,
WP_SABER, WP_SABER,
/* precache */ "", /* precache */ "",
@ -462,8 +778,8 @@ Don't place this
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/briar_pistol/briar_pistol.md3", /* view */ "models/weapons2/briar_pistol/briar_pistol.md3",
/* icon */ "gfx/hud/w_icon_rifle", /* icon */ "gfx/hud/w_icon_rifle",
/* pickup */ "Bryar Pistol", /* pickup */// "Bryar Pistol",
50, 100,
IT_WEAPON, IT_WEAPON,
WP_BRYAR_PISTOL, WP_BRYAR_PISTOL,
/* precache */ "", /* precache */ "",
@ -479,8 +795,8 @@ Don't place this
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/blaster_r/blaster.md3", /* view */ "models/weapons2/blaster_r/blaster.md3",
/* icon */ "gfx/hud/w_icon_blaster", /* icon */ "gfx/hud/w_icon_blaster",
/* pickup */ "E11 Blaster Rifle", /* pickup */// "E11 Blaster Rifle",
50, 100,
IT_WEAPON, IT_WEAPON,
WP_BLASTER, WP_BLASTER,
/* precache */ "", /* precache */ "",
@ -496,8 +812,8 @@ Don't place this
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/disruptor/disruptor.md3", /* view */ "models/weapons2/disruptor/disruptor.md3",
/* icon */ "gfx/hud/w_icon_disruptor", /* icon */ "gfx/hud/w_icon_disruptor",
/* pickup */ "Tenloss Disruptor Rifle", /* pickup */// "Tenloss Disruptor Rifle",
50, 100,
IT_WEAPON, IT_WEAPON,
WP_DISRUPTOR, WP_DISRUPTOR,
/* precache */ "", /* precache */ "",
@ -513,8 +829,8 @@ Don't place this
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/bowcaster/bowcaster.md3", /* view */ "models/weapons2/bowcaster/bowcaster.md3",
/* icon */ "gfx/hud/w_icon_bowcaster", /* icon */ "gfx/hud/w_icon_bowcaster",
/* pickup */ "Wookiee Bowcaster", /* pickup */// "Wookiee Bowcaster",
50, 100,
IT_WEAPON, IT_WEAPON,
WP_BOWCASTER, WP_BOWCASTER,
/* precache */ "", /* precache */ "",
@ -530,8 +846,8 @@ Don't place this
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/heavy_repeater/heavy_repeater.md3", /* view */ "models/weapons2/heavy_repeater/heavy_repeater.md3",
/* icon */ "gfx/hud/w_icon_repeater", /* icon */ "gfx/hud/w_icon_repeater",
/* pickup */ "Imperial Heavy Repeater", /* pickup */// "Imperial Heavy Repeater",
50, 100,
IT_WEAPON, IT_WEAPON,
WP_REPEATER, WP_REPEATER,
/* precache */ "", /* precache */ "",
@ -548,8 +864,8 @@ NOTENOTE This weapon is not yet complete. Don't place it.
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/demp2/demp2.md3", /* view */ "models/weapons2/demp2/demp2.md3",
/* icon */ "gfx/hud/w_icon_demp2", /* icon */ "gfx/hud/w_icon_demp2",
/* pickup */ "DEMP2", /* pickup */// "DEMP2",
50, 100,
IT_WEAPON, IT_WEAPON,
WP_DEMP2, WP_DEMP2,
/* precache */ "", /* precache */ "",
@ -565,8 +881,8 @@ NOTENOTE This weapon is not yet complete. Don't place it.
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/golan_arms/golan_arms.md3", /* view */ "models/weapons2/golan_arms/golan_arms.md3",
/* icon */ "gfx/hud/w_icon_flechette", /* icon */ "gfx/hud/w_icon_flechette",
/* pickup */ "Golan Arms Flechette", /* pickup */// "Golan Arms Flechette",
50, 100,
IT_WEAPON, IT_WEAPON,
WP_FLECHETTE, WP_FLECHETTE,
/* precache */ "", /* precache */ "",
@ -582,25 +898,75 @@ NOTENOTE This weapon is not yet complete. Don't place it.
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/merr_sonn/merr_sonn.md3", /* view */ "models/weapons2/merr_sonn/merr_sonn.md3",
/* icon */ "gfx/hud/w_icon_merrsonn", /* icon */ "gfx/hud/w_icon_merrsonn",
/* pickup */ "Merr-Sonn Missile System", /* pickup */// "Merr-Sonn Missile System",
50, 3,
IT_WEAPON, IT_WEAPON,
WP_ROCKET_LAUNCHER, WP_ROCKET_LAUNCHER,
/* precache */ "", /* precache */ "",
/* sounds */ "" /* sounds */ ""
}, },
/*QUAKED ammo_thermal (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
*/
{
"ammo_thermal",
"sound/weapons/w_pkup.wav",
{ "models/weapons2/thermal/thermal_pu.md3",
"models/weapons2/thermal/thermal_w.glm", 0, 0},
/* view */ "models/weapons2/thermal/thermal.md3",
/* icon */ "gfx/hud/w_icon_thermal",
/* pickup */// "Thermal Detonators",
4,
IT_AMMO,
AMMO_THERMAL,
/* precache */ "",
/* sounds */ ""
},
/*QUAKED ammo_tripmine (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
*/
{
"ammo_tripmine",
"sound/weapons/w_pkup.wav",
{ "models/weapons2/laser_trap/laser_trap_pu.md3",
"models/weapons2/laser_trap/laser_trap_w.glm", 0, 0},
/* view */ "models/weapons2/laser_trap/laser_trap.md3",
/* icon */ "gfx/hud/w_icon_tripmine",
/* pickup */// "Trip Mines",
3,
IT_AMMO,
AMMO_TRIPMINE,
/* precache */ "",
/* sounds */ ""
},
/*QUAKED ammo_detpack (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
*/
{
"ammo_detpack",
"sound/weapons/w_pkup.wav",
{ "models/weapons2/detpack/det_pack_pu.md3", "models/weapons2/detpack/det_pack_proj.glm", "models/weapons2/detpack/det_pack_w.glm", 0},
/* view */ "models/weapons2/detpack/det_pack.md3",
/* icon */ "gfx/hud/w_icon_detpack",
/* pickup */// "Det Packs",
3,
IT_AMMO,
AMMO_DETPACK,
/* precache */ "",
/* sounds */ ""
},
/*QUAKED weapon_thermal (.3 .3 1) (-16 -16 -16) (16 16 16) suspended /*QUAKED weapon_thermal (.3 .3 1) (-16 -16 -16) (16 16 16) suspended
*/ */
{ {
"weapon_thermal", "weapon_thermal",
"sound/weapons/w_pkup.wav", "sound/weapons/w_pkup.wav",
{ "models/weapons2/thermal/thermal_w.glm", { "models/weapons2/thermal/thermal_w.glm", "models/weapons2/thermal/thermal_pu.md3",
0, 0, 0}, 0, 0 },
/* view */ "models/weapons2/thermal/thermal.md3", /* view */ "models/weapons2/thermal/thermal.md3",
/* icon */ "gfx/hud/w_icon_thermal", /* icon */ "gfx/hud/w_icon_thermal",
/* pickup */ "Thermal Detonator", /* pickup */// "Thermal Detonator",
1, 4,
IT_WEAPON, IT_WEAPON,
WP_THERMAL, WP_THERMAL,
/* precache */ "", /* precache */ "",
@ -612,12 +978,12 @@ NOTENOTE This weapon is not yet complete. Don't place it.
{ {
"weapon_trip_mine", "weapon_trip_mine",
"sound/weapons/w_pkup.wav", "sound/weapons/w_pkup.wav",
{ "models/weapons2/laser_trap/laser_trap_w.glm", { "models/weapons2/laser_trap/laser_trap_w.glm", "models/weapons2/laser_trap/laser_trap_pu.md3",
0, 0, 0}, 0, 0},
/* view */ "models/weapons2/laser_trap/laser_trap.md3", /* view */ "models/weapons2/laser_trap/laser_trap.md3",
/* icon */ "gfx/hud/w_icon_tripmine", /* icon */ "gfx/hud/w_icon_tripmine",
/* pickup */ "Trip Mine", /* pickup */// "Trip Mine",
1, 3,
IT_WEAPON, IT_WEAPON,
WP_TRIP_MINE, WP_TRIP_MINE,
/* precache */ "", /* precache */ "",
@ -629,11 +995,11 @@ NOTENOTE This weapon is not yet complete. Don't place it.
{ {
"weapon_det_pack", "weapon_det_pack",
"sound/weapons/w_pkup.wav", "sound/weapons/w_pkup.wav",
{ "models/weapons2/detpack/det_pack_proj.glm", "models/weapons2/detpack/det_pack_w.glm", 0, 0}, { "models/weapons2/detpack/det_pack_proj.glm", "models/weapons2/detpack/det_pack_pu.md3", "models/weapons2/detpack/det_pack_w.glm", 0},
/* view */ "models/weapons2/detpack/det_pack.md3", /* view */ "models/weapons2/detpack/det_pack.md3",
/* icon */ "gfx/hud/w_icon_detpack", /* icon */ "gfx/hud/w_icon_detpack",
/* pickup */ "Det Pack", /* pickup */// "Det Pack",
1, 3,
IT_WEAPON, IT_WEAPON,
WP_DET_PACK, WP_DET_PACK,
/* precache */ "", /* precache */ "",
@ -649,7 +1015,7 @@ NOTENOTE This weapon is not yet complete. Don't place it.
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/blaster_r/blaster.md3", /* view */ "models/weapons2/blaster_r/blaster.md3",
/* icon */ "gfx/hud/w_icon_blaster", /* icon */ "gfx/hud/w_icon_blaster",
/* pickup */ "Emplaced Gun", /* pickup */// "Emplaced Gun",
50, 50,
IT_WEAPON, IT_WEAPON,
WP_EMPLACED_GUN, WP_EMPLACED_GUN,
@ -666,7 +1032,7 @@ NOTENOTE This weapon is not yet complete. Don't place it.
0, 0, 0}, 0, 0, 0},
/* view */ "models/weapons2/blaster_r/blaster.md3", /* view */ "models/weapons2/blaster_r/blaster.md3",
/* icon */ "gfx/hud/w_icon_blaster", /* icon */ "gfx/hud/w_icon_blaster",
/* pickup */ "Turret Gun", /* pickup */// "Turret Gun",
50, 50,
IT_WEAPON, IT_WEAPON,
WP_TURRET, WP_TURRET,
@ -688,7 +1054,7 @@ Don't place this
0, 0, 0}, 0, 0, 0},
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/w_icon_blaster", /* icon */ "gfx/hud/w_icon_blaster",
/* pickup */ "Force??", /* pickup */// "Force??",
100, 100,
IT_AMMO, IT_AMMO,
AMMO_FORCE, AMMO_FORCE,
@ -706,7 +1072,7 @@ Ammo for the Bryar and Blaster pistols.
0, 0, 0}, 0, 0, 0},
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/i_icon_battery", /* icon */ "gfx/hud/i_icon_battery",
/* pickup */ "Blaster Pack", /* pickup */// "Blaster Pack",
100, 100,
IT_AMMO, IT_AMMO,
AMMO_BLASTER, AMMO_BLASTER,
@ -724,7 +1090,7 @@ Ammo for Tenloss Disruptor, Wookie Bowcaster, and the Destructive Electro Magnet
0, 0, 0}, 0, 0, 0},
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/mp/ammo_power_cell", /* icon */ "gfx/mp/ammo_power_cell",
/* pickup */ "Power Cell", /* pickup */// "Power Cell",
100, 100,
IT_AMMO, IT_AMMO,
AMMO_POWERCELL, AMMO_POWERCELL,
@ -742,7 +1108,7 @@ Ammo for Imperial Heavy Repeater and the Golan Arms Flechette
0, 0, 0}, 0, 0, 0},
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/mp/ammo_metallic_bolts", /* icon */ "gfx/mp/ammo_metallic_bolts",
/* pickup */ "Metallic Bolts", /* pickup */// "Metallic Bolts",
100, 100,
IT_AMMO, IT_AMMO,
AMMO_METAL_BOLTS, AMMO_METAL_BOLTS,
@ -760,8 +1126,8 @@ Ammo for Merr-Sonn portable missile launcher
0, 0, 0}, 0, 0, 0},
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/mp/ammo_rockets", /* icon */ "gfx/mp/ammo_rockets",
/* pickup */ "Rockets", /* pickup */// "Rockets",
100, 3,
IT_AMMO, IT_AMMO,
AMMO_ROCKETS, AMMO_ROCKETS,
/* precache */ "", /* precache */ "",
@ -782,7 +1148,7 @@ Only in CTF games
"models/flags/r_flag_ysal.md3", 0, 0 }, "models/flags/r_flag_ysal.md3", 0, 0 },
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/mpi_rflag", /* icon */ "gfx/hud/mpi_rflag",
/* pickup */ "Red Flag", /* pickup */// "Red Flag",
0, 0,
IT_TEAM, IT_TEAM,
PW_REDFLAG, PW_REDFLAG,
@ -800,7 +1166,7 @@ Only in CTF games
"models/flags/b_flag_ysal.md3", 0, 0 }, "models/flags/b_flag_ysal.md3", 0, 0 },
/* view */ NULL, /* view */ NULL,
/* icon */ "gfx/hud/mpi_bflag", /* icon */ "gfx/hud/mpi_bflag",
/* pickup */ "Blue Flag", /* pickup */// "Blue Flag",
0, 0,
IT_TEAM, IT_TEAM,
PW_BLUEFLAG, PW_BLUEFLAG,
@ -822,7 +1188,7 @@ Only in One Flag CTF games
0, 0, 0 }, 0, 0, 0 },
/* view */ NULL, /* view */ NULL,
/* icon */ "icons/iconf_neutral1", /* icon */ "icons/iconf_neutral1",
/* pickup */ "Neutral Flag", /* pickup */// "Neutral Flag",
0, 0,
IT_TEAM, IT_TEAM,
PW_NEUTRALFLAG, PW_NEUTRALFLAG,
@ -837,7 +1203,7 @@ Only in One Flag CTF games
0, 0, 0 }, 0, 0, 0 },
/* view */ NULL, /* view */ NULL,
/* icon */ "icons/iconh_rorb", /* icon */ "icons/iconh_rorb",
/* pickup */ "Red Cube", /* pickup */// "Red Cube",
0, 0,
IT_TEAM, IT_TEAM,
0, 0,
@ -852,7 +1218,7 @@ Only in One Flag CTF games
0, 0, 0 }, 0, 0, 0 },
/* view */ NULL, /* view */ NULL,
/* icon */ "icons/iconh_borb", /* icon */ "icons/iconh_borb",
/* pickup */ "Blue Cube", /* pickup */// "Blue Cube",
0, 0,
IT_TEAM, IT_TEAM,
0, 0,
@ -866,7 +1232,28 @@ Only in One Flag CTF games
int bg_numItems = sizeof(bg_itemlist) / sizeof(bg_itemlist[0]) - 1; int bg_numItems = sizeof(bg_itemlist) / sizeof(bg_itemlist[0]) - 1;
qboolean BG_HasYsalimari(int gametype, playerState_t *ps) 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;
}
qboolean BG_HasYsalamiri(int gametype, playerState_t *ps)
{ {
if (gametype == GT_CTY && if (gametype == GT_CTY &&
(ps->powerups[PW_REDFLAG] || ps->powerups[PW_BLUEFLAG])) (ps->powerups[PW_REDFLAG] || ps->powerups[PW_BLUEFLAG]))
@ -874,7 +1261,7 @@ qboolean BG_HasYsalimari(int gametype, playerState_t *ps)
return qtrue; return qtrue;
} }
if (ps->powerups[PW_YSALIMARI]) if (ps->powerups[PW_YSALAMIRI])
{ {
return qtrue; return qtrue;
} }
@ -884,7 +1271,7 @@ qboolean BG_HasYsalimari(int gametype, playerState_t *ps)
qboolean BG_CanUseFPNow(int gametype, playerState_t *ps, int time, forcePowers_t power) qboolean BG_CanUseFPNow(int gametype, playerState_t *ps, int time, forcePowers_t power)
{ {
if (BG_HasYsalimari(gametype, ps)) if (BG_HasYsalamiri(gametype, ps))
{ {
return qfalse; return qfalse;
} }
@ -982,11 +1369,11 @@ BG_FindItem
=============== ===============
*/ */
gitem_t *BG_FindItem( const char *pickupName ) { gitem_t *BG_FindItem( const char *classname ) {
gitem_t *it; gitem_t *it;
for ( it = bg_itemlist + 1 ; it->classname ; it++ ) { for ( it = bg_itemlist + 1 ; it->classname ; it++ ) {
if ( !Q_stricmp( it->pickup_name, pickupName ) ) if ( !Q_stricmp( it->classname, classname) )
return it; return it;
} }
@ -1210,6 +1597,11 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
{ {
return qfalse; return qfalse;
} }
if (!(ent->eFlags & EF_DROPPEDWEAPON) && (ps->stats[STAT_WEAPONS] & (1 << item->giTag)) &&
item->giTag != WP_THERMAL && item->giTag != WP_TRIP_MINE && item->giTag != WP_DET_PACK)
{ //weaponstay stuff.. if this isn't dropped, and you already have it, you don't get it.
return qfalse;
}
return qtrue; // weapons are always picked up return qtrue; // weapons are always picked up
case IT_AMMO: case IT_AMMO:
@ -1245,6 +1637,13 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
return qtrue; return qtrue;
case IT_POWERUP: case IT_POWERUP:
if (ps && (ps->powerups[PW_YSALAMIRI]))
{
if (item->giTag != PW_YSALAMIRI)
{
return qfalse;
}
}
return qtrue; // powerups are always picked up return qtrue; // powerups are always picked up
case IT_TEAM: // team items, such as flags case IT_TEAM: // team items, such as flags
@ -1330,7 +1729,11 @@ void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result )
result[2] -= 0.5 * DEFAULT_GRAVITY * deltaTime * deltaTime; // FIXME: local gravity... result[2] -= 0.5 * DEFAULT_GRAVITY * deltaTime * deltaTime; // FIXME: local gravity...
break; break;
default: default:
Com_Error( ERR_DROP, "BG_EvaluateTrajectory: unknown trType: %i", tr->trTime ); #ifdef QAGAME
Com_Error( ERR_DROP, "BG_EvaluateTrajectory: [GAME SIDE] unknown trType: %i", tr->trType );
#else
Com_Error( ERR_DROP, "BG_EvaluateTrajectory: [CLIENTGAME SIDE] unknown trType: %i", tr->trType );
#endif
break; break;
} }
} }
@ -1425,6 +1828,12 @@ char *eventnames[] = {
"EV_DISRUPTOR_HIT", "EV_DISRUPTOR_HIT",
"EV_DISRUPTOR_ZOOMSOUND", "EV_DISRUPTOR_ZOOMSOUND",
"EV_PREDEFSOUND",
"EV_TEAM_POWER",
"EV_SCREENSHAKE",
"EV_USE", // +Use key "EV_USE", // +Use key
"EV_USE_ITEM0", "EV_USE_ITEM0",
@ -1452,6 +1861,7 @@ char *eventnames[] = {
"EV_PLAYER_TELEPORT_OUT", "EV_PLAYER_TELEPORT_OUT",
"EV_GRENADE_BOUNCE", // eventParm will be the soundindex "EV_GRENADE_BOUNCE", // eventParm will be the soundindex
"EV_MISSILE_STICK",
"EV_PLAY_EFFECT", "EV_PLAY_EFFECT",
"EV_PLAY_EFFECT_ID", //finally gave in and added it.. "EV_PLAY_EFFECT_ID", //finally gave in and added it..
@ -1498,6 +1908,7 @@ char *eventnames[] = {
"EV_GIVE_NEW_RANK", "EV_GIVE_NEW_RANK",
"EV_SET_FREE_SABER", "EV_SET_FREE_SABER",
"EV_SET_FORCE_DISABLE",
"EV_WEAPON_CHARGE", "EV_WEAPON_CHARGE",
"EV_WEAPON_CHARGE_ALT", "EV_WEAPON_CHARGE_ALT",
@ -1508,7 +1919,16 @@ char *eventnames[] = {
"EV_TESTLINE", "EV_TESTLINE",
"EV_STOPLOOPINGSOUND", "EV_STOPLOOPINGSOUND",
"EV_STARTLOOPINGSOUND", "EV_STARTLOOPINGSOUND",
"EV_TAUNT" "EV_TAUNT",
"EV_TAUNT_YES",
"EV_TAUNT_NO",
"EV_TAUNT_FOLLOWME",
"EV_TAUNT_GETFLAG",
"EV_TAUNT_GUARDBASE",
"EV_TAUNT_PATROL",
"EV_BODY_QUEUE_COPY"
}; };

View file

@ -659,6 +659,20 @@ qboolean BG_ParseAnimationFile(const char *filename)
bgGlobalAnimations[animNum].initialLerp = ceil(1000.0f / fabs(fps)); bgGlobalAnimations[animNum].initialLerp = ceil(1000.0f / fabs(fps));
} }
#ifdef _DEBUG
//Check the array, and print the ones that have nothing in them.
for(i = 0; i < MAX_ANIMATIONS; i++)
{
if (animTable[i].name != NULL) // This animation reference exists.
{
if (bgGlobalAnimations[i].firstFrame <= 0 && bgGlobalAnimations[i].numFrames <=0)
{ // This is an empty animation reference.
Com_Printf("***ANIMTABLE reference #%d (%s) is empty!\n", i, animTable[i].name);
}
}
}
#endif // _DEBUG
BGPAFtextLoaded = qtrue; BGPAFtextLoaded = qtrue;
return qtrue; return qtrue;
} }
@ -754,16 +768,6 @@ void PM_StartTorsoAnim( int anim ) {
| anim; | anim;
} }
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);
}
/* /*
------------------------- -------------------------
@ -955,6 +959,9 @@ setAnimDone:
// Imported from single-player, this function is mainly intended to make porting from SP easier. // Imported from single-player, this function is mainly intended to make porting from SP easier.
void PM_SetAnim(int setAnimParts,int anim,int setAnimFlags, int blendTime) void PM_SetAnim(int setAnimParts,int anim,int setAnimFlags, int blendTime)
{ {
assert( bgGlobalAnimations[anim].firstFrame != 0 ||
bgGlobalAnimations[anim].numFrames != 0);
if (BG_InSpecialJump(anim)) if (BG_InSpecialJump(anim))
{ {
setAnimFlags |= SETANIM_FLAG_RESTART; setAnimFlags |= SETANIM_FLAG_RESTART;

View file

@ -12,6 +12,8 @@
pmove_t *pm; pmove_t *pm;
pml_t pml; pml_t pml;
qboolean gPMDoSlowFall = qfalse;
// movement parameters // movement parameters
float pm_stopspeed = 100.0f; float pm_stopspeed = 100.0f;
float pm_duckScale = 0.50f; float pm_duckScale = 0.50f;
@ -100,7 +102,7 @@ int forcePowerNeeded[NUM_FORCE_POWER_LEVELS][NUM_FORCE_POWERS] =
20,//FP_SEE,//duration 20,//FP_SEE,//duration
0,//FP_SABERATTACK, 0,//FP_SABERATTACK,
1,//FP_SABERDEFEND, 1,//FP_SABERDEFEND,
10//FP_SABERTHROW, 20//FP_SABERTHROW,
//NUM_FORCE_POWERS //NUM_FORCE_POWERS
}, },
{ {
@ -110,7 +112,7 @@ int forcePowerNeeded[NUM_FORCE_POWER_LEVELS][NUM_FORCE_POWERS] =
20,//FP_PUSH,//hold/duration 20,//FP_PUSH,//hold/duration
20,//FP_PULL,//hold/duration 20,//FP_PULL,//hold/duration
20,//FP_TELEPATHY,//instant 20,//FP_TELEPATHY,//instant
30,//FP_GRIP,//hold/duration 60,//FP_GRIP,//hold/duration
1,//FP_LIGHTNING,//hold/duration 1,//FP_LIGHTNING,//hold/duration
50,//FP_RAGE,//duration 50,//FP_RAGE,//duration
10,//FP_PROTECT,//duration 10,//FP_PROTECT,//duration
@ -121,7 +123,7 @@ int forcePowerNeeded[NUM_FORCE_POWER_LEVELS][NUM_FORCE_POWERS] =
20,//FP_SEE,//duration 20,//FP_SEE,//duration
0,//FP_SABERATTACK, 0,//FP_SABERATTACK,
0,//FP_SABERDEFEND, 0,//FP_SABERDEFEND,
5//FP_SABERTHROW, 20//FP_SABERTHROW,
//NUM_FORCE_POWERS //NUM_FORCE_POWERS
} }
}; };
@ -157,6 +159,16 @@ int PM_GetSaberStance(void)
return BOTH_SABERFAST_STANCE; return BOTH_SABERFAST_STANCE;
} }
qboolean PM_DoSlowFall(void)
{
if ( ( (pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_RIGHT || (pm->ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_LEFT ) && pm->ps->legsTimer > 500 )
{
return qtrue;
}
return qfalse;
}
/* /*
=============== ===============
PM_AddEvent PM_AddEvent
@ -444,7 +456,7 @@ qboolean PM_ForceJumpingUp(void)
return qfalse; return qfalse;
} }
if (BG_HasYsalimari(pm->gametype, pm->ps)) if (BG_HasYsalamiri(pm->gametype, pm->ps))
{ {
return qfalse; return qfalse;
} }
@ -498,6 +510,117 @@ static void PM_JumpForDir( void )
} }
} }
void PM_SetPMViewAngle(playerState_t *ps, vec3_t angle, usercmd_t *ucmd)
{
int i;
// set the delta angle
for (i=0 ; i<3 ; i++) {
int cmdAngle;
cmdAngle = ANGLE2SHORT(angle[i]);
ps->delta_angles[i] = cmdAngle - ucmd->angles[i];
}
//VectorCopy( angle, ent->s.angles );
VectorCopy (angle, ps->viewangles);
}
qboolean PM_AdjustAngleForWallRun( playerState_t *ps, usercmd_t *ucmd, qboolean doMove )
{
if (( (ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_RIGHT || (ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_LEFT ) && ps->legsTimer > 500 )
{//wall-running and not at end of anim
//stick to wall, if there is one
vec3_t rt, traceTo, mins, maxs, fwdAngles;
trace_t trace;
float dist, yawAdjust;
VectorSet(mins, -15, -15, 0);
VectorSet(maxs, 15, 15, 24);
VectorSet(fwdAngles, 0, pm->ps->viewangles[YAW], 0);
AngleVectors( fwdAngles, NULL, rt, NULL );
if ( (ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_RIGHT )
{
dist = 128;
yawAdjust = -90;
}
else
{
dist = -128;
yawAdjust = 90;
}
VectorMA( ps->origin, dist, rt, traceTo );
pm->trace( &trace, ps->origin, mins, maxs, traceTo, ps->clientNum, MASK_PLAYERSOLID );
if ( trace.fraction < 1.0f )
{//still a wall there
//FIXME: don't pull around 90 turns
//FIXME: simulate stepping up steps here, somehow?
if ( (ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_RIGHT )
{
ucmd->rightmove = 127;
}
else
{
ucmd->rightmove = -127;
}
if ( ucmd->upmove < 0 )
{
ucmd->upmove = 0;
}
//make me face perpendicular to the wall
ps->viewangles[YAW] = vectoyaw( trace.plane.normal )+yawAdjust;
//SetClientViewAngle( ent, ent->client->ps.viewangles );
PM_SetPMViewAngle(ps, ps->viewangles, ucmd);
ucmd->angles[YAW] = ANGLE2SHORT( ps->viewangles[YAW] ) - ps->delta_angles[YAW];
if ( doMove )
{
//push me forward
vec3_t fwd;
float zVel = ps->velocity[2];
if ( ps->legsTimer > 500 )
{//not at end of anim yet
float speed = 175;
fwdAngles[YAW] = ps->viewangles[YAW];
AngleVectors( fwdAngles, fwd, NULL, NULL );
//FIXME: or MA?
if ( ucmd->forwardmove < 0 )
{//slower
speed = 100;
}
else if ( ucmd->forwardmove > 0 )
{
speed = 250;//running speed
}
VectorScale( fwd, speed, ps->velocity );
}
ps->velocity[2] = zVel;//preserve z velocity
//pull me toward the wall, too
VectorMA( ps->velocity, dist, rt, ps->velocity );
}
ucmd->forwardmove = 0;
return qtrue;
}
else if ( doMove )
{//stop it
if ( (ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_RIGHT )
{
PM_SetAnim(SETANIM_BOTH, BOTH_WALL_RUN_RIGHT_STOP, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
}
else if ( (ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_WALL_RUN_LEFT )
{
PM_SetAnim(SETANIM_BOTH, BOTH_WALL_RUN_LEFT_STOP, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
}
}
}
return qfalse;
}
/* /*
============= =============
PM_CheckJump PM_CheckJump
@ -606,7 +729,6 @@ static qboolean PM_CheckJump( void )
{ {
//start force jump //start force jump
pm->ps->fd.forcePowersActive |= (1<<FP_LEVITATION); pm->ps->fd.forcePowersActive |= (1<<FP_LEVITATION);
// G_SoundOnEnt( pm->gent, CHAN_BODY, "sound/weapons/force/jump.wav" );
pm->ps->fd.forceJumpSound = 1; pm->ps->fd.forceJumpSound = 1;
//play flip //play flip
//FIXME: do this only when they stop the jump (below) or when they're just about to hit the peak of the jump //FIXME: do this only when they stop the jump (below) or when they're just about to hit the peak of the jump
@ -788,7 +910,7 @@ static qboolean PM_CheckJump( void )
{ {
VectorMA( pm->ps->velocity, JUMP_VELOCITY*2, forward, pm->ps->velocity ); VectorMA( pm->ps->velocity, JUMP_VELOCITY*2, forward, pm->ps->velocity );
//FIXME: kicking off wall anim? At least check what anim we're in? //FIXME: kicking off wall anim? At least check what anim we're in?
PM_SetAnim(SETANIM_LEGS,BOTH_SWIMFORWARDSTART,SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART, 150); PM_SetAnim(SETANIM_LEGS,BOTH_FORCEJUMP1,SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD|SETANIM_FLAG_RESTART, 150);
}//else no surf close enough to push off of }//else no surf close enough to push off of
pm->cmd.upmove = 0; pm->cmd.upmove = 0;
} }
@ -797,7 +919,7 @@ static qboolean PM_CheckJump( void )
!(pm->ps->pm_flags&PMF_JUMP_HELD) /*&& !(pm->ps->pm_flags&PMF_JUMP_HELD) /*&&
WP_ForcePowerAvailable( pm->gent, FP_LEVITATION, 0 ) */ && WP_ForcePowerAvailable( pm->gent, FP_LEVITATION, 0 ) */ &&
pm->ps->weapon == WP_SABER && pm->ps->weapon == WP_SABER &&
!BG_HasYsalimari(pm->gametype, pm->ps) && !BG_HasYsalamiri(pm->gametype, pm->ps) &&
BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_LEVITATION) BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_LEVITATION)
) )
{ {
@ -985,7 +1107,6 @@ static qboolean PM_CheckJump( void )
pm->ps->fd.forceJumpZStart = pm->ps->origin[2];//so we don't take damage if we land at same height pm->ps->fd.forceJumpZStart = pm->ps->origin[2];//so we don't take damage if we land at same height
pm->ps->pm_flags |= PMF_JUMP_HELD;//PMF_JUMPING|PMF_SLOW_MO_FALL; pm->ps->pm_flags |= PMF_JUMP_HELD;//PMF_JUMPING|PMF_SLOW_MO_FALL;
pm->cmd.upmove = 0; pm->cmd.upmove = 0;
//G_SoundOnEnt( pm->gent, CHAN_BODY, "sound/weapons/force/jump.wav" );
//WP_ForcePowerDrain( pm->gent, FP_LEVITATION, 0 ); //WP_ForcePowerDrain( pm->gent, FP_LEVITATION, 0 );
pm->ps->fd.forceJumpSound = 1; pm->ps->fd.forceJumpSound = 1;
} }
@ -996,13 +1117,12 @@ static qboolean PM_CheckJump( void )
int legsAnim = (pm->ps->legsAnim&~ANIM_TOGGLEBIT); int legsAnim = (pm->ps->legsAnim&~ANIM_TOGGLEBIT);
if ( legsAnim == BOTH_WALL_RUN_LEFT || legsAnim == BOTH_WALL_RUN_RIGHT ) if ( legsAnim == BOTH_WALL_RUN_LEFT || legsAnim == BOTH_WALL_RUN_RIGHT )
{//running on a wall {//running on a wall
//FIXME: if already in a wall run, keep checking for a wall surf... maybe kick people?
vec3_t right, traceto, mins, maxs, fwdAngles; vec3_t right, traceto, mins, maxs, fwdAngles;
trace_t trace; trace_t trace;
int anim = -1; int anim = -1;
VectorSet(mins, pm->mins[0],pm->mins[0],0); VectorSet(mins, pm->mins[0], pm->mins[0], 0);
VectorSet(maxs, pm->maxs[0],pm->maxs[0],24); VectorSet(maxs, pm->maxs[0], pm->maxs[0], 24);
VectorSet(fwdAngles, 0, pm->ps->viewangles[YAW], 0); VectorSet(fwdAngles, 0, pm->ps->viewangles[YAW], 0);
AngleVectors( fwdAngles, NULL, right, NULL ); AngleVectors( fwdAngles, NULL, right, NULL );
@ -1011,7 +1131,7 @@ static qboolean PM_CheckJump( void )
{ {
if ( pm->ps->legsTimer > 400 ) if ( pm->ps->legsTimer > 400 )
{//not at the end of the anim {//not at the end of the anim
float animLen = PM_AnimLength( 0, BOTH_WALL_RUN_LEFT ); float animLen = PM_AnimLength( 0, (animNumber_t)BOTH_WALL_RUN_LEFT );
if ( pm->ps->legsTimer < animLen - 400 ) if ( pm->ps->legsTimer < animLen - 400 )
{//not at start of anim {//not at start of anim
VectorMA( pm->ps->origin, -16, right, traceto ); VectorMA( pm->ps->origin, -16, right, traceto );
@ -1023,7 +1143,7 @@ static qboolean PM_CheckJump( void )
{ {
if ( pm->ps->legsTimer > 400 ) if ( pm->ps->legsTimer > 400 )
{//not at the end of the anim {//not at the end of the anim
float animLen = PM_AnimLength( 0, BOTH_WALL_RUN_RIGHT ); float animLen = PM_AnimLength( 0, (animNumber_t)BOTH_WALL_RUN_RIGHT );
if ( pm->ps->legsTimer < animLen - 400 ) if ( pm->ps->legsTimer < animLen - 400 )
{//not at start of anim {//not at start of anim
VectorMA( pm->ps->origin, 16, right, traceto ); VectorMA( pm->ps->origin, 16, right, traceto );
@ -1033,11 +1153,11 @@ static qboolean PM_CheckJump( void )
} }
if ( anim != -1 ) if ( anim != -1 )
{ {
int parts;
pm->trace( &trace, pm->ps->origin, mins, maxs, traceto, pm->ps->clientNum, CONTENTS_SOLID|CONTENTS_BODY ); pm->trace( &trace, pm->ps->origin, mins, maxs, traceto, pm->ps->clientNum, CONTENTS_SOLID|CONTENTS_BODY );
if ( trace.fraction < 1.0f ) if ( trace.fraction < 1.0f )
{//flip off wall {//flip off wall
int parts = 0;
if ( anim == BOTH_WALL_RUN_LEFT_FLIP ) if ( anim == BOTH_WALL_RUN_LEFT_FLIP )
{ {
pm->ps->velocity[0] *= 0.5f; pm->ps->velocity[0] *= 0.5f;
@ -1057,7 +1177,7 @@ static qboolean PM_CheckJump( void )
} }
PM_SetAnim( parts, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0 ); PM_SetAnim( parts, anim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0 );
//FIXME: do damage to traceEnt, like above? //FIXME: do damage to traceEnt, like above?
pm->ps->pm_flags |= PMF_JUMP_HELD;//PMF_JUMPING|PMF_SLOW_MO_FALL; //pm->ps->pm_flags |= PMF_JUMPING|PMF_SLOW_MO_FALL;
pm->cmd.upmove = 0; pm->cmd.upmove = 0;
} }
} }
@ -1395,10 +1515,18 @@ static void PM_AirMove( void ) {
VectorNormalize (pml.forward); VectorNormalize (pml.forward);
VectorNormalize (pml.right); VectorNormalize (pml.right);
for ( i = 0 ; i < 2 ; i++ ) { if ( gPMDoSlowFall )
wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove; {//no air-control
VectorClear( wishvel );
}
else
{
for ( i = 0 ; i < 2 ; i++ )
{
wishvel[i] = pml.forward[i]*fmove + pml.right[i]*smove;
}
wishvel[2] = 0;
} }
wishvel[2] = 0;
VectorCopy (wishvel, wishdir); VectorCopy (wishvel, wishdir);
wishspeed = VectorNormalize(wishdir); wishspeed = VectorNormalize(wishdir);
@ -1702,7 +1830,7 @@ static int PM_TryRoll( void )
return 0; return 0;
} }
if (pm->ps->weapon != WP_SABER || BG_HasYsalimari(pm->gametype, pm->ps) || if (pm->ps->weapon != WP_SABER || BG_HasYsalamiri(pm->gametype, pm->ps) ||
!BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_LEVITATION)) !BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_LEVITATION))
{ {
return 0; return 0;
@ -1810,10 +1938,30 @@ static void PM_CrashLand( void ) {
} }
} }
/*
if (pm->ps->forceHandExtend == HANDEXTEND_NONE) if (pm->ps->forceHandExtend == HANDEXTEND_NONE)
{ {
pm->ps->forceHandExtend = HANDEXTEND_WEAPONREADY; pm->ps->forceHandExtend = HANDEXTEND_WEAPONREADY;
} }
*/
if (pm->ps->weapon != WP_SABER)
{ //saber handles its own anims
if (pm->ps->weapon == WP_DISRUPTOR && pm->ps->zoomMode == 1)
{
PM_StartTorsoAnim( TORSO_WEAPONREADY4 );
}
else
{
if (pm->ps->weapon == WP_EMPLACED_GUN)
{
PM_StartTorsoAnim( BOTH_GUNSIT1 );
}
else
{
PM_StartTorsoAnim( WeaponReadyAnim[pm->ps->weapon] );
}
}
}
//just a stupid hack to push us back into our "idle" stance //just a stupid hack to push us back into our "idle" stance
if (!BG_InSpecialJump(pm->ps->legsAnim) || if (!BG_InSpecialJump(pm->ps->legsAnim) ||
@ -3058,7 +3206,8 @@ static void PM_Weapon( void ) {
{ //saber handles its own anims { //saber handles its own anims
if (pm->ps->weapon == WP_DISRUPTOR && pm->ps->zoomMode == 1) if (pm->ps->weapon == WP_DISRUPTOR && pm->ps->zoomMode == 1)
{ {
PM_StartTorsoAnim( TORSO_WEAPONREADY4 ); //PM_StartTorsoAnim( TORSO_WEAPONREADY4 );
PM_StartTorsoAnim( TORSO_RAISEWEAP1);
} }
else else
{ {
@ -3068,10 +3217,17 @@ static void PM_Weapon( void ) {
} }
else else
{ {
PM_StartTorsoAnim( WeaponReadyAnim[pm->ps->weapon] ); //PM_StartTorsoAnim( WeaponReadyAnim[pm->ps->weapon] );
PM_StartTorsoAnim( TORSO_RAISEWEAP1);
} }
} }
} }
//we now go into a weapon raise anim after every force hand extend.
//this is so that my holster-view-weapon-when-hand-extend stuff works.
pm->ps->weaponstate = WEAPON_RAISING;
pm->ps->weaponTime += 250;
pm->ps->forceHandExtend = HANDEXTEND_NONE; pm->ps->forceHandExtend = HANDEXTEND_NONE;
} }
else if (pm->ps->forceHandExtend != HANDEXTEND_NONE) else if (pm->ps->forceHandExtend != HANDEXTEND_NONE)
@ -3679,8 +3835,8 @@ void PM_AdjustAttackStates( pmove_t *pm )
// disruptor alt-fire should toggle the zoom mode, but only bother doing this for the player? // disruptor alt-fire should toggle the zoom mode, but only bother doing this for the player?
if ( pm->ps->weapon == WP_DISRUPTOR && pm->ps->weaponstate == WEAPON_READY ) if ( pm->ps->weapon == WP_DISRUPTOR && pm->ps->weaponstate == WEAPON_READY )
{ {
if ( !(pm->ps->eFlags & EF_ALT_FIRING) && (pm->cmd.buttons & BUTTON_ALT_ATTACK) && if ( !(pm->ps->eFlags & EF_ALT_FIRING) && (pm->cmd.buttons & BUTTON_ALT_ATTACK) /*&&
pm->cmd.upmove <= 0 && !pm->cmd.forwardmove && !pm->cmd.rightmove) pm->cmd.upmove <= 0 && !pm->cmd.forwardmove && !pm->cmd.rightmove*/)
{ {
// We just pressed the alt-fire key // We just pressed the alt-fire key
if ( !pm->ps->zoomMode ) if ( !pm->ps->zoomMode )
@ -3722,12 +3878,15 @@ void PM_AdjustAttackStates( pmove_t *pm )
pm->ps->zoomLocked = qtrue; pm->ps->zoomLocked = qtrue;
} }
} }
//This seemed like a good idea, but apparently it confuses people. So disabled for now.
/*
else if (!(pm->ps->eFlags & EF_ALT_FIRING) && (pm->cmd.buttons & BUTTON_ALT_ATTACK) && else if (!(pm->ps->eFlags & EF_ALT_FIRING) && (pm->cmd.buttons & BUTTON_ALT_ATTACK) &&
(pm->cmd.upmove > 0 || pm->cmd.forwardmove || pm->cmd.rightmove)) (pm->cmd.upmove > 0 || pm->cmd.forwardmove || pm->cmd.rightmove))
{ //if you try to zoom while moving, just convert it into a primary attack { //if you try to zoom while moving, just convert it into a primary attack
pm->cmd.buttons &= ~BUTTON_ALT_ATTACK; pm->cmd.buttons &= ~BUTTON_ALT_ATTACK;
pm->cmd.buttons |= BUTTON_ATTACK; pm->cmd.buttons |= BUTTON_ATTACK;
} }
*/
if (pm->cmd.upmove > 0 || pm->cmd.forwardmove || pm->cmd.rightmove) if (pm->cmd.upmove > 0 || pm->cmd.forwardmove || pm->cmd.rightmove)
{ {
@ -3756,6 +3915,19 @@ void PM_AdjustAttackStates( pmove_t *pm )
amount = 0; amount = 0;
} }
} }
else if (pm->ps->weapon == WP_DISRUPTOR) //still perform certain checks, even if the weapon is not ready
{
if (pm->cmd.upmove > 0 || pm->cmd.forwardmove || pm->cmd.rightmove)
{
if (pm->ps->zoomMode == 1 && pm->ps->zoomLockTime < pm->cmd.serverTime)
{ //check for == 1 so we can't turn binoculars off with disruptor alt fire
pm->ps->zoomMode = 0;
pm->ps->zoomTime = pm->ps->commandTime;
pm->ps->zoomLocked = qfalse;
PM_AddEvent(EV_DISRUPTOR_ZOOMSOUND);
}
}
}
/* /*
// set the firing flag for continuous beam weapons // set the firing flag for continuous beam weapons
@ -3812,12 +3984,17 @@ void PM_AdjustAttackStates( pmove_t *pm )
// disruptor should convert a main fire to an alt-fire if the gun is currently zoomed // disruptor should convert a main fire to an alt-fire if the gun is currently zoomed
if ( pm->ps->weapon == WP_DISRUPTOR) if ( pm->ps->weapon == WP_DISRUPTOR)
{ {
if ( pm->cmd.buttons & BUTTON_ATTACK && pm->ps->zoomMode == 1) if ( pm->cmd.buttons & BUTTON_ATTACK && pm->ps->zoomMode == 1 && pm->ps->zoomLocked)
{ {
// converting the main fire to an alt-fire // converting the main fire to an alt-fire
pm->cmd.buttons |= BUTTON_ALT_ATTACK; pm->cmd.buttons |= BUTTON_ALT_ATTACK;
pm->ps->eFlags |= EF_ALT_FIRING; pm->ps->eFlags |= EF_ALT_FIRING;
} }
else if ( pm->cmd.buttons & BUTTON_ALT_ATTACK && pm->ps->zoomMode == 1 && pm->ps->zoomLocked)
{
pm->cmd.buttons &= ~BUTTON_ALT_ATTACK;
pm->ps->eFlags &= ~EF_ALT_FIRING;
}
} }
} }
@ -4004,7 +4181,14 @@ void BG_AdjustClientSpeed(playerState_t *ps, usercmd_t *cmd, int svTime)
if ( BG_InRoll( ps, ps->legsAnim ) && ps->speed > 200 ) if ( BG_InRoll( ps, ps->legsAnim ) && ps->speed > 200 )
{ //can't roll unless you're able to move normally { //can't roll unless you're able to move normally
BG_CmdForRoll( ps->legsAnim, cmd ); BG_CmdForRoll( ps->legsAnim, cmd );
ps->speed = ps->legsTimer/1.5;//450; if ((ps->legsAnim&~ANIM_TOGGLEBIT) == BOTH_ROLL_B)
{ //backwards roll is pretty fast, should also be slower
ps->speed = ps->legsTimer/2.5;
}
else
{
ps->speed = ps->legsTimer/1.5;//450;
}
if (ps->speed > 600) if (ps->speed > 600)
{ {
ps->speed = 600; ps->speed = 600;
@ -4024,6 +4208,8 @@ void trap_SnapVector( float *v );
void PmoveSingle (pmove_t *pmove) { void PmoveSingle (pmove_t *pmove) {
pm = pmove; pm = pmove;
gPMDoSlowFall = PM_DoSlowFall();
// this counter lets us debug movement problems with a journal // this counter lets us debug movement problems with a journal
// by setting a conditional breakpoint fot the previous frame // by setting a conditional breakpoint fot the previous frame
c_pmove++; c_pmove++;
@ -4157,6 +4343,8 @@ void PmoveSingle (pmove_t *pmove) {
pml.frametime = pml.msec * 0.001; pml.frametime = pml.msec * 0.001;
PM_AdjustAngleForWallRun(pm->ps, &pm->cmd, qtrue);
// update the viewangles // update the viewangles
PM_UpdateViewAngles( pm->ps, &pm->cmd ); PM_UpdateViewAngles( pm->ps, &pm->cmd );
@ -4208,6 +4396,11 @@ void PmoveSingle (pmove_t *pmove) {
return; // no movement at all return; // no movement at all
} }
if (gPMDoSlowFall)
{
pm->ps->gravity *= 0.5;
}
// set watertype, and waterlevel // set watertype, and waterlevel
PM_SetWaterLevel(); PM_SetWaterLevel();
pml.previous_waterlevel = pmove->waterlevel; pml.previous_waterlevel = pmove->waterlevel;
@ -4282,6 +4475,11 @@ void PmoveSingle (pmove_t *pmove) {
// snap some parts of playerstate to save network bandwidth // snap some parts of playerstate to save network bandwidth
trap_SnapVector( pm->ps->velocity ); trap_SnapVector( pm->ps->velocity );
if (gPMDoSlowFall)
{
pm->ps->gravity *= 2;
}
} }

View file

@ -40,6 +40,8 @@
#define CROUCH_VIEWHEIGHT (CROUCH_MAXS_2+STANDARD_VIEWHEIGHT_OFFSET)//12 #define CROUCH_VIEWHEIGHT (CROUCH_MAXS_2+STANDARD_VIEWHEIGHT_OFFSET)//12
#define DEAD_VIEWHEIGHT -16 #define DEAD_VIEWHEIGHT -16
#define MAX_CLIENT_SCORE_SEND 20
// //
// config strings are a general means of communicating variable length strings // config strings are a general means of communicating variable length strings
// from the server to all connected clients. // from the server to all connected clients.
@ -72,6 +74,8 @@
#define CS_ITEMS 27 // string of 0's and 1's that tell which items are present #define CS_ITEMS 27 // string of 0's and 1's that tell which items are present
#define CS_CLIENT_JEDIMASTER 28 // current jedi master #define CS_CLIENT_JEDIMASTER 28 // current jedi master
#define CS_CLIENT_DUELWINNER 29 // current duel round winner - needed for printing at top of scoreboard
#define CS_CLIENT_DUELISTS 30 // client numbers for both current duelists. Needed for a number of client-side things.
// these are also in be_aas_def.h - argh (rjr) // these are also in be_aas_def.h - argh (rjr)
#define CS_MODELS 32 #define CS_MODELS 32
@ -199,16 +203,18 @@ typedef enum {
FORCE_MASTERY_UNINITIATED, FORCE_MASTERY_UNINITIATED,
FORCE_MASTERY_INITIATE, FORCE_MASTERY_INITIATE,
FORCE_MASTERY_PADAWAN, FORCE_MASTERY_PADAWAN,
FORCE_MASTERY_DISCIPLE,
FORCE_MASTERY_JEDI, FORCE_MASTERY_JEDI,
FORCE_MASTERY_JEDI_GUARDIAN,
FORCE_MASTERY_JEDI_ADEPT, FORCE_MASTERY_JEDI_ADEPT,
FORCE_MASTERY_JEDI_KNIGHT,
FORCE_MASTERY_JEDI_MASTER, FORCE_MASTERY_JEDI_MASTER,
FORCE_MASTERY_JEDI_LORD,
NUM_FORCE_MASTERY_LEVELS NUM_FORCE_MASTERY_LEVELS
}; };
extern char *forceMasteryLevels[NUM_FORCE_MASTERY_LEVELS]; extern char *forceMasteryLevels[NUM_FORCE_MASTERY_LEVELS];
extern int forceMasteryPoints[NUM_FORCE_MASTERY_LEVELS]; extern int forceMasteryPoints[NUM_FORCE_MASTERY_LEVELS];
extern int bgForcePowerCost[NUM_FORCE_POWERS][NUM_FORCE_POWER_LEVELS];
// pmove->pm_flags // pmove->pm_flags
#define PMF_DUCKED 1 #define PMF_DUCKED 1
#define PMF_JUMP_HELD 2 #define PMF_JUMP_HELD 2
@ -404,7 +410,7 @@ typedef enum {
PW_FORCE_ENLIGHTENED_LIGHT, PW_FORCE_ENLIGHTENED_LIGHT,
PW_FORCE_ENLIGHTENED_DARK, PW_FORCE_ENLIGHTENED_DARK,
PW_FORCE_BOON, PW_FORCE_BOON,
PW_YSALIMARI, PW_YSALAMIRI,
PW_NUM_POWERUPS PW_NUM_POWERUPS
@ -451,6 +457,17 @@ typedef enum {
#define EVENT_VALID_MSEC 300 #define EVENT_VALID_MSEC 300
typedef enum
{
PDSOUND_NONE,
PDSOUND_PROTECTHIT,
PDSOUND_PROTECT,
PDSOUND_ABSORBHIT,
PDSOUND_ABSORB,
PDSOUND_FORCEJUMP,
PDSOUND_FORCEGRIP
} pdSounds_t;
typedef enum { typedef enum {
EV_NONE, EV_NONE,
@ -498,6 +515,10 @@ typedef enum {
EV_DISRUPTOR_HIT, EV_DISRUPTOR_HIT,
EV_DISRUPTOR_ZOOMSOUND, EV_DISRUPTOR_ZOOMSOUND,
EV_PREDEFSOUND,
EV_TEAM_POWER,
EV_SCREENSHAKE, EV_SCREENSHAKE,
EV_USE, // +Use key EV_USE, // +Use key
@ -574,6 +595,7 @@ typedef enum {
EV_GIVE_NEW_RANK, EV_GIVE_NEW_RANK,
EV_SET_FREE_SABER, EV_SET_FREE_SABER,
EV_SET_FORCE_DISABLE,
EV_WEAPON_CHARGE, EV_WEAPON_CHARGE,
EV_WEAPON_CHARGE_ALT, EV_WEAPON_CHARGE_ALT,
@ -710,7 +732,7 @@ typedef struct gitem_s {
char *view_model; char *view_model;
char *icon; char *icon;
char *pickup_name; // for printing on pickup // char *pickup_name; // for printing on pickup
int quantity; // for ammo how much, or duration of powerup int quantity; // for ammo how much, or duration of powerup
itemType_t giType; // IT_* flags itemType_t giType; // IT_* flags
@ -725,7 +747,9 @@ typedef struct gitem_s {
extern gitem_t bg_itemlist[]; extern gitem_t bg_itemlist[];
extern int bg_numItems; extern int bg_numItems;
gitem_t *BG_FindItem( const char *pickupName ); float vectoyaw( const vec3_t vec );
gitem_t *BG_FindItem( const char *classname );
gitem_t *BG_FindItemForWeapon( weapon_t weapon ); gitem_t *BG_FindItemForWeapon( weapon_t weapon );
gitem_t *BG_FindItemForPowerup( powerup_t pw ); gitem_t *BG_FindItemForPowerup( powerup_t pw );
gitem_t *BG_FindItemForHoldable( holdable_t pw ); gitem_t *BG_FindItemForHoldable( holdable_t pw );
@ -964,6 +988,8 @@ typedef struct
extern saberMoveData_t saberMoveData[LS_MOVE_MAX]; extern saberMoveData_t saberMoveData[LS_MOVE_MAX];
qboolean BG_LegalizedForcePowers(char *powerOut, int maxRank, qboolean freeSaber, int teamForce, int gametype, int fpDisabled);
//BG anim utility functions: //BG anim utility functions:
qboolean BG_InSpecialJump( int anim ); qboolean BG_InSpecialJump( int anim );
qboolean BG_InSaberStandAnim( int anim ); qboolean BG_InSaberStandAnim( int anim );
@ -1000,7 +1026,7 @@ qboolean BG_ParseAnimationFile(const char *filename);
int BG_GetItemIndexByTag(int tag, int type); int BG_GetItemIndexByTag(int tag, int type);
qboolean BG_HasYsalimari(int gametype, playerState_t *ps); qboolean BG_HasYsalamiri(int gametype, playerState_t *ps);
qboolean BG_CanUseFPNow(int gametype, playerState_t *ps, int time, forcePowers_t power); qboolean BG_CanUseFPNow(int gametype, playerState_t *ps, int time, forcePowers_t power);
void *BG_Alloc ( int size ); void *BG_Alloc ( int size );

View file

@ -24,10 +24,12 @@ void BG_ForcePowerDrain( playerState_t *ps, forcePowers_t forcePower, int overri
//take away the power //take away the power
int drain = overrideAmt; int drain = overrideAmt;
/*
if (ps->powerups[PW_FORCE_BOON]) if (ps->powerups[PW_FORCE_BOON])
{ {
return; return;
} }
*/
if ( !drain ) if ( !drain )
{ {
@ -1229,7 +1231,7 @@ void PM_WeaponLightsaber(void)
pm->ps->weaponTime < 1 && pm->ps->weaponTime < 1 &&
pm->ps->saberCanThrow && pm->ps->saberCanThrow &&
pm->ps->fd.forcePower >= forcePowerNeeded[pm->ps->fd.forcePowerLevel[FP_SABERTHROW]][FP_SABERTHROW] && pm->ps->fd.forcePower >= forcePowerNeeded[pm->ps->fd.forcePowerLevel[FP_SABERTHROW]][FP_SABERTHROW] &&
!BG_HasYsalimari(pm->gametype, pm->ps) && !BG_HasYsalamiri(pm->gametype, pm->ps) &&
BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_SABERTHROW) BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_SABERTHROW)
) )
{ //might as well just check for a saber throw right here { //might as well just check for a saber throw right here
@ -1408,7 +1410,7 @@ void PM_WeaponLightsaber(void)
if (pm->ps->saberBlocked != BLOCKED_ATK_BOUNCE && pm->ps->saberBlocked != BLOCKED_PARRY_BROKEN && pm->ps->weaponTime < 1) if (pm->ps->saberBlocked != BLOCKED_ATK_BOUNCE && pm->ps->saberBlocked != BLOCKED_PARRY_BROKEN && pm->ps->weaponTime < 1)
{ {
pm->ps->torsoTimer = SABER_BLOCK_DUR*2; pm->ps->torsoTimer = SABER_BLOCK_DUR;
pm->ps->weaponTime = pm->ps->torsoTimer; pm->ps->weaponTime = pm->ps->torsoTimer;
} }
@ -1620,6 +1622,10 @@ weapChecks:
/* /*
if ( PM_HasAnimation( pm->gent, saberMoveData[newmove].animToUse ) ) if ( PM_HasAnimation( pm->gent, saberMoveData[newmove].animToUse ) )
*/ */
assert( bgGlobalAnimations[saberMoveData[newmove].animToUse].firstFrame != 0 ||
bgGlobalAnimations[saberMoveData[newmove].animToUse].numFrames != 0);
if (1) if (1)
{ {
anim = saberMoveData[newmove].animToUse; anim = saberMoveData[newmove].animToUse;
@ -1712,6 +1718,11 @@ void PM_SetSaberMove(short newMove)
pm->ps->saberAttackChainCount++; pm->ps->saberAttackChainCount++;
} }
if (pm->ps->saberAttackChainCount > 16)
{ //for the sake of being able to send the value over the net within a reasonable bit count
pm->ps->saberAttackChainCount = 16;
}
if ( pm->ps->fd.saberAnimLevel > FORCE_LEVEL_1 && if ( pm->ps->fd.saberAnimLevel > FORCE_LEVEL_1 &&
!BG_SaberInIdle( newMove ) && !PM_SaberInParry( newMove ) && !PM_SaberInReflect( newMove ) && !BG_SaberInSpecial(newMove)) !BG_SaberInIdle( newMove ) && !PM_SaberInParry( newMove ) && !PM_SaberInReflect( newMove ) && !BG_SaberInSpecial(newMove))
{//readies, parries and reflections have only 1 level {//readies, parries and reflections have only 1 level

View file

@ -52,7 +52,7 @@ weaponData_t weaponData[WP_NUM_WEAPONS] =
400, // int fireTime; // Amount of time between firings 400, // int fireTime; // Amount of time between firings
8192, // int range; // Range of weapon 8192, // int range; // Range of weapon
0, // int altEnergyPerShot; // Amount of energy used for alt-fire 0, // int altEnergyPerShot; // Amount of energy used for alt-fire
800, // int altFireTime; // Amount of time between alt-firings 400, // int altFireTime; // Amount of time between alt-firings
8192, // int altRange; // Range of alt-fire 8192, // int altRange; // Range of alt-fire
0, // int chargeSubTime; // ms interval for subtracting ammo during charge 0, // int chargeSubTime; // ms interval for subtracting ammo during charge
0, // int altChargeSubTime; // above for secondary 0, // int altChargeSubTime; // above for secondary
@ -116,18 +116,18 @@ weaponData_t weaponData[WP_NUM_WEAPONS] =
// "Tenloss Disruptor Rifle",// char classname[32]; // Spawning name // "Tenloss Disruptor Rifle",// char classname[32]; // Spawning name
AMMO_POWERCELL, // int ammoIndex; // Index to proper ammo slot AMMO_POWERCELL, // int ammoIndex; // Index to proper ammo slot
5, // int ammoLow; // Count when ammo is low 5, // int ammoLow; // Count when ammo is low
4, // int energyPerShot; // Amount of energy used per shot 5, // int energyPerShot; // Amount of energy used per shot
600, // int fireTime; // Amount of time between firings 600, // int fireTime; // Amount of time between firings
8192, // int range; // Range of weapon 8192, // int range; // Range of weapon
10, // int altEnergyPerShot; // Amount of energy used for alt-fire 6, // int altEnergyPerShot; // Amount of energy used for alt-fire
1300, // int altFireTime; // Amount of time between alt-firings 1300, // int altFireTime; // Amount of time between alt-firings
8192, // int altRange; // Range of alt-fire 8192, // int altRange; // Range of alt-fire
0, // int chargeSubTime; // ms interval for subtracting ammo during charge 0, // int chargeSubTime; // ms interval for subtracting ammo during charge
0, // int altChargeSubTime; // above for secondary 200, // int altChargeSubTime; // above for secondary
0, // int chargeSub; // amount to subtract during charge on each interval 0, // int chargeSub; // amount to subtract during charge on each interval
0, //int altChargeSub; // above for secondary 3, //int altChargeSub; // above for secondary
0, // int maxCharge; // stop subtracting once charged for this many ms 0, // int maxCharge; // stop subtracting once charged for this many ms
0 // int altMaxCharge; // above for secondary 1700 // int altMaxCharge; // above for secondary
}, },
{ // WP_BOWCASTER { // WP_BOWCASTER
// "Wookiee Bowcaster", // char classname[32]; // Spawning name // "Wookiee Bowcaster", // char classname[32]; // Spawning name
@ -139,11 +139,11 @@ weaponData_t weaponData[WP_NUM_WEAPONS] =
5, // int altEnergyPerShot; // Amount of energy used for alt-fire 5, // int altEnergyPerShot; // Amount of energy used for alt-fire
750, // int altFireTime; // Amount of time between alt-firings 750, // int altFireTime; // Amount of time between alt-firings
8192, // int altRange; // Range of alt-fire 8192, // int altRange; // Range of alt-fire
200, // int chargeSubTime; // ms interval for subtracting ammo during charge 400, // int chargeSubTime; // ms interval for subtracting ammo during charge
0, // int altChargeSubTime; // above for secondary 0, // int altChargeSubTime; // above for secondary
1, // int chargeSub; // amount to subtract during charge on each interval 5, // int chargeSub; // amount to subtract during charge on each interval
0, //int altChargeSub; // above for secondary 0, //int altChargeSub; // above for secondary
1500, // int maxCharge; // stop subtracting once charged for this many ms 1700, // int maxCharge; // stop subtracting once charged for this many ms
0 // int altMaxCharge; // above for secondary 0 // int altMaxCharge; // above for secondary
}, },
{ // WP_REPEATER { // WP_REPEATER
@ -151,7 +151,7 @@ weaponData_t weaponData[WP_NUM_WEAPONS] =
AMMO_METAL_BOLTS, // int ammoIndex; // Index to proper ammo slot AMMO_METAL_BOLTS, // int ammoIndex; // Index to proper ammo slot
5, // int ammoLow; // Count when ammo is low 5, // int ammoLow; // Count when ammo is low
1, // int energyPerShot; // Amount of energy used per shot 1, // int energyPerShot; // Amount of energy used per shot
50, // int fireTime; // Amount of time between firings 100, // int fireTime; // Amount of time between firings
8192, // int range; // Range of weapon 8192, // int range; // Range of weapon
8, // int altEnergyPerShot; // Amount of energy used for alt-fire 8, // int altEnergyPerShot; // Amount of energy used for alt-fire
800, // int altFireTime; // Amount of time between alt-firings 800, // int altFireTime; // Amount of time between alt-firings
@ -167,25 +167,25 @@ weaponData_t weaponData[WP_NUM_WEAPONS] =
// "DEMP2", // char classname[32]; // Spawning name // "DEMP2", // char classname[32]; // Spawning name
AMMO_POWERCELL, // int ammoIndex; // Index to proper ammo slot AMMO_POWERCELL, // int ammoIndex; // Index to proper ammo slot
5, // int ammoLow; // Count when ammo is low 5, // int ammoLow; // Count when ammo is low
10, // int energyPerShot; // Amount of energy used per shot 8, // int energyPerShot; // Amount of energy used per shot
500, // int fireTime; // Amount of time between firings 500, // int fireTime; // Amount of time between firings
8192, // int range; // Range of weapon 8192, // int range; // Range of weapon
4, // int altEnergyPerShot; // Amount of energy used for alt-fire 6, // int altEnergyPerShot; // Amount of energy used for alt-fire
900, // int altFireTime; // Amount of time between alt-firings 900, // int altFireTime; // Amount of time between alt-firings
8192, // int altRange; // Range of alt-fire 8192, // int altRange; // Range of alt-fire
0, // int chargeSubTime; // ms interval for subtracting ammo during charge 0, // int chargeSubTime; // ms interval for subtracting ammo during charge
700, // int altChargeSubTime; // above for secondary 250, // int altChargeSubTime; // above for secondary
0, // int chargeSub; // amount to subtract during charge on each interval 0, // int chargeSub; // amount to subtract during charge on each interval
4, // int altChargeSub; // above for secondary 3, // int altChargeSub; // above for secondary
0, // int maxCharge; // stop subtracting once charged for this many ms 0, // int maxCharge; // stop subtracting once charged for this many ms
2200 // int altMaxCharge; // above for secondary 2100 // int altMaxCharge; // above for secondary
}, },
{ // WP_FLECHETTE { // WP_FLECHETTE
// "Golan Arms Flechette", // char classname[32]; // Spawning name // "Golan Arms Flechette", // char classname[32]; // Spawning name
AMMO_METAL_BOLTS, // int ammoIndex; // Index to proper ammo slot AMMO_METAL_BOLTS, // int ammoIndex; // Index to proper ammo slot
5, // int ammoLow; // Count when ammo is low 5, // int ammoLow; // Count when ammo is low
10, // int energyPerShot; // Amount of energy used per shot 10, // int energyPerShot; // Amount of energy used per shot
550, // int fireTime; // Amount of time between firings 700, // int fireTime; // Amount of time between firings
8192, // int range; // Range of weapon 8192, // int range; // Range of weapon
15, // int altEnergyPerShot; // Amount of energy used for alt-fire 15, // int altEnergyPerShot; // Amount of energy used for alt-fire
800, // int altFireTime; // Amount of time between alt-firings 800, // int altFireTime; // Amount of time between alt-firings
@ -201,11 +201,11 @@ weaponData_t weaponData[WP_NUM_WEAPONS] =
// "Merr-Sonn Missile System", // char classname[32]; // Spawning name // "Merr-Sonn Missile System", // char classname[32]; // Spawning name
AMMO_ROCKETS, // int ammoIndex; // Index to proper ammo slot AMMO_ROCKETS, // int ammoIndex; // Index to proper ammo slot
5, // int ammoLow; // Count when ammo is low 5, // int ammoLow; // Count when ammo is low
20, // int energyPerShot; // Amount of energy used per shot 1, // int energyPerShot; // Amount of energy used per shot
600, // int fireTime; // Amount of time between firings 900, // int fireTime; // Amount of time between firings
8192, // int range; // Range of weapon 8192, // int range; // Range of weapon
25, // int altEnergyPerShot; // Amount of energy used for alt-fire 2, // int altEnergyPerShot; // Amount of energy used for alt-fire
800, // int altFireTime; // Amount of time between alt-firings 1200, // int altFireTime; // Amount of time between alt-firings
8192, // int altRange; // Range of alt-fire 8192, // int altRange; // Range of alt-fire
0, // int chargeSubTime; // ms interval for subtracting ammo during charge 0, // int chargeSubTime; // ms interval for subtracting ammo during charge
0, // int altChargeSubTime; // above for secondary 0, // int altChargeSubTime; // above for secondary
@ -308,7 +308,7 @@ ammoData_t ammoData[AMMO_MAX] =
}, },
{ // AMMO_ROCKETS { // AMMO_ROCKETS
// "", // char icon[32]; // Name of ammo icon file // "", // char icon[32]; // Name of ammo icon file
300 // int max; // Max amount player can hold of ammo 25 // int max; // Max amount player can hold of ammo
}, },
{ // AMMO_EMPLACED { // AMMO_EMPLACED
// "", // char icon[32]; // Name of ammo icon file // "", // char icon[32]; // Name of ammo icon file

View file

@ -65,6 +65,19 @@ void P_DamageFeedback( gentity_t *player ) {
player->pain_debounce_time = level.time + 700; player->pain_debounce_time = level.time + 700;
G_AddEvent( player, EV_PAIN, player->health ); G_AddEvent( player, EV_PAIN, player->health );
client->ps.damageEvent++; client->ps.damageEvent++;
if (client->damage_armor && !client->damage_blood)
{
client->ps.damageType = 1; //pure shields
}
else if (client->damage_armor)
{
client->ps.damageType = 2; //shields and health
}
else
{
client->ps.damageType = 0; //pure health
}
} }
@ -806,49 +819,6 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) {
} }
/*
==============
StuckInOtherClient
==============
*/
static int StuckInOtherClient(gentity_t *ent) {
int i;
gentity_t *ent2;
ent2 = &g_entities[0];
for ( i = 0; i < MAX_CLIENTS; i++, ent2++ ) {
if ( ent2 == ent ) {
continue;
}
if ( !ent2->inuse ) {
continue;
}
if ( !ent2->client ) {
continue;
}
if ( ent2->health <= 0 ) {
continue;
}
//
if (ent2->r.absmin[0] > ent->r.absmax[0])
continue;
if (ent2->r.absmin[1] > ent->r.absmax[1])
continue;
if (ent2->r.absmin[2] > ent->r.absmax[2])
continue;
if (ent2->r.absmax[0] < ent->r.absmin[0])
continue;
if (ent2->r.absmax[1] < ent->r.absmin[1])
continue;
if (ent2->r.absmax[2] < ent->r.absmin[2])
continue;
return qtrue;
}
return qfalse;
}
void BotTestSolid(vec3_t origin);
/* /*
============== ==============
SendPendingPredictableEvents SendPendingPredictableEvents
@ -1286,6 +1256,8 @@ void ClientThink_real( gentity_t *ent ) {
player_die(ent, ent, ent, 100000, MOD_FALLING); player_die(ent, ent, ent, 100000, MOD_FALLING);
respawn(ent); respawn(ent);
ent->client->ps.fallingToDeath = 0; ent->client->ps.fallingToDeath = 0;
G_MuteSound(ent->s.number, CHAN_VOICE); //stop screaming, because you are dead!
} }
if (ent->client->ps.otherKillerTime > level.time && if (ent->client->ps.otherKillerTime > level.time &&
@ -1293,6 +1265,7 @@ void ClientThink_real( gentity_t *ent ) {
ent->client->ps.otherKillerDebounceTime < level.time) ent->client->ps.otherKillerDebounceTime < level.time)
{ {
ent->client->ps.otherKillerTime = 0; ent->client->ps.otherKillerTime = 0;
ent->client->ps.otherKiller = ENTITYNUM_NONE;
} }
else if (ent->client->ps.otherKillerTime > level.time && else if (ent->client->ps.otherKillerTime > level.time &&
ent->client->ps.groundEntityNum == ENTITYNUM_NONE) ent->client->ps.groundEntityNum == ENTITYNUM_NONE)
@ -1303,8 +1276,8 @@ void ClientThink_real( gentity_t *ent ) {
} }
} }
WP_ForcePowersUpdate( ent, ucmd ); //update any active force powers // WP_ForcePowersUpdate( ent, msec, ucmd); //update any active force powers
WP_SaberPositionUpdate(ent, ucmd); //check the server-side saber point, do apprioriate server-side actions (effects are cs-only) // WP_SaberPositionUpdate(ent, ucmd); //check the server-side saber point, do apprioriate server-side actions (effects are cs-only)
if ((ent->client->pers.cmd.buttons & BUTTON_USE) && ent->client->ps.useDelay < level.time) if ((ent->client->pers.cmd.buttons & BUTTON_USE) && ent->client->ps.useDelay < level.time)
{ {
@ -1734,7 +1707,7 @@ void SpectatorClientEndFrame( gentity_t *ent ) {
// drop them to free spectators unless they are dedicated camera followers // drop them to free spectators unless they are dedicated camera followers
if ( ent->client->sess.spectatorClient >= 0 ) { if ( ent->client->sess.spectatorClient >= 0 ) {
ent->client->sess.spectatorState = SPECTATOR_FREE; ent->client->sess.spectatorState = SPECTATOR_FREE;
ClientBegin( ent->client - level.clients ); ClientBegin( ent->client - level.clients, qtrue );
} }
} }
} }

View file

@ -132,6 +132,7 @@ int G_GetMapTypeBits(char *type)
if( *type ) { if( *type ) {
if( strstr( type, "ffa" ) ) { if( strstr( type, "ffa" ) ) {
typeBits |= (1 << GT_FFA); typeBits |= (1 << GT_FFA);
typeBits |= (1 << GT_TEAM);
} }
if( strstr( type, "holocron" ) ) { if( strstr( type, "holocron" ) ) {
typeBits |= (1 << GT_HOLOCRON); typeBits |= (1 << GT_HOLOCRON);
@ -629,7 +630,7 @@ void G_CheckBotSpawn( void ) {
if ( botSpawnQueue[n].spawnTime > level.time ) { if ( botSpawnQueue[n].spawnTime > level.time ) {
continue; continue;
} }
ClientBegin( botSpawnQueue[n].clientNum ); ClientBegin( botSpawnQueue[n].clientNum, qfalse );
botSpawnQueue[n].spawnTime = 0; botSpawnQueue[n].spawnTime = 0;
if( g_gametype.integer == GT_SINGLE_PLAYER ) { if( g_gametype.integer == GT_SINGLE_PLAYER ) {
@ -657,7 +658,7 @@ static void AddBotToSpawnQueue( int clientNum, int delay ) {
} }
G_Printf( S_COLOR_YELLOW "Unable to delay spawn\n" ); G_Printf( S_COLOR_YELLOW "Unable to delay spawn\n" );
ClientBegin( clientNum ); ClientBegin( clientNum, qfalse );
} }
@ -718,7 +719,7 @@ static void G_AddBot( const char *name, float skill, const char *team, int delay
char *s; char *s;
char *botname; char *botname;
char *model; char *model;
char *headmodel; // char *headmodel;
char userinfo[MAX_INFO_STRING]; char userinfo[MAX_INFO_STRING];
int preTeam = 0; int preTeam = 0;
@ -764,7 +765,7 @@ static void G_AddBot( const char *name, float skill, const char *team, int delay
key = "team_model"; key = "team_model";
Info_SetValueForKey( userinfo, key, model ); Info_SetValueForKey( userinfo, key, model );
key = "headmodel"; /* key = "headmodel";
headmodel = Info_ValueForKey( botinfo, key ); headmodel = Info_ValueForKey( botinfo, key );
if ( !*headmodel ) { if ( !*headmodel ) {
headmodel = model; headmodel = model;
@ -772,7 +773,7 @@ static void G_AddBot( const char *name, float skill, const char *team, int delay
Info_SetValueForKey( userinfo, key, headmodel ); Info_SetValueForKey( userinfo, key, headmodel );
key = "team_headmodel"; key = "team_headmodel";
Info_SetValueForKey( userinfo, key, headmodel ); Info_SetValueForKey( userinfo, key, headmodel );
*/
key = "gender"; key = "gender";
s = Info_ValueForKey( botinfo, key ); s = Info_ValueForKey( botinfo, key );
if ( !*s ) { if ( !*s ) {
@ -807,8 +808,9 @@ static void G_AddBot( const char *name, float skill, const char *team, int delay
// have the server allocate a client slot // have the server allocate a client slot
clientNum = trap_BotAllocateClient(); clientNum = trap_BotAllocateClient();
if ( clientNum == -1 ) { if ( clientNum == -1 ) {
G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" ); // G_Printf( S_COLOR_RED "Unable to add bot. All player slots are in use.\n" );
G_Printf( S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n" ); // G_Printf( S_COLOR_RED "Start server with more 'open' slots.\n" );
trap_SendServerCommand( -1, va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "UNABLE_TO_ADD_BOT")));
return; return;
} }
@ -889,7 +891,7 @@ static void G_AddBot( const char *name, float skill, const char *team, int delay
} }
if( delay == 0 ) { if( delay == 0 ) {
ClientBegin( clientNum ); ClientBegin( clientNum, qfalse );
return; return;
} }
@ -972,7 +974,7 @@ void Svcmd_BotList_f( void ) {
for (i = 0; i < g_numBots; i++) { for (i = 0; i < g_numBots; i++) {
strcpy(name, Info_ValueForKey( g_botInfos[i], "name" )); strcpy(name, Info_ValueForKey( g_botInfos[i], "name" ));
if ( !*name ) { if ( !*name ) {
strcpy(name, "UnnamedPlayer"); strcpy(name, "Padawan");
} }
strcpy(funname, Info_ValueForKey( g_botInfos[i], "funname" )); strcpy(funname, Info_ValueForKey( g_botInfos[i], "funname" ));
if ( !*funname ) { if ( !*funname ) {

View file

@ -69,7 +69,6 @@ void SP_info_player_intermission( gentity_t *ent ) {
#define JMSABER_RESPAWN_TIME 20000 //in case it gets stuck somewhere no one can reach #define JMSABER_RESPAWN_TIME 20000 //in case it gets stuck somewhere no one can reach
void ThrowSaberToAttacker(gentity_t *self, gentity_t *attacker) void ThrowSaberToAttacker(gentity_t *self, gentity_t *attacker)
{ {
gentity_t *ent = &g_entities[self->client->ps.saberIndex]; gentity_t *ent = &g_entities[self->client->ps.saberIndex];
@ -78,7 +77,26 @@ void ThrowSaberToAttacker(gentity_t *self, gentity_t *attacker)
if (!ent || ent->enemy != self) if (!ent || ent->enemy != self)
{ //something has gone very wrong (this should never happen) { //something has gone very wrong (this should never happen)
return; //but in case it does.. find the saber manually
#ifdef _DEBUG
Com_Printf("Lost the saber! Attempting to use global pointer..\n");
#endif
ent = gJMSaberEnt;
if (!ent)
{
#ifdef _DEBUG
Com_Printf("The global pointer was NULL. This is a bad thing.\n");
#endif
return;
}
#ifdef _DEBUG
Com_Printf("Got it (%i). Setting enemy to client %i.\n", ent->s.number, self->s.number);
#endif
ent->enemy = self;
self->client->ps.saberIndex = ent->s.number;
} }
trap_SetConfigstring ( CS_CLIENT_JEDIMASTER, "-1" ); trap_SetConfigstring ( CS_CLIENT_JEDIMASTER, "-1" );
@ -180,7 +198,7 @@ void JMSaberThink(gentity_t *ent)
void JMSaberTouch(gentity_t *self, gentity_t *other, trace_t *trace) void JMSaberTouch(gentity_t *self, gentity_t *other, trace_t *trace)
{ {
int i = 0; int i = 0;
gentity_t *te; // gentity_t *te;
if (!other || !other->client || other->health < 1) if (!other || !other->client || other->health < 1)
{ {
@ -253,9 +271,12 @@ void JMSaberTouch(gentity_t *self, gentity_t *other, trace_t *trace)
self->s.modelGhoul2 = 0; self->s.modelGhoul2 = 0;
self->s.eType = ET_GENERAL; self->s.eType = ET_GENERAL;
/*
te = G_TempEntity( vec3_origin, EV_DESTROY_GHOUL2_INSTANCE ); te = G_TempEntity( vec3_origin, EV_DESTROY_GHOUL2_INSTANCE );
te->r.svFlags |= SVF_BROADCAST; te->r.svFlags |= SVF_BROADCAST;
te->s.eventParm = self->s.number; te->s.eventParm = self->s.number;
*/
G_KillG2Queue(self->s.number);
return; return;
} }
@ -291,6 +312,8 @@ void SP_info_jedimaster_start(gentity_t *ent)
ent->r.contents = CONTENTS_TRIGGER; ent->r.contents = CONTENTS_TRIGGER;
ent->clipmask = MASK_SOLID; ent->clipmask = MASK_SOLID;
ent->isSaberEntity = qtrue;
ent->bounceCount = -5; ent->bounceCount = -5;
ent->physicsObject = qtrue; ent->physicsObject = qtrue;
@ -621,6 +644,11 @@ void CopyToBodyQue( gentity_t *ent ) {
gentity_t *body; gentity_t *body;
int contents; int contents;
if (level.intermissiontime)
{
return;
}
trap_UnlinkEntity (ent); trap_UnlinkEntity (ent);
// if client is in a nodrop area, don't leave the body // if client is in a nodrop area, don't leave the body
@ -922,7 +950,7 @@ static void ClientCleanName( const char *in, char *out, int outSize ) {
// don't allow empty names // don't allow empty names
if( *p == 0 || colorlessLen == 0 ) { if( *p == 0 || colorlessLen == 0 ) {
Q_strncpyz( p, "UnnamedPlayer", outSize ); Q_strncpyz( p, "Padawan", outSize );
} }
} }
@ -1085,7 +1113,7 @@ void ClientUserinfoChanged( int clientNum ) {
int teamTask, teamLeader, team, health; int teamTask, teamLeader, team, health;
char *s; char *s;
char model[MAX_QPATH]; char model[MAX_QPATH];
char headModel[MAX_QPATH]; //char headModel[MAX_QPATH];
char forcePowers[MAX_QPATH]; char forcePowers[MAX_QPATH];
char oldname[MAX_STRING_CHARS]; char oldname[MAX_STRING_CHARS];
gclient_t *client; gclient_t *client;
@ -1148,10 +1176,10 @@ void ClientUserinfoChanged( int clientNum ) {
// set model // set model
if( g_gametype.integer >= GT_TEAM ) { if( g_gametype.integer >= GT_TEAM ) {
Q_strncpyz( model, Info_ValueForKey (userinfo, "team_model"), sizeof( model ) ); Q_strncpyz( model, Info_ValueForKey (userinfo, "team_model"), sizeof( model ) );
Q_strncpyz( headModel, Info_ValueForKey (userinfo, "team_headmodel"), sizeof( headModel ) ); //Q_strncpyz( headModel, Info_ValueForKey (userinfo, "team_headmodel"), sizeof( headModel ) );
} else { } else {
Q_strncpyz( model, Info_ValueForKey (userinfo, "model"), sizeof( model ) ); Q_strncpyz( model, Info_ValueForKey (userinfo, "model"), sizeof( model ) );
Q_strncpyz( headModel, Info_ValueForKey (userinfo, "headmodel"), sizeof( headModel ) ); //Q_strncpyz( headModel, Info_ValueForKey (userinfo, "headmodel"), sizeof( headModel ) );
} }
Q_strncpyz( forcePowers, Info_ValueForKey (userinfo, "forcepowers"), sizeof( forcePowers ) ); Q_strncpyz( forcePowers, Info_ValueForKey (userinfo, "forcepowers"), sizeof( forcePowers ) );
@ -1228,13 +1256,13 @@ void ClientUserinfoChanged( int clientNum ) {
// send over a subset of the userinfo keys so other clients can // send over a subset of the userinfo keys so other clients can
// print scoreboards, display models, and play custom sounds // print scoreboards, display models, and play custom sounds
if ( ent->r.svFlags & SVF_BOT ) { if ( ent->r.svFlags & SVF_BOT ) {
s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d", s = va("n\\%s\\t\\%i\\model\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d",
client->pers.netname, team, model, headModel, c1, c2, client->pers.netname, team, model, c1, c2,
client->pers.maxHealth, client->sess.wins, client->sess.losses, client->pers.maxHealth, client->sess.wins, client->sess.losses,
Info_ValueForKey( userinfo, "skill" ), teamTask, teamLeader ); Info_ValueForKey( userinfo, "skill" ), teamTask, teamLeader );
} else { } else {
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", s = va("n\\%s\\t\\%i\\model\\%s\\g_redteam\\%s\\g_blueteam\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d",
client->pers.netname, client->sess.sessionTeam, model, headModel, redTeam, blueTeam, c1, c2, client->pers.netname, client->sess.sessionTeam, model, redTeam, blueTeam, c1, c2,
client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader); client->pers.maxHealth, client->sess.wins, client->sess.losses, teamTask, teamLeader);
} }
@ -1287,7 +1315,9 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) {
value = Info_ValueForKey (userinfo, "password"); value = Info_ValueForKey (userinfo, "password");
if ( g_password.string[0] && Q_stricmp( g_password.string, "none" ) && if ( g_password.string[0] && Q_stricmp( g_password.string, "none" ) &&
strcmp( g_password.string, value) != 0) { strcmp( g_password.string, value) != 0) {
return "Invalid password"; static char sTemp[1024];
Q_strncpyz(sTemp, G_GetStripEdString("SVINGAME","INVALID_PASSWORD"), sizeof (sTemp) );
return sTemp;// return "Invalid password";
} }
} }
@ -1344,6 +1374,8 @@ char *ClientConnect( int clientNum, qboolean firstTime, qboolean isBot ) {
return NULL; return NULL;
} }
void G_WriteClientSessionData( gclient_t *client );
/* /*
=========== ===========
ClientBegin ClientBegin
@ -1353,7 +1385,7 @@ to be placed into the level. This will happen every level load,
and on transition between teams, but doesn't happen on respawns and on transition between teams, but doesn't happen on respawns
============ ============
*/ */
void ClientBegin( int clientNum ) { void ClientBegin( int clientNum, qboolean allowTeamReset ) {
gentity_t *ent; gentity_t *ent;
gclient_t *client; gclient_t *client;
gentity_t *tent; gentity_t *tent;
@ -1362,6 +1394,47 @@ void ClientBegin( int clientNum ) {
ent = g_entities + clientNum; ent = g_entities + clientNum;
if ((ent->r.svFlags & SVF_BOT) && g_gametype.integer >= GT_TEAM)
{
if (allowTeamReset)
{
const char *team = "Red";
int preSess;
//SetTeam(ent, "");
ent->client->sess.sessionTeam = PickTeam(-1);
trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING);
if (ent->client->sess.sessionTeam == TEAM_SPECTATOR)
{
ent->client->sess.sessionTeam = TEAM_RED;
}
if (ent->client->sess.sessionTeam == TEAM_RED)
{
team = "Red";
}
else
{
team = "Blue";
}
Info_SetValueForKey( userinfo, "team", team );
trap_SetUserinfo( clientNum, userinfo );
ent->client->ps.persistant[ PERS_TEAM ] = ent->client->sess.sessionTeam;
preSess = ent->client->sess.sessionTeam;
G_ReadSessionData( ent->client );
ent->client->sess.sessionTeam = preSess;
G_WriteClientSessionData(ent->client);
ClientUserinfoChanged( clientNum );
ClientBegin(clientNum, qfalse);
return;
}
}
client = level.clients + clientNum; client = level.clients + clientNum;
if ( ent->r.linked ) { if ( ent->r.linked ) {
@ -1480,6 +1553,7 @@ void ClientSpawn(gentity_t *ent) {
forcedata_t savedForce; forcedata_t savedForce;
void *ghoul2save; void *ghoul2save;
int saveSaberNum = ENTITYNUM_NONE; int saveSaberNum = ENTITYNUM_NONE;
int wDisable = 0;
index = ent - g_entities; index = ent - g_entities;
client = ent->client; client = ent->client;
@ -1638,7 +1712,16 @@ void ClientSpawn(gentity_t *ent) {
} }
} }
if (!g_weaponDisable.integer || !(g_weaponDisable.integer & (1 << WP_BRYAR_PISTOL))) if (g_gametype.integer == GT_TOURNAMENT)
{
wDisable = g_duelWeaponDisable.integer;
}
else
{
wDisable = g_weaponDisable.integer;
}
if (!wDisable || !(wDisable & (1 << WP_BRYAR_PISTOL)))
{ {
client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BRYAR_PISTOL ); client->ps.stats[STAT_WEAPONS] |= ( 1 << WP_BRYAR_PISTOL );
} }

View file

@ -32,6 +32,11 @@ void DeathmatchScoreboardMessage( gentity_t *ent ) {
numSorted = level.numConnectedClients; numSorted = level.numConnectedClients;
if (numSorted > MAX_CLIENT_SCORE_SEND)
{
numSorted = MAX_CLIENT_SCORE_SEND;
}
for (i=0 ; i < numSorted ; i++) { for (i=0 ; i < numSorted ; i++) {
int ping; int ping;
@ -63,12 +68,15 @@ void DeathmatchScoreboardMessage( gentity_t *ent ) {
perfect, perfect,
cl->ps.persistant[PERS_CAPTURES]); cl->ps.persistant[PERS_CAPTURES]);
j = strlen(entry); j = strlen(entry);
if (stringlength + j > 1024) if (stringlength + j > 1022)
break; break;
strcpy (string + stringlength, entry); strcpy (string + stringlength, entry);
stringlength += j; stringlength += j;
} }
//still want to know the total # of clients
i = level.numConnectedClients;
trap_SendServerCommand( ent-g_entities, va("scores %i %i %i%s", i, trap_SendServerCommand( ent-g_entities, va("scores %i %i %i%s", i,
level.teamScores[TEAM_RED], level.teamScores[TEAM_BLUE], level.teamScores[TEAM_RED], level.teamScores[TEAM_BLUE],
string ) ); string ) );
@ -235,6 +243,17 @@ void Cmd_Give_f (gentity_t *ent)
else else
give_all = qfalse; give_all = qfalse;
if (give_all)
{
i = 0;
while (i < HI_NUM_HOLDABLE)
{
ent->client->ps.stats[STAT_HOLDABLE_ITEMS] |= (1 << i);
i++;
}
i = 0;
}
if (give_all || Q_stricmp( name, "health") == 0) if (give_all || Q_stricmp( name, "health") == 0)
{ {
if (trap_Argc() == 3) { if (trap_Argc() == 3) {
@ -607,6 +626,8 @@ void SetTeam( gentity_t *ent, char *s ) {
team = TEAM_BLUE; team = TEAM_BLUE;
} else { } else {
// pick the team with the least number of players // pick the team with the least number of players
//For now, don't do this. The legalize function will set powers properly now.
/*
if (g_forceBasedTeams.integer) if (g_forceBasedTeams.integer)
{ {
if (ent->client->ps.fd.forceSide == FORCE_LIGHTSIDE) if (ent->client->ps.fd.forceSide == FORCE_LIGHTSIDE)
@ -620,8 +641,9 @@ void SetTeam( gentity_t *ent, char *s ) {
} }
else else
{ {
*/
team = PickTeam( clientNum ); team = PickTeam( clientNum );
} //}
} }
if ( g_teamForceBalance.integer ) { if ( g_teamForceBalance.integer ) {
@ -632,12 +654,15 @@ void SetTeam( gentity_t *ent, char *s ) {
// We allow a spread of two // We allow a spread of two
if ( team == TEAM_RED && counts[TEAM_RED] - counts[TEAM_BLUE] > 1 ) { if ( team == TEAM_RED && counts[TEAM_RED] - counts[TEAM_BLUE] > 1 ) {
//For now, don't do this. The legalize function will set powers properly now.
/*
if (g_forceBasedTeams.integer && ent->client->ps.fd.forceSide == FORCE_DARKSIDE) if (g_forceBasedTeams.integer && ent->client->ps.fd.forceSide == FORCE_DARKSIDE)
{ {
trap_SendServerCommand( ent->client->ps.clientNum, trap_SendServerCommand( ent->client->ps.clientNum,
va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "TOOMANYRED_SWITCH")) ); va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "TOOMANYRED_SWITCH")) );
} }
else else
*/
{ {
trap_SendServerCommand( ent->client->ps.clientNum, trap_SendServerCommand( ent->client->ps.clientNum,
va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "TOOMANYRED")) ); va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "TOOMANYRED")) );
@ -645,12 +670,15 @@ void SetTeam( gentity_t *ent, char *s ) {
return; // ignore the request return; // ignore the request
} }
if ( team == TEAM_BLUE && counts[TEAM_BLUE] - counts[TEAM_RED] > 1 ) { if ( team == TEAM_BLUE && counts[TEAM_BLUE] - counts[TEAM_RED] > 1 ) {
//For now, don't do this. The legalize function will set powers properly now.
/*
if (g_forceBasedTeams.integer && ent->client->ps.fd.forceSide == FORCE_LIGHTSIDE) if (g_forceBasedTeams.integer && ent->client->ps.fd.forceSide == FORCE_LIGHTSIDE)
{ {
trap_SendServerCommand( ent->client->ps.clientNum, trap_SendServerCommand( ent->client->ps.clientNum,
va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "TOOMANYBLUE_SWITCH")) ); va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "TOOMANYBLUE_SWITCH")) );
} }
else else
*/
{ {
trap_SendServerCommand( ent->client->ps.clientNum, trap_SendServerCommand( ent->client->ps.clientNum,
va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "TOOMANYBLUE")) ); va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "TOOMANYBLUE")) );
@ -661,6 +689,8 @@ void SetTeam( gentity_t *ent, char *s ) {
// It's ok, the team we are switching to has less or same number of players // It's ok, the team we are switching to has less or same number of players
} }
//For now, don't do this. The legalize function will set powers properly now.
/*
if (g_forceBasedTeams.integer) if (g_forceBasedTeams.integer)
{ {
if (team == TEAM_BLUE && ent->client->ps.fd.forceSide != FORCE_LIGHTSIDE) if (team == TEAM_BLUE && ent->client->ps.fd.forceSide != FORCE_LIGHTSIDE)
@ -674,6 +704,7 @@ void SetTeam( gentity_t *ent, char *s ) {
return; return;
} }
} }
*/
} else { } else {
// force them to spectators if there aren't any spots free // force them to spectators if there aren't any spots free
@ -742,7 +773,7 @@ void SetTeam( gentity_t *ent, char *s ) {
// get and distribute relevent paramters // get and distribute relevent paramters
ClientUserinfoChanged( clientNum ); ClientUserinfoChanged( clientNum );
ClientBegin( clientNum ); ClientBegin( clientNum, qfalse );
} }
/* /*
@ -818,34 +849,34 @@ void Cmd_ForceChanged_f( gentity_t *ent )
{ {
char fpChStr[1024]; char fpChStr[1024];
const char *buf; const char *buf;
int i = 0;
int ccount = 0;
// Cmd_Kill_f(ent); // Cmd_Kill_f(ent);
if (ent->client->sess.sessionTeam == TEAM_SPECTATOR) if (ent->client->sess.sessionTeam == TEAM_SPECTATOR)
{ //if it's a spec, just make the changes now { //if it's a spec, just make the changes now
trap_SendServerCommand( ent-g_entities, va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "FORCEAPPLIED")) ); //trap_SendServerCommand( ent-g_entities, va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "FORCEAPPLIED")) );
//No longer print it, as the UI calls this a lot.
WP_InitForcePowers( ent ); WP_InitForcePowers( ent );
return; goto argCheck;
} }
buf = G_GetStripEdString("SVINGAME", "FORCEPOWERCHANGED"); buf = G_GetStripEdString("SVINGAME", "FORCEPOWERCHANGED");
strcpy(fpChStr, buf); strcpy(fpChStr, buf);
while (i < 1024 && fpChStr[i]) trap_SendServerCommand( ent-g_entities, va("print \"%s%s\n\"", S_COLOR_GREEN, fpChStr) );
{
if (ccount > 24 && fpChStr[i] == ' ')
{
fpChStr[i] = '\n';
ccount = 0;
}
ccount++;
i++;
}
trap_SendServerCommand( ent-g_entities, va("cp \"%s\n\"", fpChStr) );
ent->client->ps.fd.forceDoInit = 1; ent->client->ps.fd.forceDoInit = 1;
argCheck:
if (trap_Argc() > 1)
{
char arg[MAX_TOKEN_CHARS];
trap_Argv( 1, arg, sizeof( arg ) );
if (arg && arg[0])
{ //if there's an arg, assume it's a combo team command from the UI.
Cmd_Team_f(ent);
}
}
} }
/* /*
@ -1352,8 +1383,9 @@ static const char *gameNames[] = {
"Duel", "Duel",
"Single Player", "Single Player",
"Team FFA", "Team FFA",
"Saga", "N/A",
"Capture the Flag" "Capture the Flag",
"Capture the Ysalamiri"
}; };
/* /*
@ -1434,7 +1466,8 @@ void Cmd_CallVote_f( gentity_t *ent ) {
if (!G_DoesMapSupportGametype(arg2, trap_Cvar_VariableIntegerValue("g_gametype"))) if (!G_DoesMapSupportGametype(arg2, trap_Cvar_VariableIntegerValue("g_gametype")))
{ {
trap_SendServerCommand( ent-g_entities, "print \"You can't vote for this map, it isn't supported by the current gametype.\n\"" ); //trap_SendServerCommand( ent-g_entities, "print \"You can't vote for this map, it isn't supported by the current gametype.\n\"" );
trap_SendServerCommand( ent-g_entities, va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "NOVOTE_MAPNOTSUPPORTEDBYGAME")) );
return; return;
} }
@ -1939,19 +1972,22 @@ void Cmd_SaberAttackCycle_f(gentity_t *ent)
{ {
selectLevel = FORCE_LEVEL_1; selectLevel = FORCE_LEVEL_1;
} }
/*
#ifndef FINAL_BUILD
switch ( selectLevel ) switch ( selectLevel )
{ {
case FORCE_LEVEL_1: case FORCE_LEVEL_1:
trap_SendServerCommand( ent-g_entities, va("print \"Saber Attack Set: %sfast\n\"", S_COLOR_GREEN) ); trap_SendServerCommand( ent-g_entities, va("print \"Lightsaber Combat Style: %sfast\n\"", S_COLOR_BLUE) );
break; break;
case FORCE_LEVEL_2: case FORCE_LEVEL_2:
trap_SendServerCommand( ent-g_entities, va("print \"Saber Attack Set: %smedium\n\"", S_COLOR_YELLOW) ); trap_SendServerCommand( ent-g_entities, va("print \"Lightsaber Combat Style: %smedium\n\"", S_COLOR_YELLOW) );
break; break;
case FORCE_LEVEL_3: case FORCE_LEVEL_3:
trap_SendServerCommand( ent-g_entities, va("print \"Saber Attack Set: %sstrong\n\"", S_COLOR_RED) ); trap_SendServerCommand( ent-g_entities, va("print \"Lightsaber Combat Style: %sstrong\n\"", S_COLOR_RED) );
break; break;
} }
#endif
*/
if (ent->client->ps.weaponTime <= 0) if (ent->client->ps.weaponTime <= 0)
{ //not busy, set it now { //not busy, set it now
ent->client->ps.fd.saberAnimLevel = selectLevel; ent->client->ps.fd.saberAnimLevel = selectLevel;
@ -2381,7 +2417,8 @@ void ClientCommand( int clientNum ) {
{ {
if (Q_stricmp(cmd, "addbot") == 0) if (Q_stricmp(cmd, "addbot") == 0)
{ //because addbot isn't a recognized command unless you're the server, but it is in the menus regardless { //because addbot isn't a recognized command unless you're the server, but it is in the menus regardless
trap_SendServerCommand( clientNum, va("print \"You can only add bots as the server.\n\"" ) ); // trap_SendServerCommand( clientNum, va("print \"You can only add bots as the server.\n\"" ) );
trap_SendServerCommand( clientNum, va("print \"%s.\n\"", G_GetStripEdString("SVINGAME", "ONLY_ADD_BOTS_AS_SERVER")));
} }
else else
{ {

View file

@ -8,8 +8,6 @@
void BotDamageNotification(gclient_t *bot, gentity_t *attacker); void BotDamageNotification(gclient_t *bot, gentity_t *attacker);
//end rww //end rww
extern int protectHitSound;
void ThrowSaberToAttacker(gentity_t *self, gentity_t *attacker); void ThrowSaberToAttacker(gentity_t *self, gentity_t *attacker);
void ObjectDie (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) void ObjectDie (gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath )
@ -738,6 +736,12 @@ void GibEntity( gentity_t *self, int killer ) {
self->r.contents = 0; self->r.contents = 0;
} }
void BodyRid(gentity_t *ent)
{
trap_UnlinkEntity( ent );
ent->physicsObject = qfalse;
}
/* /*
================== ==================
body_die body_die
@ -745,16 +749,49 @@ body_die
*/ */
void body_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) { void body_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) {
// NOTENOTE No gibbing right now, this is star wars. // NOTENOTE No gibbing right now, this is star wars.
if(1) // if ( self->health > GIB_HEALTH ) qboolean doDisint = qfalse;
if (self->health < (GIB_HEALTH+1))
{
self->health = GIB_HEALTH+1;
if (self->client && (level.time - self->client->respawnTime) < 2000)
{
doDisint = qfalse;
}
else
{
doDisint = qtrue;
}
}
if (self->client && (self->client->ps.eFlags & EF_DISINTEGRATION))
{ {
return; return;
} }
if ( !g_blood.integer ) { else if (self->s.eFlags & EF_DISINTEGRATION)
self->health = GIB_HEALTH+1; {
return; return;
} }
GibEntity( self, 0 ); if (doDisint)
{
if (self->client)
{
self->client->ps.eFlags |= EF_DISINTEGRATION;
VectorCopy(self->client->ps.origin, self->client->ps.lastHitLoc);
}
else
{
self->s.eFlags |= EF_DISINTEGRATION;
VectorCopy(self->r.currentOrigin, self->s.origin2);
//since it's the corpse entity, tell it to "remove" itself
self->think = BodyRid;
self->nextthink = level.time + 1000;
}
return;
}
} }
@ -1168,6 +1205,26 @@ static int G_PickDeathAnim( gentity_t *self, vec3_t point, int damage, int mod,
void G_CheckForDismemberment(gentity_t *ent, vec3_t point, int damage, int deathAnim); void G_CheckForDismemberment(gentity_t *ent, vec3_t point, int damage, int deathAnim);
gentity_t *G_GetJediMaster(void)
{
int i = 0;
gentity_t *ent;
while (i < MAX_CLIENTS)
{
ent = &g_entities[i];
if (ent && ent->inuse && ent->client && ent->client->ps.isJediMaster)
{
return ent;
}
i++;
}
return NULL;
}
/* /*
================== ==================
player_die player_die
@ -1276,7 +1333,33 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
attacker->client->lastkilled_client = self->s.number; attacker->client->lastkilled_client = self->s.number;
if ( attacker == self || OnSameTeam (self, attacker ) ) { if ( attacker == self || OnSameTeam (self, attacker ) ) {
AddScore( attacker, self->r.currentOrigin, -1 ); if (g_gametype.integer == GT_TOURNAMENT)
{ //in duel, if you kill yourself, the person you are dueling against gets a kill for it
int otherClNum = -1;
if (level.sortedClients[0] == self->s.number)
{
otherClNum = level.sortedClients[1];
}
else if (level.sortedClients[1] == self->s.number)
{
otherClNum = level.sortedClients[0];
}
if (otherClNum >= 0 && otherClNum < MAX_CLIENTS &&
g_entities[otherClNum].inuse && g_entities[otherClNum].client &&
otherClNum != attacker->s.number)
{
AddScore( &g_entities[otherClNum], self->r.currentOrigin, 1 );
}
else
{
AddScore( attacker, self->r.currentOrigin, -1 );
}
}
else
{
AddScore( attacker, self->r.currentOrigin, -1 );
}
if (g_gametype.integer == GT_JEDIMASTER) if (g_gametype.integer == GT_JEDIMASTER)
{ {
if (self->client && self->client->ps.isJediMaster) if (self->client && self->client->ps.isJediMaster)
@ -1301,6 +1384,15 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
self->client->ps.isJediMaster = qfalse; self->client->ps.isJediMaster = qfalse;
} }
} }
else
{
gentity_t *jmEnt = G_GetJediMaster();
if (jmEnt && jmEnt->client)
{
AddScore( jmEnt, self->r.currentOrigin, 1 );
}
}
} }
else else
{ {
@ -1343,7 +1435,34 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
ThrowSaberToAttacker(self, NULL); ThrowSaberToAttacker(self, NULL);
self->client->ps.isJediMaster = qfalse; self->client->ps.isJediMaster = qfalse;
} }
AddScore( self, self->r.currentOrigin, -1 );
if (g_gametype.integer == GT_TOURNAMENT)
{ //in duel, if you kill yourself, the person you are dueling against gets a kill for it
int otherClNum = -1;
if (level.sortedClients[0] == self->s.number)
{
otherClNum = level.sortedClients[1];
}
else if (level.sortedClients[1] == self->s.number)
{
otherClNum = level.sortedClients[0];
}
if (otherClNum >= 0 && otherClNum < MAX_CLIENTS &&
g_entities[otherClNum].inuse && g_entities[otherClNum].client &&
otherClNum != self->s.number)
{
AddScore( &g_entities[otherClNum], self->r.currentOrigin, 1 );
}
else
{
AddScore( self, self->r.currentOrigin, -1 );
}
}
else
{
AddScore( self, self->r.currentOrigin, -1 );
}
} }
// Add team bonuses // Add team bonuses
@ -1494,8 +1613,8 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
// the body can still be gibbed // the body can still be gibbed
self->die = body_die; self->die = body_die;
//rww - even though we have no gibbing, if you shoot the body it will disappear unless it doesn't take damage //It won't gib, it will disintegrate (because this is Star Wars).
self->takedamage = qfalse; self->takedamage = qtrue;
// globally cycle through the different death animations // globally cycle through the different death animations
i = ( i + 1 ) % 3; i = ( i + 1 ) % 3;
@ -2004,6 +2123,26 @@ void G_CheckForDismemberment(gentity_t *ent, vec3_t point, int damage, int death
G_Dismember(ent, boltPoint, hitLocUse, 90, 0, deathAnim); G_Dismember(ent, boltPoint, hitLocUse, 90, 0, deathAnim);
} }
qboolean G_ThereIsAMaster(void)
{
int i = 0;
gentity_t *ent;
while (i < MAX_CLIENTS)
{
ent = &g_entities[i];
if (ent && ent->client && ent->client->ps.isJediMaster)
{
return qtrue;
}
i++;
}
return qfalse;
}
/* /*
============ ============
T_Damage T_Damage
@ -2059,6 +2198,10 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
{ {
return; return;
} }
else if (attacker && attacker->client && mod != MOD_SABER)
{
return;
}
} }
if (attacker && attacker->client && attacker->client->ps.duelInProgress) if (attacker && attacker->client && attacker->client->ps.duelInProgress)
{ {
@ -2066,6 +2209,10 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
{ {
return; return;
} }
else if (targ && targ->client && mod != MOD_SABER)
{
return;
}
} }
if (targ && targ->client && (targ->client->ps.fd.forcePowersActive & (1 << FP_RAGE))) if (targ && targ->client && (targ->client->ps.fd.forcePowersActive & (1 << FP_RAGE)))
@ -2141,6 +2288,12 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
VectorScale (dir, g_knockback.value * (float)knockback / mass, kvel); VectorScale (dir, g_knockback.value * (float)knockback / mass, kvel);
VectorAdd (targ->client->ps.velocity, kvel, targ->client->ps.velocity); VectorAdd (targ->client->ps.velocity, kvel, targ->client->ps.velocity);
if (attacker && attacker->client && attacker != targ)
{
targ->client->ps.otherKiller = attacker->s.number;
targ->client->ps.otherKillerTime = level.time + 5000;
targ->client->ps.otherKillerDebounceTime = level.time + 100;
}
// set the timer so that the other client can't cancel // set the timer so that the other client can't cancel
// out the movement immediately // out the movement immediately
if ( !targ->client->ps.pm_time ) { if ( !targ->client->ps.pm_time ) {
@ -2169,6 +2322,14 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
} }
} }
if (g_gametype.integer == GT_JEDIMASTER && !g_friendlyFire.integer &&
targ && targ->client && attacker && attacker->client &&
targ != attacker && !targ->client->ps.isJediMaster && !attacker->client->ps.isJediMaster &&
G_ThereIsAMaster())
{
return;
}
if (targ->client && targ->s.shouldtarget && targ->s.teamowner && if (targ->client && targ->s.shouldtarget && targ->s.teamowner &&
attacker && attacker->inuse && attacker->client && targ->s.owner >= 0 && targ->s.owner < MAX_CLIENTS) attacker && attacker->inuse && attacker->client && targ->s.owner >= 0 && targ->s.owner < MAX_CLIENTS)
{ {
@ -2321,12 +2482,13 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
{ {
int maxtake = take; int maxtake = take;
G_Sound(targ, CHAN_AUTO, protectHitSound); //G_Sound(targ, CHAN_AUTO, protectHitSound);
G_PreDefSound(targ->client->ps.origin, PDSOUND_PROTECTHIT);
if (targ->client->ps.fd.forcePowerLevel[FP_PROTECT] == FORCE_LEVEL_1) if (targ->client->ps.fd.forcePowerLevel[FP_PROTECT] == FORCE_LEVEL_1)
{ {
famt = 1; famt = 1;
hamt = 0.5; hamt = 0.40;
if (maxtake > 100) if (maxtake > 100)
{ {
@ -2336,7 +2498,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
else if (targ->client->ps.fd.forcePowerLevel[FP_PROTECT] == FORCE_LEVEL_2) else if (targ->client->ps.fd.forcePowerLevel[FP_PROTECT] == FORCE_LEVEL_2)
{ {
famt = 0.5; famt = 0.5;
hamt = 0.75; hamt = 0.60;
if (maxtake > 200) if (maxtake > 200)
{ {
@ -2346,7 +2508,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
else if (targ->client->ps.fd.forcePowerLevel[FP_PROTECT] == FORCE_LEVEL_3) else if (targ->client->ps.fd.forcePowerLevel[FP_PROTECT] == FORCE_LEVEL_3)
{ {
famt = 0.25; famt = 0.25;
hamt = 1; hamt = 0.80;
if (maxtake > 400) if (maxtake > 400)
{ {
@ -2358,6 +2520,10 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
{ {
targ->client->ps.fd.forcePower -= maxtake*famt; targ->client->ps.fd.forcePower -= maxtake*famt;
} }
else
{
targ->client->ps.fd.forcePower -= (maxtake*famt)/2;
}
subamt = (maxtake*hamt)+(take-maxtake); subamt = (maxtake*hamt)+(take-maxtake);
if (targ->client->ps.fd.forcePower < 0) if (targ->client->ps.fd.forcePower < 0)
{ {
@ -2412,7 +2578,7 @@ void G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
if (take) { if (take) {
if (targ->client && (targ->client->ps.fd.forcePowersActive & (1 << FP_RAGE)) && (inflictor->client || attacker->client)) if (targ->client && (targ->client->ps.fd.forcePowersActive & (1 << FP_RAGE)) && (inflictor->client || attacker->client))
{ {
take /= (targ->client->ps.fd.forcePowerLevel[FP_RAGE]); take /= (targ->client->ps.fd.forcePowerLevel[FP_RAGE]+1);
} }
targ->health = targ->health - take; targ->health = targ->health - take;
if ( targ->client ) { if ( targ->client ) {

View file

@ -32,8 +32,20 @@ extern gentity_t *droppedBlueFlag;
#define MAX_SENTRY_DISTANCE 256 #define MAX_SENTRY_DISTANCE 256
// For more than four players, adjust the respawn times, up to 1/4. // For more than four players, adjust the respawn times, up to 1/4.
int adjustRespawnTime(float respawnTime) int adjustRespawnTime(float preRespawnTime, int itemType, int itemTag)
{ {
float respawnTime = preRespawnTime;
if (itemType == IT_WEAPON)
{
if (itemTag == WP_THERMAL ||
itemTag == WP_TRIP_MINE ||
itemTag == WP_DET_PACK)
{ //special case for these, use ammo respawn rate
respawnTime = RESPAWN_AMMO;
}
}
if (!g_adaptRespawn.integer) if (!g_adaptRespawn.integer)
{ {
return((int)respawnTime); return((int)respawnTime);
@ -670,6 +682,57 @@ void pas_think( gentity_t *ent )
vec3_t enemyDir, org; vec3_t enemyDir, org;
vec3_t frontAngles, backAngles; vec3_t frontAngles, backAngles;
vec3_t desiredAngles; vec3_t desiredAngles;
int iEntityList[MAX_GENTITIES];
int numListedEntities;
int i = 0;
qboolean clTrapped = qfalse;
vec3_t testMins, testMaxs;
testMins[0] = ent->r.currentOrigin[0] + ent->r.mins[0]+4;
testMins[1] = ent->r.currentOrigin[1] + ent->r.mins[1]+4;
testMins[2] = ent->r.currentOrigin[2] + ent->r.mins[2]+4;
testMaxs[0] = ent->r.currentOrigin[0] + ent->r.maxs[0]-4;
testMaxs[1] = ent->r.currentOrigin[1] + ent->r.maxs[1]-4;
testMaxs[2] = ent->r.currentOrigin[2] + ent->r.maxs[2]-4;
numListedEntities = trap_EntitiesInBox( testMins, testMaxs, iEntityList, MAX_GENTITIES );
while (i < numListedEntities)
{
if (iEntityList[i] < MAX_CLIENTS)
{ //client stuck inside me. go nonsolid.
int clNum = iEntityList[i];
numListedEntities = trap_EntitiesInBox( g_entities[clNum].r.absmin, g_entities[clNum].r.absmax, iEntityList, MAX_GENTITIES );
i = 0;
while (i < numListedEntities)
{
if (iEntityList[i] == ent->s.number)
{
clTrapped = qtrue;
break;
}
i++;
}
break;
}
i++;
}
if (clTrapped)
{
ent->r.contents = 0;
ent->s.fireflag = 0;
ent->nextthink = level.time + FRAMETIME;
return;
}
else
{
ent->r.contents = CONTENTS_SOLID;
}
if (!g_entities[ent->boltpoint3].inuse || !g_entities[ent->boltpoint3].client || if (!g_entities[ent->boltpoint3].inuse || !g_entities[ent->boltpoint3].client ||
g_entities[ent->boltpoint3].client->sess.sessionTeam != ent->boltpoint2) g_entities[ent->boltpoint3].client->sess.sessionTeam != ent->boltpoint2)
@ -679,7 +742,7 @@ void pas_think( gentity_t *ent )
return; return;
} }
G_RunObject(ent); // G_RunObject(ent);
if ( !ent->damage ) if ( !ent->damage )
{ {
@ -822,7 +885,7 @@ void pas_think( gentity_t *ent )
{ {
pas_fire( ent ); pas_fire( ent );
ent->s.fireflag = 1; ent->s.fireflag = 1;
ent->attackDebounceTime = level.time + 100; ent->attackDebounceTime = level.time + 200;
} }
else else
{ {
@ -1055,6 +1118,13 @@ int Pickup_Powerup( gentity_t *ent, gentity_t *other ) {
other->client->ps.powerups[ent->item->giTag] += quantity * 1000; other->client->ps.powerups[ent->item->giTag] += quantity * 1000;
if (ent->item->giTag == PW_YSALAMIRI)
{
other->client->ps.powerups[PW_FORCE_ENLIGHTENED_LIGHT] = 0;
other->client->ps.powerups[PW_FORCE_ENLIGHTENED_DARK] = 0;
other->client->ps.powerups[PW_FORCE_BOON] = 0;
}
// give any nearby players a "denied" anti-reward // give any nearby players a "denied" anti-reward
for ( i = 0 ; i < level.maxclients ; i++ ) { for ( i = 0 ; i < level.maxclients ; i++ ) {
vec3_t delta; vec3_t delta;
@ -1114,7 +1184,7 @@ int Pickup_Holdable( gentity_t *ent, gentity_t *other ) {
G_LogWeaponItem(other->s.number, ent->item->giTag); G_LogWeaponItem(other->s.number, ent->item->giTag);
return adjustRespawnTime(RESPAWN_HOLDABLE); return adjustRespawnTime(RESPAWN_HOLDABLE, ent->item->giType, ent->item->giTag);
} }
@ -1140,7 +1210,7 @@ int Pickup_Ammo (gentity_t *ent, gentity_t *other)
Add_Ammo (other, ent->item->giTag, quantity); Add_Ammo (other, ent->item->giTag, quantity);
return adjustRespawnTime(RESPAWN_AMMO); return adjustRespawnTime(RESPAWN_AMMO, ent->item->giType, ent->item->giTag);
} }
//====================================================================== //======================================================================
@ -1194,10 +1264,10 @@ int Pickup_Weapon (gentity_t *ent, gentity_t *other) {
// team deathmatch has slow weapon respawns // team deathmatch has slow weapon respawns
if ( g_gametype.integer == GT_TEAM ) if ( g_gametype.integer == GT_TEAM )
{ {
return adjustRespawnTime(RESPAWN_TEAM_WEAPON); return adjustRespawnTime(RESPAWN_TEAM_WEAPON, ent->item->giType, ent->item->giTag);
} }
return adjustRespawnTime(g_weaponRespawn.integer); return adjustRespawnTime(g_weaponRespawn.integer, ent->item->giType, ent->item->giTag);
} }
@ -1231,7 +1301,7 @@ int Pickup_Health (gentity_t *ent, gentity_t *other) {
return RESPAWN_MEGAHEALTH; return RESPAWN_MEGAHEALTH;
} }
return adjustRespawnTime(RESPAWN_HEALTH); return adjustRespawnTime(RESPAWN_HEALTH, ent->item->giType, ent->item->giTag);
} }
//====================================================================== //======================================================================
@ -1244,7 +1314,7 @@ int Pickup_Armor( gentity_t *ent, gentity_t *other )
other->client->ps.stats[STAT_ARMOR] = other->client->ps.stats[STAT_MAX_HEALTH] * ent->item->giTag; other->client->ps.stats[STAT_ARMOR] = other->client->ps.stats[STAT_MAX_HEALTH] * ent->item->giTag;
} }
return adjustRespawnTime(RESPAWN_ARMOR); return adjustRespawnTime(RESPAWN_ARMOR, ent->item->giType, ent->item->giTag);
} }
//====================================================================== //======================================================================
@ -1372,6 +1442,28 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
break; break;
case IT_AMMO: case IT_AMMO:
respawn = Pickup_Ammo(ent, other); respawn = Pickup_Ammo(ent, other);
if (ent->item->giTag == AMMO_THERMAL || ent->item->giTag == AMMO_TRIPMINE || ent->item->giTag == AMMO_DETPACK)
{
int weapForAmmo = 0;
if (ent->item->giTag == AMMO_THERMAL)
{
weapForAmmo = WP_THERMAL;
}
else if (ent->item->giTag == AMMO_TRIPMINE)
{
weapForAmmo = WP_TRIP_MINE;
}
else
{
weapForAmmo = WP_DET_PACK;
}
if (other && other->client && other->client->ps.ammo[weaponData[weapForAmmo].ammoIndex] > 0 )
{
other->client->ps.stats[STAT_WEAPONS] |= (1 << weapForAmmo);
}
}
// predict = qfalse; // predict = qfalse;
predict = qtrue; predict = qtrue;
break; break;
@ -1419,7 +1511,7 @@ void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
} }
// powerup pickups are global broadcasts // powerup pickups are global broadcasts
if ( ent->item->giType == IT_POWERUP || ent->item->giType == IT_TEAM) { if ( /*ent->item->giType == IT_POWERUP ||*/ ent->item->giType == IT_TEAM) {
// if we want the global sound to play // if we want the global sound to play
if (!ent->speed) { if (!ent->speed) {
gentity_t *te; gentity_t *te;
@ -1631,14 +1723,24 @@ free fall from their spawn points
void FinishSpawningItem( gentity_t *ent ) { void FinishSpawningItem( gentity_t *ent ) {
trace_t tr; trace_t tr;
vec3_t dest; vec3_t dest;
int wDisable = 0;
// gitem_t *item; // gitem_t *item;
// VectorSet( ent->r.mins, -ITEM_RADIUS, -ITEM_RADIUS, -ITEM_RADIUS ); // VectorSet( ent->r.mins, -ITEM_RADIUS, -ITEM_RADIUS, -ITEM_RADIUS );
// VectorSet( ent->r.maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS ); // VectorSet( ent->r.maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS );
if (g_gametype.integer == GT_TOURNAMENT)
{
wDisable = g_duelWeaponDisable.integer;
}
else
{
wDisable = g_weaponDisable.integer;
}
if (ent->item->giType == IT_WEAPON && if (ent->item->giType == IT_WEAPON &&
g_weaponDisable.integer && wDisable &&
(g_weaponDisable.integer & (1 << ent->item->giTag))) (wDisable & (1 << ent->item->giTag)))
{ {
if (g_gametype.integer != GT_JEDIMASTER) if (g_gametype.integer != GT_JEDIMASTER)
{ {
@ -1678,6 +1780,33 @@ void FinishSpawningItem( gentity_t *ent ) {
} }
} }
if (g_gametype.integer == GT_HOLOCRON)
{
if (ent->item->giType == IT_POWERUP)
{
if (ent->item->giTag == PW_FORCE_ENLIGHTENED_LIGHT ||
ent->item->giTag == PW_FORCE_ENLIGHTENED_DARK)
{
G_FreeEntity(ent);
return;
}
}
}
if (g_forcePowerDisable.integer)
{ //if force powers disabled, don't add force powerups
if (ent->item->giType == IT_POWERUP)
{
if (ent->item->giTag == PW_FORCE_ENLIGHTENED_LIGHT ||
ent->item->giTag == PW_FORCE_ENLIGHTENED_DARK ||
ent->item->giTag == PW_FORCE_BOON)
{
G_FreeEntity(ent);
return;
}
}
}
if (g_gametype.integer == GT_TOURNAMENT) if (g_gametype.integer == GT_TOURNAMENT)
{ {
if ( ent->item->giType == IT_ARMOR || if ( ent->item->giType == IT_ARMOR ||
@ -1806,11 +1935,11 @@ void G_CheckTeamItems( void ) {
gitem_t *item; gitem_t *item;
// check for the two flags // check for the two flags
item = BG_FindItem( "Red Flag" ); item = BG_FindItem( "team_CTF_redflag" );
if ( !item || !itemRegistered[ item - bg_itemlist ] ) { if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map" ); G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_redflag in map" );
} }
item = BG_FindItem( "Blue Flag" ); item = BG_FindItem( "team_CTF_blueflag" );
if ( !item || !itemRegistered[ item - bg_itemlist ] ) { if ( !item || !itemRegistered[ item - bg_itemlist ] ) {
G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map" ); G_Printf( S_COLOR_YELLOW "WARNING: No team_CTF_blueflag in map" );
} }
@ -1940,6 +2069,15 @@ void G_BounceItem( gentity_t *ent, trace_t *trace ) {
// cut the velocity to keep from bouncing forever // cut the velocity to keep from bouncing forever
VectorScale( ent->s.pos.trDelta, ent->physicsBounce, ent->s.pos.trDelta ); VectorScale( ent->s.pos.trDelta, ent->physicsBounce, ent->s.pos.trDelta );
if ((ent->s.weapon == WP_DET_PACK && ent->s.eType == ET_GENERAL && ent->physicsObject))
{ //detpacks only
if (ent->touch)
{
ent->touch(ent, &g_entities[trace->entityNum], trace);
return;
}
}
// check for stop // check for stop
if ( trace->plane.normal[2] > 0 && ent->s.pos.trDelta[2] < 40 ) { if ( trace->plane.normal[2] > 0 && ent->s.pos.trDelta[2] < 40 ) {
trace->endpos[2] += 1.0; // make sure it is off ground trace->endpos[2] += 1.0; // make sure it is off ground
@ -1952,6 +2090,15 @@ void G_BounceItem( gentity_t *ent, trace_t *trace ) {
VectorAdd( ent->r.currentOrigin, trace->plane.normal, ent->r.currentOrigin); VectorAdd( ent->r.currentOrigin, trace->plane.normal, ent->r.currentOrigin);
VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase ); VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
ent->s.pos.trTime = level.time; ent->s.pos.trTime = level.time;
if (ent->s.eType == ET_HOLOCRON ||
(ent->s.shouldtarget && ent->s.eType == ET_GENERAL && ent->physicsObject))
{ //holocrons and sentry guns
if (ent->touch)
{
ent->touch(ent, &g_entities[trace->entityNum], trace);
}
}
} }

Some files were not shown because too many files have changed in this diff Show more