Jedi Outcast v056

This commit is contained in:
James Monroe 2013-04-04 13:02:27 -05:00
parent ccbb2c0000
commit b2f9cf6f08
1054 changed files with 451439 additions and 46076 deletions

Binary file not shown.

Binary file not shown.

View file

@ -1,129 +0,0 @@
#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

@ -1,174 +0,0 @@
#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

@ -1,113 +0,0 @@
#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

@ -1,202 +0,0 @@
#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

@ -1,57 +0,0 @@
#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

@ -1,169 +0,0 @@
#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

@ -1,123 +0,0 @@
//#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

@ -1,553 +0,0 @@
#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

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

View file

@ -1,514 +0,0 @@
// 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

@ -1,955 +0,0 @@
// 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;
}

View file

@ -1,789 +0,0 @@
#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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,325 +0,0 @@
#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

@ -1,598 +0,0 @@
//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

View file

@ -1,796 +0,0 @@
//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

Binary file not shown.

View file

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

Binary file not shown.

View file

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

View file

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

View file

@ -443,42 +443,17 @@ CG_DrawHead
Used for both the status bar and the scoreboard
================
*/
void CG_DrawHead( float x, float y, float w, float h, int clientNum, vec3_t headAngles ) {
clipHandle_t cm;
void CG_DrawHead( float x, float y, float w, float h, int clientNum, vec3_t headAngles )
{
clientInfo_t *ci;
float len;
vec3_t origin;
vec3_t mins, maxs;
ci = &cgs.clientinfo[ clientNum ];
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 );
CG_Draw3DModel( x, y, w, h, ci->headModel, ci->headSkin, origin, headAngles );
} else if ( cg_drawIcons.integer ) {
CG_DrawPic( x, y, w, h, ci->modelIcon );
}
CG_DrawPic( x, y, w, h, ci->modelIcon );
// if they are deferred, draw a cross out
if ( ci->deferred ) {
if ( ci->deferred )
{
CG_DrawPic( x, y, w, h, cgs.media.deferShader );
}
}
@ -917,7 +892,20 @@ static void CG_DrawAmmo(centity_t *cent,int x,int y)
if ( cent->currentState.weapon == WP_SABER )
{
// value = cent->gent->client->ps.forcePower;
trap_R_SetColor( colorTable[CT_WHITE] );
// don't need to draw ammo, but we will draw the current saber style in this window
switch ( cg.predictedPlayerState.fd.saberDrawAnimLevel )
{
case 1://FORCE_LEVEL_1:
CG_DrawPic( x, y, 80, 40, cgs.media.HUDSaberStyle1 );
break;
case 2://FORCE_LEVEL_2:
CG_DrawPic( x, y, 80, 40, cgs.media.HUDSaberStyle2 );
break;
case 3://FORCE_LEVEL_3:
CG_DrawPic( x, y, 80, 40, cgs.media.HUDSaberStyle3 );
break;
}
return;
}
else
@ -1551,48 +1539,109 @@ void CG_DrawTeamBackground( int x, int y, int w, int h, float alpha, int team )
/*
================
CG_DrawAttacker
CG_DrawMiniScoreboard
================
*/
static float CG_DrawAttacker( float y ) {
int t;
static float CG_DrawMiniScoreboard ( float y )
{
char temp[MAX_QPATH];
if ( !cg_drawScores.integer )
{
return y;
}
if ( cgs.gametype >= GT_TEAM )
{
strcpy ( temp, "Red: " );
Q_strcat ( temp, MAX_QPATH, cgs.scores1==SCORE_NOT_PRESENT?"-":(va("%i",cgs.scores1)) );
Q_strcat ( temp, MAX_QPATH, " Blue: " );
Q_strcat ( temp, MAX_QPATH, cgs.scores2==SCORE_NOT_PRESENT?"-":(va("%i",cgs.scores2)) );
CG_Text_Paint( 630 - CG_Text_Width ( temp, 0.75f, FONT_SMALL ), y, 0.75f, colorWhite, temp, 0, 0, 0, FONT_SMALL );
y += 15;
}
else
{
strcpy ( temp, "1st: " );
Q_strcat ( temp, MAX_QPATH, cgs.scores1==SCORE_NOT_PRESENT?"-":(va("%i",cgs.scores1)) );
Q_strcat ( temp, MAX_QPATH, " 2nd: " );
Q_strcat ( temp, MAX_QPATH, cgs.scores2==SCORE_NOT_PRESENT?"-":(va("%i",cgs.scores2)) );
CG_Text_Paint( 630 - CG_Text_Width ( temp, 0.75f, FONT_SMALL ), y, 0.75f, colorWhite, temp, 0, 0, 0, FONT_SMALL );
y += 15;
}
return y;
}
/*
================
CG_DrawEnemyInfo
================
*/
static float CG_DrawEnemyInfo ( float y )
{
float size;
vec3_t angles;
const char *info;
const char *name;
int clientNum;
const char *title;
clientInfo_t *ci;
if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) {
if ( !cg_drawEnemyInfo.integer )
{
return y;
}
if ( !cg.attackerTime ) {
if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 )
{
return y;
}
if ( cgs.gametype == GT_JEDIMASTER )
{
title = "Jedi Master";
clientNum = cgs.jediMaster;
if ( clientNum < 0 )
{
return y;
}
}
else if ( cg.snap->ps.duelInProgress )
{
title = "Dueling";
clientNum = cg.snap->ps.duelIndex;
}
else
{
title = "Attacker";
clientNum = cg.predictedPlayerState.persistant[PERS_ATTACKER];
if ( clientNum < 0 || clientNum >= MAX_CLIENTS || clientNum == cg.snap->ps.clientNum )
{
return y;
}
if ( cg.time - cg.attackerTime > ATTACKER_HEAD_TIME )
{
cg.attackerTime = 0;
return y;
}
}
clientNum = cg.predictedPlayerState.persistant[PERS_ATTACKER];
if ( clientNum < 0 || clientNum >= MAX_CLIENTS || clientNum == cg.snap->ps.clientNum ) {
return y;
}
t = cg.time - cg.attackerTime;
if ( t > ATTACKER_HEAD_TIME ) {
cg.attackerTime = 0;
return y;
}
ci = &cgs.clientinfo[ clientNum ];
size = ICON_SIZE * 1.25;
y += 5;
angles[PITCH] = 0;
angles[YAW] = 180;
angles[ROLL] = 0;
CG_DrawHead( 640 - size, y, size, size, clientNum, angles );
CG_DrawPic( 640 - size - 5, y, size, size, ci->modelIcon );
info = CG_ConfigString( CS_PLAYERS + clientNum );
name = Info_ValueForKey( info, "n" );
y += size;
CG_DrawBigString( 640 - ( Q_PrintStrlen( name ) * BIGCHAR_WIDTH), y, name, 0.5 );
CG_Text_Paint( 630 - CG_Text_Width ( ci->name, 0.75f, FONT_SMALL ), y, 0.75f, colorWhite, ci->name, 0, 0, 0, FONT_SMALL );
y += 15;
CG_Text_Paint( 630 - CG_Text_Width ( title, 0.75f, FONT_SMALL ), y, 0.75f, colorWhite, title, 0, 0, 0, FONT_SMALL );
return y + BIGCHAR_HEIGHT + 2;
}
@ -1884,10 +1933,10 @@ static void CG_DrawUpperRight( void ) {
if ( cg_drawTimer.integer ) {
y = CG_DrawTimer( y );
}
if ( cg_drawAttacker.integer ) {
y = CG_DrawAttacker( y );
}
y = CG_DrawEnemyInfo ( y );
y = CG_DrawMiniScoreboard ( y );
}
/*
@ -2037,6 +2086,18 @@ static void CG_DrawDisconnect( void ) {
const char *s;
int w; // bk010215 - FIXME char message[1024];
if (cg.mMapChange)
{
s = "Server Changing Maps";
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
CG_DrawBigString( 320 - w/2, 100, s, 1.0F);
s = "Please wait...";
w = CG_DrawStrlen( s ) * BIGCHAR_WIDTH;
CG_DrawBigString( 320 - w/2, 200, s, 1.0F);
return;
}
// draw the phone jack if we are completely past our buffers
cmdNum = trap_GetCurrentCmdNumber() - CMD_BACKUP + 1;
trap_GetUserCmd( cmdNum, &cmd );
@ -2634,6 +2695,17 @@ static void CG_DrawRocketLocking( int lockEntNum, int lockTime )
return;
}
//We can't check to see in pmove if players are on the same team, so we resort
//to just not drawing the lock if a teammate is the locked on ent
if (cg.snap->ps.rocketLockIndex >= 0 &&
cg.snap->ps.rocketLockIndex < MAX_CLIENTS)
{
if (cgs.clientinfo[cg.snap->ps.rocketLockIndex].team == cgs.clientinfo[cg.snap->ps.clientNum].team)
{
return;
}
}
if (cg.snap->ps.rocketLockTime != -1)
{
lastvalidlockdif = dif;
@ -2865,13 +2937,15 @@ static void CG_DrawCrosshairNames( void ) {
if ( !cg_drawCrosshair.integer ) {
return;
}
if ( !cg_drawCrosshairNames.integer ) {
return;
}
// scan the known entities to see if the crosshair is sighted on one
CG_ScanForCrosshairEntity();
if ( !cg_drawCrosshairNames.integer ) {
return;
}
//rww - still do the trace, our dynamic crosshair depends on it
if (cg.crosshairClientNum >= MAX_CLIENTS)
{
return;
@ -3015,12 +3089,49 @@ static void CG_DrawTeamVote(void) {
if ( sec < 0 ) {
sec = 0;
}
s = va("TEAMVOTE(%i):%s yes:%i no:%i", sec, cgs.teamVoteString[cs_offset],
cgs.teamVoteYes[cs_offset], cgs.teamVoteNo[cs_offset] );
if (strstr(cgs.teamVoteString[cs_offset], "leader"))
{
int i = 0;
while (cgs.teamVoteString[cs_offset][i] && cgs.teamVoteString[cs_offset][i] != ' ')
{
i++;
}
if (cgs.teamVoteString[cs_offset][i] == ' ')
{
int voteIndex = 0;
char voteIndexStr[256];
i++;
while (cgs.teamVoteString[cs_offset][i])
{
voteIndexStr[voteIndex] = cgs.teamVoteString[cs_offset][i];
voteIndex++;
i++;
}
voteIndexStr[voteIndex] = 0;
voteIndex = atoi(voteIndexStr);
s = va("TEAMVOTE(%i):(Make %s the new team leader) yes:%i no:%i", sec, cgs.clientinfo[voteIndex].name,
cgs.teamVoteYes[cs_offset], cgs.teamVoteNo[cs_offset] );
}
else
{
s = va("TEAMVOTE(%i):%s yes:%i no:%i", sec, cgs.teamVoteString[cs_offset],
cgs.teamVoteYes[cs_offset], cgs.teamVoteNo[cs_offset] );
}
}
else
{
s = va("TEAMVOTE(%i):%s yes:%i no:%i", sec, cgs.teamVoteString[cs_offset],
cgs.teamVoteYes[cs_offset], cgs.teamVoteNo[cs_offset] );
}
CG_DrawSmallString( 0, 90, s, 1.0F );
}
static qboolean CG_DrawScoreboard() {
return CG_DrawOldScoreboard();
#if 0

View file

@ -644,7 +644,7 @@ static void CG_General( centity_t *cent ) {
else
*/
{
anim = &ci->animations[ limb_anim ];
anim = &bgGlobalAnimations[ limb_anim ];
}
}
@ -1140,9 +1140,20 @@ Ghoul2 Insert End
}
else
{ //neutral
ent.shaderRGBA[0] = 0;
ent.shaderRGBA[1] = wv*255;
ent.shaderRGBA[2] = wv*255;
if ((s1->modelindex+128) == FP_SABERATTACK ||
(s1->modelindex+128) == FP_SABERDEFEND ||
(s1->modelindex+128) == FP_SABERTHROW)
{ //saber power
ent.shaderRGBA[0] = 0;
ent.shaderRGBA[1] = wv*255;
ent.shaderRGBA[2] = 0;
}
else
{
ent.shaderRGBA[0] = 0;
ent.shaderRGBA[1] = wv*255;
ent.shaderRGBA[2] = wv*255;
}
}
ent.modelScale[0] = 1.1;
@ -1175,8 +1186,8 @@ Ghoul2 Insert End
if (cent->currentState.trickedentindex3 == 1)
{ //dark
fxSArgs.sAlpha *= 2;
fxSArgs.eAlpha *= 2;
fxSArgs.sAlpha *= 3;
fxSArgs.eAlpha *= 3;
fxSArgs.shader = cgs.media.redSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
}
@ -1193,12 +1204,24 @@ Ghoul2 Insert End
}
else
{ //neutral
fxSArgs.sAlpha *= 0.5;
fxSArgs.eAlpha *= 0.5;
fxSArgs.shader = cgs.media.greenSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
fxSArgs.shader = cgs.media.blueSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
if ((s1->modelindex+128) == FP_SABERATTACK ||
(s1->modelindex+128) == FP_SABERDEFEND ||
(s1->modelindex+128) == FP_SABERTHROW)
{ //saber power
fxSArgs.sAlpha *= 1.5;
fxSArgs.eAlpha *= 1.5;
fxSArgs.shader = cgs.media.greenSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
}
else
{
fxSArgs.sAlpha *= 0.5;
fxSArgs.eAlpha *= 0.5;
fxSArgs.shader = cgs.media.greenSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
fxSArgs.shader = cgs.media.blueSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
}
}
}

View file

@ -322,13 +322,13 @@ clientkilled:
message = "KILLED_TELEFRAG";
break;
case MOD_CRUSH:
message = "KILLED_FORCETOSS";
message = "KILLED_GENERIC";//"KILLED_FORCETOSS";
break;
case MOD_FALLING:
message = "KILLED_FORCETOSS";
break;
case MOD_TRIGGER_HURT:
message = "KILLED_FORCETOSS";
message = "KILLED_GENERIC";//"KILLED_FORCETOSS";
break;
default:
message = "KILLED_GENERIC";
@ -439,7 +439,7 @@ static void CG_UseItem( centity_t *cent ) {
ci = &cgs.clientinfo[ clientNum ];
ci->medkitUsageTime = cg.time;
}
trap_S_StartSound (NULL, es->number, CHAN_BODY, cgs.media.medkitSound );
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.medkitSound );
break;
}
@ -649,14 +649,14 @@ static void CG_BodyQueueCopy(centity_t *cent, int clientNum, int knownWeapon)
trap_G2API_CopySpecificGhoul2Model(g2WeaponInstances[knownWeapon], 0, cent->ghoul2, 1);
}
anim = &ci->animations[ cent->currentState.torsoAnim ];
anim = &bgGlobalAnimations[ cent->currentState.torsoAnim ];
animSpeed = 50.0f / anim->frameLerp;
//this will just set us to the last frame of the animation, in theory
if (source->isATST)
{
int aNum = cgs.clientinfo[source->currentState.number].frame+1;
anim = &ci->animations[ BOTH_DEAD1 ];
anim = &bgGlobalAnimations[ BOTH_DEAD1 ];
animSpeed = 1;
flags &= ~BONE_ANIM_OVERRIDE_LOOP;
@ -837,14 +837,14 @@ void DoFall(centity_t *cent, entityState_t *es, int clientNum)
{
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.fallSound );
trap_S_StartSound( NULL, cent->currentState.number, CHAN_VOICE,
CG_CustomSound( cent->currentState.number, "*fall1.wav" ) );
CG_CustomSound( cent->currentState.number, "*land1.wav" ) );
cent->pe.painTime = cg.time; // don't play a pain sound right after this
}
else if (delta > 44)
{
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.fallSound );
trap_S_StartSound( NULL, cent->currentState.number, CHAN_VOICE,
CG_CustomSound( cent->currentState.number, "*fall1.wav" ) );
CG_CustomSound( cent->currentState.number, "*land1.wav" ) );
cent->pe.painTime = cg.time; // don't play a pain sound right after this
}
else
@ -1022,23 +1022,6 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
case EV_JUMP_PAD:
DEBUGNAME("EV_JUMP_PAD");
// CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm );
{
localEntity_t *smoke;
vec3_t up = {0, 0, 1};
smoke = CG_SmokePuff( cent->lerpOrigin, up,
32,
1, 1, 1, 0.33f,
1000,
cg.time, 0,
LEF_PUFF_DONT_SCALE,
cgs.media.smokePuffShader );
}
// boing sound at origin, jump sound on player
trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) );
break;
case EV_PRIVATE_DUEL:
@ -1142,7 +1125,7 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
index = cg_entities[es->eventParm].currentState.modelindex; // player predicted
if (index < 1)
if (index < 1 && cg_entities[es->eventParm].currentState.isJediMaster)
{ //a holocron most likely
index = cg_entities[es->eventParm].currentState.trickedentindex4;
trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.holocronPickup );
@ -1444,11 +1427,35 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
case EV_DISRUPTOR_MAIN_SHOT:
DEBUGNAME("EV_DISRUPTOR_MAIN_SHOT");
if (cent->currentState.eventParm != cg.snap->ps.clientNum ||
cg.renderingThirdPerson)
{ //h4q3ry
CG_GetClientWeaponMuzzleBoltPoint(cent->currentState.eventParm, cent->currentState.origin2);
}
else
{
if (cg.lastFPFlashPoint[0] ||cg.lastFPFlashPoint[1] || cg.lastFPFlashPoint[2])
{ //get the position of the muzzle flash for the first person weapon model from the last frame
VectorCopy(cg.lastFPFlashPoint, cent->currentState.origin2);
}
}
FX_DisruptorMainShot( cent->currentState.origin2, cent->lerpOrigin );
break;
case EV_DISRUPTOR_SNIPER_SHOT:
DEBUGNAME("EV_DISRUPTOR_SNIPER_SHOT");
if (cent->currentState.eventParm != cg.snap->ps.clientNum ||
cg.renderingThirdPerson)
{ //h4q3ry
CG_GetClientWeaponMuzzleBoltPoint(cent->currentState.eventParm, cent->currentState.origin2);
}
else
{
if (cg.lastFPFlashPoint[0] ||cg.lastFPFlashPoint[1] || cg.lastFPFlashPoint[2])
{ //get the position of the muzzle flash for the first person weapon model from the last frame
VectorCopy(cg.lastFPFlashPoint, cent->currentState.origin2);
}
}
FX_DisruptorAltShot( cent->currentState.origin2, cent->lerpOrigin, cent->currentState.shouldtarget );
break;
@ -1779,6 +1786,9 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
case EFFECT_EXPLOSION:
eID = trap_FX_RegisterEffect("emplaced/explode.efx");
break;
case EFFECT_EXPLOSION_PAS:
eID = trap_FX_RegisterEffect("turret/explode.efx");
break;
case EFFECT_SPARK_EXPLOSION:
eID = trap_FX_RegisterEffect("spark_explosion.efx");
break;
@ -1805,18 +1815,54 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
if (eID != -1)
{
trap_FX_PlayEffectID(eID, es->origin, es->angles);
vec3_t fxDir;
VectorCopy(es->angles, fxDir);
if (!fxDir[0] && !fxDir[1] && !fxDir[2])
{
fxDir[1] = 1;
}
trap_FX_PlayEffectID(eID, es->origin, fxDir);
}
break;
case EV_PLAY_EFFECT_ID:
DEBUGNAME("EV_PLAY_EFFECT_ID");
{
vec3_t fxDir;
AngleVectors(es->angles, fxDir, 0, 0);
if (!fxDir[0] && !fxDir[1] && !fxDir[2])
{
fxDir[1] = 1;
}
if ( cgs.gameEffects[ es->eventParm ] )
{
trap_FX_PlayEffectID(cgs.gameEffects[es->eventParm], es->origin, fxDir );
}
else
{
s = CG_ConfigString( CS_EFFECTS + es->eventParm );
if (s && s[0])
{
trap_FX_PlayEffectID(trap_FX_RegisterEffect(s), es->origin, fxDir );
}
}
}
break;
case EV_MUTE_SOUND:
DEBUGNAME("EV_MUTE_SOUND");
if (cg_entities[es->eventParm].currentState.eFlags & EF_SOUNDTRACKER)
if (cg_entities[es->trickedentindex2].currentState.eFlags & EF_SOUNDTRACKER)
{
cg_entities[es->eventParm].currentState.eFlags -= EF_SOUNDTRACKER;
cg_entities[es->trickedentindex2].currentState.eFlags -= EF_SOUNDTRACKER;
}
trap_S_MuteSound(es->eventParm, es->trickedentindex);
trap_S_StopLoopingSound(es->eventParm);
trap_S_MuteSound(es->trickedentindex2, es->trickedentindex);
trap_S_StopLoopingSound(es->trickedentindex2);
break;
case EV_GENERAL_SOUND:

View file

@ -515,8 +515,6 @@ typedef struct {
qhandle_t modelIcon;
animation_t animations[MAX_TOTALANIMATIONS];
qhandle_t bolt_rhand;
qhandle_t bolt_lhand;
@ -530,6 +528,9 @@ typedef struct {
int saberHitWallSoundDebounceTime;
sfxHandle_t sounds[MAX_CUSTOM_SOUNDS];
int legsAnim;
int torsoAnim;
} clientInfo_t;
@ -649,6 +650,8 @@ typedef struct {
float frameInterpolation; // (float)( cg.time - cg.frame->serverTime ) / (cg.nextFrame->serverTime - cg.frame->serverTime)
qboolean mMapChange;
qboolean thisFrameTeleport;
qboolean nextFrameTeleport;
@ -840,6 +843,8 @@ typedef struct {
float invenSelectTime;
float forceSelectTime;
vec3_t lastFPFlashPoint;
/*
Ghoul2 Insert Start
*/
@ -1159,6 +1164,10 @@ typedef struct {
qhandle_t HUDLeftStatic;
qhandle_t HUDLeft;
qhandle_t HUDSaberStyle1;
qhandle_t HUDSaberStyle2;
qhandle_t HUDSaberStyle3;
qhandle_t HUDRightFrame;
qhandle_t HUDInnerRight;
@ -1301,6 +1310,7 @@ typedef struct {
int levelStartTime;
int scores1, scores2; // from configstrings
int jediMaster;
int redflag, blueflag; // flag status from configstrings
int flagStatus;
@ -1311,6 +1321,7 @@ typedef struct {
//
qhandle_t gameModels[MAX_MODELS];
sfxHandle_t gameSounds[MAX_SOUNDS];
fxHandle_t gameEffects[MAX_FX];
/*
Ghoul2 Insert Start
*/
@ -1383,6 +1394,7 @@ extern vmCvar_t cg_drawIcons;
extern vmCvar_t cg_drawAmmoWarning;
extern vmCvar_t cg_drawCrosshair;
extern vmCvar_t cg_drawCrosshairNames;
extern vmCvar_t cg_drawScores;
extern vmCvar_t cg_dynamicCrosshair;
extern vmCvar_t cg_drawRewards;
extern vmCvar_t cg_drawTeamOverlay;
@ -1441,7 +1453,7 @@ extern vmCvar_t cg_thirdPersonHorzOffset;
extern vmCvar_t cg_stereoSeparation;
extern vmCvar_t cg_lagometer;
extern vmCvar_t cg_drawAttacker;
extern vmCvar_t cg_drawEnemyInfo;
extern vmCvar_t cg_synchronousClients;
extern vmCvar_t cg_teamChatTime;
extern vmCvar_t cg_teamChatHeight;
@ -1685,6 +1697,8 @@ void TurretClientRun(centity_t *ent);
//
// cg_weapons.c
//
void CG_GetClientWeaponMuzzleBoltPoint(int clIndex, vec3_t to);
void CG_NextWeapon_f( void );
void CG_PrevWeapon_f( void );
void CG_Weapon_f( void );
@ -2175,10 +2189,3 @@ extern void *g2WeaponInstances[MAX_WEAPONS];
/*
Ghoul2 Insert End
*/
enum {
FONT_NONE,
FONT_SMALL=1,
FONT_MEDIUM,
FONT_LARGE
};

View file

@ -235,6 +235,13 @@ int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int a
C_ImpactMark();
return 0;
case CG_MAP_CHANGE:
// this trap map be called more than once for a given map change, as the
// server is going to attempt to send out multiple broadcasts in hopes that
// the client will receive one of them
cg.mMapChange = qtrue;
return 0;
default:
CG_Error( "vmMain: unknown command %i", command );
break;
@ -369,6 +376,7 @@ vmCvar_t cg_drawCrosshair;
vmCvar_t cg_drawCrosshairNames;
vmCvar_t cg_dynamicCrosshair;
vmCvar_t cg_drawRewards;
vmCvar_t cg_drawScores;
vmCvar_t cg_crosshairSize;
vmCvar_t cg_crosshairX;
vmCvar_t cg_crosshairY;
@ -424,7 +432,7 @@ vmCvar_t cg_thirdPersonHorzOffset;
vmCvar_t cg_stereoSeparation;
vmCvar_t cg_lagometer;
vmCvar_t cg_drawAttacker;
vmCvar_t cg_drawEnemyInfo;
vmCvar_t cg_synchronousClients;
vmCvar_t cg_teamChatTime;
vmCvar_t cg_teamChatHeight;
@ -502,9 +510,10 @@ static cvarTable_t cvarTable[] = { // bk001129
{ &cg_draw3dIcons, "cg_draw3dIcons", "1", CVAR_ARCHIVE },
{ &cg_drawIcons, "cg_drawIcons", "1", CVAR_ARCHIVE },
{ &cg_drawAmmoWarning, "cg_drawAmmoWarning", "0", CVAR_ARCHIVE },
{ &cg_drawAttacker, "cg_drawAttacker", "1", CVAR_ARCHIVE },
{ &cg_drawEnemyInfo, "cg_drawEnemyInfo", "1", CVAR_ARCHIVE },
{ &cg_drawCrosshair, "cg_drawCrosshair", "1", CVAR_ARCHIVE },
{ &cg_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE },
{ &cg_drawScores, "cg_drawScores", "1", CVAR_ARCHIVE },
{ &cg_dynamicCrosshair, "cg_dynamicCrosshair", "1", CVAR_ARCHIVE },
{ &cg_drawRewards, "cg_drawRewards", "1", CVAR_ARCHIVE },
{ &cg_crosshairSize, "cg_crosshairSize", "24", CVAR_ARCHIVE },
@ -549,14 +558,14 @@ static cvarTable_t cvarTable[] = { // bk001129
{ &cg_dismember, "cg_dismember", "0", 0 },
{ &cg_thirdPerson, "cg_thirdPerson", "0", 0 },
{ &cg_thirdPersonRange, "cg_thirdPersonRange", "80", 0 },
{ &cg_thirdPersonAngle, "cg_thirdPersonAngle", "0", 0 },
{ &cg_thirdPersonPitchOffset, "cg_thirdPersonPitchOffset", "0", 0 },
{ &cg_thirdPersonVertOffset, "cg_thirdPersonVertOffset", "16", 0},
{ &cg_thirdPersonCameraDamp, "cg_thirdPersonCameraDamp", "0.3", 0},
{ &cg_thirdPersonTargetDamp, "cg_thirdPersonTargetDamp", "0.5", 0},
{ &cg_thirdPersonRange, "cg_thirdPersonRange", "80", CVAR_CHEAT },
{ &cg_thirdPersonAngle, "cg_thirdPersonAngle", "0", CVAR_CHEAT },
{ &cg_thirdPersonPitchOffset, "cg_thirdPersonPitchOffset", "0", CVAR_CHEAT },
{ &cg_thirdPersonVertOffset, "cg_thirdPersonVertOffset", "16", CVAR_CHEAT },
{ &cg_thirdPersonCameraDamp, "cg_thirdPersonCameraDamp", "0.3", CVAR_CHEAT },
{ &cg_thirdPersonTargetDamp, "cg_thirdPersonTargetDamp", "0.5", CVAR_CHEAT },
{ &cg_thirdPersonHorzOffset, "cg_thirdPersonHorzOffset", "0", 0},
{ &cg_thirdPersonHorzOffset, "cg_thirdPersonHorzOffset", "0", CVAR_CHEAT },
{ &cg_thirdPersonAlpha, "cg_thirdPersonAlpha", "1.0", CVAR_CHEAT },
{ &cg_teamChatTime, "cg_teamChatTime", "3000", CVAR_ARCHIVE },
@ -923,10 +932,12 @@ static void CG_RegisterSounds( void ) {
trap_S_RegisterSound(va("sound/weapons/saber/bounce%i.wav", i));
}
trap_S_RegisterSound( "sound/weapons/saber/saberhum.wav" );
trap_S_RegisterSound( "sound/weapons/saber/saberhum1.wav" );
trap_S_RegisterSound( "sound/weapons/saber/saberon.wav" );
trap_S_RegisterSound( "sound/weapons/saber/saberoffquick.wav" );
trap_S_RegisterSound( "sound/weapons/saber/saberhitwall.wav" );
trap_S_RegisterSound( "sound/weapons/saber/saberhitwall1" );
trap_S_RegisterSound( "sound/weapons/saber/saberhitwall2" );
trap_S_RegisterSound( "sound/weapons/saber/saberhitwall3" );
trap_S_RegisterSound("sound/weapons/saber/saberhit.wav");
trap_S_RegisterSound("sound/weapons/force/heal.wav");
@ -1073,7 +1084,7 @@ static void CG_RegisterSounds( void ) {
cgs.media.zoomEnd = trap_S_RegisterSound( "sound/interface/zoomend.wav" );
for (i=0 ; i<4 ; i++) {
Com_sprintf (name, sizeof(name), "sound/player/footsteps/step%i.wav", i+1);
Com_sprintf (name, sizeof(name), "sound/player/footsteps/boot%i.wav", i+1);
cgs.media.footsteps[FOOTSTEP_NORMAL][i] = trap_S_RegisterSound (name);
Com_sprintf (name, sizeof(name), "sound/player/footsteps/splash%i.wav", i+1);
@ -1083,7 +1094,7 @@ static void CG_RegisterSounds( void ) {
cgs.media.footsteps[FOOTSTEP_METAL][i] = trap_S_RegisterSound (name);
// should these always be registered??
Com_sprintf (name, sizeof(name), "sound/player/footsteps/boot%i.wav", i+1);
Com_sprintf (name, sizeof(name), "sound/player/footsteps/step%i.wav", i+1);
trap_S_RegisterSound (name);
}
@ -1107,6 +1118,17 @@ static void CG_RegisterSounds( void ) {
cgs.gameSounds[i] = trap_S_RegisterSound( soundName );
}
for ( i = 1 ; i < MAX_FX ; i++ ) {
soundName = CG_ConfigString( CS_EFFECTS+i );
if ( !soundName[0] ) {
break;
}
if ( soundName[0] == '*' ) {
continue; // custom sound
}
cgs.gameEffects[i] = trap_FX_RegisterEffect( soundName );
}
cg.loadLCARSStage = 2;
// FIXME: only needed with item
@ -1254,10 +1276,8 @@ static void CG_RegisterGraphics( void ) {
trap_FX_RegisterEffect("emplaced/dead_smoke.efx");
trap_FX_RegisterEffect("emplaced/explode.efx");
if (cg_buildScript.integer)
{
trap_FX_RegisterEffect("emplaced/explode.efx");
}
trap_FX_RegisterEffect("turret/explode.efx");
trap_FX_RegisterEffect("spark_explosion.efx");
trap_FX_RegisterEffect("effects/turret/muzzle_flash.efx");
@ -2328,6 +2348,7 @@ Ghoul2 Insert End
cgs.media.loadBarLEDSurround= trap_R_RegisterShaderNoMip( "gfx/hud/mp_levelload" );
//rww - precache HUD weapon icons here
//actually, these should be stored in the icon field of each item def
cgs.media.weaponIcons[WP_STUN_BATON] = trap_R_RegisterShaderNoMip("gfx/hud/w_icon_stunbaton");
cgs.media.weaponIcons_NA[WP_STUN_BATON] = trap_R_RegisterShaderNoMip("gfx/hud/w_icon_stunbaton_na");
@ -2417,6 +2438,10 @@ Ghoul2 Insert End
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.HUDSaberStyle1 = trap_R_RegisterShader( "gfx/hud/saber_styles1" );
cgs.media.HUDSaberStyle2 = trap_R_RegisterShader( "gfx/hud/saber_styles2" );
cgs.media.HUDSaberStyle3 = trap_R_RegisterShader( "gfx/hud/saber_styles3" );
cgs.media.HUDRightFrame = trap_R_RegisterShaderNoMip("gfx/hud/hudrightframe");
cgs.media.HUDInnerRight = trap_R_RegisterShaderNoMip( "gfx/hud/hudright_innerframe" );

View file

@ -4,7 +4,6 @@
#include "cg_local.h"
#include "..\ghoul2\g2.h"
extern stringID_table_t animTable [MAX_ANIMATIONS+1];
char *cg_customSoundNames[MAX_CUSTOM_SOUNDS] = {
@ -21,7 +20,7 @@ char *cg_customSoundNames[MAX_CUSTOM_SOUNDS] = {
"*choke2.wav",
"*choke3.wav",
"*gasp.wav",
"*fall1.wav",
"*land1.wav",
"*falling1.wav",
"*taunt.wav"
};
@ -288,6 +287,10 @@ static qboolean CG_RegisterClientSkin( clientInfo_t *ci, const char *teamName, c
if ( !ci->legsSkin || !ci->torsoSkin || !ci->headSkin ) {
return qfalse;
}
// Model icon for drawing the portrait on screen
ci->modelIcon = trap_R_RegisterShaderNoMip ( va ( "models/players/%s/icon_%s", modelName, skinName ) );
return qtrue;
}
@ -405,66 +408,67 @@ retryModel:
GLAName[0] = 0;
//get the location of the animation.cfg
//GLAName = trap_G2API_GetGLAName( ci->ghoul2Model, 0);
trap_G2API_GetGLAName( ci->ghoul2Model, 0, GLAName);
if (GLAName[0] == 0/*GLAName == NULL*/)
if (!BGPAFtextLoaded)
{
if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg", ci->animations))
trap_G2API_GetGLAName( ci->ghoul2Model, 0, GLAName);
if (GLAName[0] == 0/*GLAName == NULL*/)
{
Com_Printf( "Failed to load animation file %s\n", afilename );
if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg"))
{
Com_Printf( "Failed to load animation file %s\n", afilename );
return qfalse;
}
return qtrue;
}
Q_strncpyz( afilename, GLAName, sizeof( afilename ));
slash = Q_strrchr( afilename, '/' );
if ( slash )
{
strcpy(slash, "/animation.cfg");
} // Now afilename holds just the path to the animation.cfg
else
{ // Didn't find any slashes, this is a raw filename right in base (whish isn't a good thing)
return qfalse;
}
return qtrue;
}
Q_strncpyz( afilename, GLAName, sizeof( afilename ));
slash = Q_strrchr( afilename, '/' );
if ( slash )
{
strcpy(slash, "/animation.cfg");
} // Now afilename holds just the path to the animation.cfg
else
{ // Didn't find any slashes, this is a raw filename right in base (whish isn't a good thing)
return qfalse;
}
/*
// Try to load the animation.cfg for this model then.
if ( !BG_ParseAnimationFile( afilename, ci->animations ) )
{ // The GLA's animations failed
if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg", ci->animations))
{
Com_Printf( "Failed to load animation file %s\n", afilename );
return qfalse;
}
}
*/
//rww - For now, we'll just ignore what animation file it wants. In theory all multiplayer-supported models
//should want _humanoid/animation.cfg, so if it doesn't want that then throw it away
if (Q_stricmp(afilename, "models/players/_humanoid/animation.cfg"))
{
Com_Printf( "Model does not use supported animation config.\n");
return qfalse;
}
else if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg", ci->animations))
{
Com_Printf( "Failed to load animation file models/players/_humanoid/animation.cfg\n" );
return qfalse;
}
else if (!retriedAlready)
{
int i;
for(i = 0; i < MAX_ANIMATIONS; i++)
/*
// Try to load the animation.cfg for this model then.
if ( !BG_ParseAnimationFile( afilename, ci->animations ) )
{ // The GLA's animations failed
if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg", ci->animations))
{
Com_Printf( "Failed to load animation file %s\n", afilename );
return qfalse;
}
}
*/
//rww - For now, we'll just ignore what animation file it wants. In theory all multiplayer-supported models
//should want _humanoid/animation.cfg, so if it doesn't want that then throw it away
if (Q_stricmp(afilename, "models/players/_humanoid/animation.cfg"))
{
if (!ci->animations[i].firstFrame && !ci->animations[i].numFrames && CG_NeedAnimSequence(i))
{ //using default for this animation so it obviously never got filled in.
//if it's a sequence that we need, this model must be an unsupported one.
badModel = qtrue;
goto retryModel;
Com_Printf( "Model does not use supported animation config.\n");
return qfalse;
}
else if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg"))
{
Com_Printf( "Failed to load animation file models/players/_humanoid/animation.cfg\n" );
return qfalse;
}
else if (!retriedAlready)
{
int i;
for(i = 0; i < MAX_ANIMATIONS; i++)
{
if (!bgGlobalAnimations[i].firstFrame && !bgGlobalAnimations[i].numFrames && CG_NeedAnimSequence(i))
{ //using default for this animation so it obviously never got filled in.
//if it's a sequence that we need, this model must be an unsupported one.
badModel = qtrue;
goto retryModel;
}
}
}
}
// NOTE - ensure this sequence of bolt and bone accessing are always the same because the client expects them in a certain order
if (clientNum != -1 && cg_entities[clientNum].currentState.teamowner && !cg_entities[clientNum].isATST)
{
@ -523,7 +527,7 @@ retryModel:
{
animation_t *anim;
anim = &ci->animations[ (cg_entities[clientNum].currentState.legsAnim & ~ANIM_TOGGLEBIT) ];
anim = &bgGlobalAnimations[ (cg_entities[clientNum].currentState.legsAnim & ~ANIM_TOGGLEBIT) ];
if (anim)
{
@ -542,7 +546,7 @@ retryModel:
cg_entities[clientNum].currentState.legsAnim = 0;
}
anim = &ci->animations[ (cg_entities[clientNum].currentState.torsoAnim & ~ANIM_TOGGLEBIT) ];
anim = &bgGlobalAnimations[ (cg_entities[clientNum].currentState.torsoAnim & ~ANIM_TOGGLEBIT) ];
if (anim)
{
@ -575,6 +579,9 @@ retryModel:
Com_sprintf(ci->teamName, sizeof(ci->teamName), teamName);
// Model icon for drawing the portrait on screen
ci->modelIcon = trap_R_RegisterShaderNoMip ( va ( "models/players/%s/icon_%s", modelName, skinName ) );
return qtrue;
}
@ -848,7 +855,6 @@ static void CG_CopyClientInfoModel( clientInfo_t *from, clientInfo_t *to ) {
// to->ATST = from->ATST;
memcpy( to->animations, from->animations, sizeof( to->animations ) );
memcpy( to->sounds, from->sounds, sizeof( to->sounds ) );
}
@ -1192,7 +1198,7 @@ void CG_NewClientInfo( int clientNum, qboolean entitiesInitialized ) {
animation_t *anim;
// First check if we have a ghoul2 model on the client entity.
anim = &ci->animations[ (cg_entities[clientNum].currentState.legsAnim & ~ANIM_TOGGLEBIT) ];
anim = &bgGlobalAnimations[ (cg_entities[clientNum].currentState.legsAnim & ~ANIM_TOGGLEBIT) ];
if (anim)
{
@ -1211,7 +1217,7 @@ void CG_NewClientInfo( int clientNum, qboolean entitiesInitialized ) {
cg_entities[clientNum].currentState.legsAnim = 0;
}
anim = &ci->animations[ (cg_entities[clientNum].currentState.torsoAnim & ~ANIM_TOGGLEBIT) ];
anim = &bgGlobalAnimations[ (cg_entities[clientNum].currentState.torsoAnim & ~ANIM_TOGGLEBIT) ];
if (anim)
{
@ -1494,7 +1500,7 @@ static void CG_SetLerpFrameAnimation( centity_t *cent, clientInfo_t *ci, lerpFra
CG_Error( "Bad animation number: %i", newAnimation );
}
anim = &ci->animations[ newAnimation ];
anim = &bgGlobalAnimations[ newAnimation ];
lf->animation = anim;
lf->animationTime = lf->frameTime + anim->initialLerp;
@ -1576,10 +1582,13 @@ static void CG_SetLerpFrameAnimation( centity_t *cent, clientInfo_t *ci, lerpFra
if (torsoOnly)
{
trap_G2API_SetBoneAnim(cent->ghoul2, 0, "upper_lumbar", anim->firstFrame, anim->firstFrame + anim->numFrames, flags, animSpeed, lf->frameTime, -1, 150);
cgs.clientinfo[cent->currentState.number].torsoAnim = newAnimation;
}
else
{
trap_G2API_SetBoneAnim(cent->ghoul2, 0, "model_root", anim->firstFrame, anim->firstFrame + anim->numFrames, flags, animSpeed, lf->frameTime, -1, 150);
cgs.clientinfo[cent->currentState.number].torsoAnim = newAnimation;
cgs.clientinfo[cent->currentState.number].legsAnim = newAnimation;
}
if ((cent->currentState.torsoAnim&~ANIM_TOGGLEBIT) == newAnimation &&
@ -1669,7 +1678,21 @@ int CG_InWalkingAnim(int animNum)
{
if (anim == BOTH_RUN1)
{
return 12;
return 18;//12;
}
else
{
//return 9;
return 18;
}
}
if (anim >= BOTH_WALKBACK1 &&
anim <= BOTH_RUNBACK2)
{
if (anim == BOTH_WALKBACK1)
{
return 18;
}
else
{
@ -1677,16 +1700,17 @@ int CG_InWalkingAnim(int animNum)
}
}
if (anim >= BOTH_WALKBACK1 &&
anim <= BOTH_RUNBACK2)
{
return 9;
}
if (anim >= LEGS_WALKBACK1 &&
anim <= LEGS_RUNBACK2)
{
return 9;
if (anim == LEGS_WALKBACK1)
{
return 18;
}
else
{
return 9;
}
}
return qfalse;
@ -2373,6 +2397,16 @@ void CG_G2ClientSpineAngles( centity_t *cent, vec3_t viewAngles, const vec3_t an
!BG_SaberInSpecialAttack(cent->currentState.torsoAnim) &&
!BG_SaberInSpecialAttack(cent->currentState.legsAnim) &&
!BG_FlippingAnim( cgs.clientinfo[cent->currentState.number].legsAnim ) &&
!BG_SpinningSaberAnim( cgs.clientinfo[cent->currentState.number].legsAnim ) &&
!BG_SpinningSaberAnim( cgs.clientinfo[cent->currentState.number].torsoAnim ) &&
!BG_InSpecialJump( cgs.clientinfo[cent->currentState.number].legsAnim ) &&
!BG_InSpecialJump( cgs.clientinfo[cent->currentState.number].torsoAnim ) &&
!BG_InDeathAnim(cgs.clientinfo[cent->currentState.number].legsAnim) &&
!BG_InDeathAnim(cgs.clientinfo[cent->currentState.number].torsoAnim) &&
!BG_SaberInSpecialAttack(cgs.clientinfo[cent->currentState.number].torsoAnim) &&
!BG_SaberInSpecialAttack(cgs.clientinfo[cent->currentState.number].legsAnim) &&
/*
!BG_FlippingAnim( cent->rootBone ) &&
!BG_SpinningSaberAnim( cent->rootBone ) &&
@ -2399,17 +2433,26 @@ void CG_G2ClientSpineAngles( centity_t *cent, vec3_t viewAngles, const vec3_t an
}
//distribute the angles differently up the spine
//NOTE: each of these distributions must add up to 1.0f
thoracicAngles[PITCH] = viewAngles[PITCH]*0.20f;
llAngles[PITCH] = viewAngles[PITCH]*0.40f;
ulAngles[PITCH] = viewAngles[PITCH]*0.40f;
thoracicAngles[PITCH] = 0;//viewAngles[PITCH]*0.20f;
llAngles[PITCH] = 0;//viewAngles[PITCH]*0.40f;
ulAngles[PITCH] = 0;//viewAngles[PITCH]*0.40f;
// thoracicAngles[YAW] = viewAngles[YAW]*0.20f;
// ulAngles[YAW] = viewAngles[YAW]*0.35f;
// llAngles[YAW] = viewAngles[YAW]*0.45f;
thoracicAngles[YAW] = viewAngles[YAW]*0.20f - (viewAngles[PITCH]*(viewAngles[YAW]*.020f));
ulAngles[YAW] = viewAngles[YAW]*0.25f - (viewAngles[PITCH]*(viewAngles[YAW]*.0005f));
llAngles[YAW] = viewAngles[YAW]*0.25f - (viewAngles[PITCH]*(viewAngles[YAW]*.0005f));
thoracicAngles[YAW] = viewAngles[YAW]*0.20f;
ulAngles[YAW] = viewAngles[YAW]*0.25f;
llAngles[YAW] = viewAngles[YAW]*0.25f;
if (thoracicAngles[YAW] > 20)
{
thoracicAngles[YAW] = 20;
}
if (ulAngles[YAW] > 20)
{
ulAngles[YAW] = 20;
}
if (llAngles[YAW] > 20)
{
llAngles[YAW] = 20;
}
thoracicAngles[ROLL] = viewAngles[ROLL]*0.20f;
ulAngles[ROLL] = viewAngles[ROLL]*0.35f;
@ -2555,6 +2598,12 @@ static void CG_G2PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t legsAngle
velPos[0] = cent->lerpOrigin[0] + velocity[0];
velPos[1] = cent->lerpOrigin[1] + velocity[1];
velPos[2] = cent->lerpOrigin[2];// + velocity[2];
if (cent->currentState.groundEntityNum == ENTITYNUM_NONE)
{ //off the ground, no direction-based leg angles
VectorCopy(cent->lerpOrigin, velPos);
}
VectorSubtract(cent->lerpOrigin, velPos, velAng);
if (!VectorCompare(velAng, vec3_origin))
@ -2686,68 +2735,6 @@ static void CG_G2PlayerAngles( centity_t *cent, vec3_t legs[3], vec3_t legsAngle
llAngles[ROLL] += torsoAngles[ROLL]*0.3;
thoracicAngles[ROLL] += torsoAngles[ROLL]*0.4;
//We must compensate yaw for pitch so that the player can't bend all the way over and contort his spine
//to the left/right at an unnatural angle
if (ulAngles[PITCH] > 0)
{
if (ulAngles[YAW] > 0)
{
ulAngles[YAW] -= ulAngles[PITCH];
if (ulAngles[YAW] < 0)
{
ulAngles[YAW] = 0;
}
}
else if (ulAngles[YAW] < 0)
{
ulAngles[YAW] += ulAngles[PITCH];
if (ulAngles[YAW] > 0)
{
ulAngles[YAW] = 0;
}
}
}
if (llAngles[PITCH] > 0)
{
if (llAngles[YAW] > 0)
{
llAngles[YAW] -= llAngles[PITCH];
if (llAngles[YAW] < 0)
{
llAngles[YAW] = 0;
}
}
else if (llAngles[YAW] < 0)
{
llAngles[YAW] += llAngles[PITCH];
if (llAngles[YAW] > 0)
{
llAngles[YAW] = 0;
}
}
}
if (thoracicAngles[PITCH] > 0)
{
if (thoracicAngles[YAW] > 0)
{
thoracicAngles[YAW] -= thoracicAngles[PITCH];
if (thoracicAngles[YAW] < 0)
{
thoracicAngles[YAW] = 0;
}
}
else if (thoracicAngles[YAW] < 0)
{
thoracicAngles[YAW] += thoracicAngles[PITCH];
if (thoracicAngles[YAW] > 0)
{
thoracicAngles[YAW] = 0;
}
}
}
if ( cent->currentState.otherEntityNum2 && !(cent->currentState.eFlags & EF_DEAD) )
{ //using an emplaced gun
centity_t *empEnt = &cg_entities[cent->currentState.otherEntityNum2];
@ -2968,6 +2955,12 @@ static void CG_PlayerFlag( centity_t *cent, qhandle_t hModel ) {
vec3_t boltOrg, tAng, getAng, right;
mdxaBone_t boltMatrix;
if (cent->currentState.number == cg.snap->ps.clientNum &&
!cg.renderingThirdPerson)
{
return;
}
if (!cent->ghoul2)
{
return;
@ -4026,7 +4019,7 @@ Ghoul2 Insert Start
if ( cg.time - client->saberHitWallSoundDebounceTime >= 100 )
{//ugh, need to have a real sound debouncer... or do this game-side
client->saberHitWallSoundDebounceTime = cg.time;
trap_S_StartSound ( trace.endpos, -1, CHAN_WEAPON, trap_S_RegisterSound( "sound/weapons/saber/saberhitwall.wav" ) );
trap_S_StartSound ( trace.endpos, -1, CHAN_WEAPON, trap_S_RegisterSound( va("sound/weapons/saber/saberhitwall%i", Q_irand(1, 3)) ) );
}
}
}
@ -4893,67 +4886,6 @@ void CG_Player( centity_t *cent ) {
goto doEssentialOne;
}
if ( (cent->currentState.powerups & (1 << PW_YSALIMARI)) ||
(cgs.gametype == GT_CTY && ((cent->currentState.powerups & (1 << PW_REDFLAG)) || (cent->currentState.powerups & (1 << PW_BLUEFLAG)))) )
{
vec3_t efColors;
if (cgs.gametype == GT_CTY && (cent->currentState.powerups & (1 << PW_REDFLAG)))
{
efColors[0] = 255;
efColors[1] = 50;
efColors[2] = -1;
}
else if (cgs.gametype == GT_CTY && (cent->currentState.powerups & (1 << PW_BLUEFLAG)))
{
efColors[0] = 50;
efColors[1] = 50;
efColors[2] = 255;
}
else
{
efColors[0] = 255;
efColors[1] = 255;
efColors[2] = -1;
}
CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors);
}
if (cent->currentState.powerups & (1 << PW_FORCE_BOON))
{
vec3_t efColors;
efColors[0] = -1;
efColors[1] = -1;
efColors[2] = 255;
CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors);
}
if (cent->currentState.powerups & (1 << PW_FORCE_ENLIGHTENED_DARK))
{
vec3_t efColors;
efColors[0] = 255;
efColors[1] = -1;
efColors[2] = -1;
CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors);
}
else if (cent->currentState.powerups & (1 << PW_FORCE_ENLIGHTENED_LIGHT))
{
vec3_t efColors;
efColors[0] = 255;
efColors[1] = 255;
efColors[2] = 255;
CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors);
}
if (cent->currentState.eFlags & EF_INVULNERABLE)
{
vec3_t efColors;
efColors[0] = 0;
efColors[1] = 255;
efColors[2] = 0;
CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors);
}
// add the shadow
shadow = CG_PlayerShadow( cent, &shadowPlane );
@ -5026,139 +4958,6 @@ void CG_Player( centity_t *cent ) {
trap_R_AddRefEntityToScene( &seeker );
}
if (cgs.gametype == GT_HOLOCRON && cent->currentState.time2 && (cg.renderingThirdPerson || cg.snap->ps.clientNum != cent->currentState.number))
{
int i = 0;
int renderedHolos = 0;
refEntity_t holoRef;
while (i < NUM_FORCE_POWERS && renderedHolos < 3)
{
if (cent->currentState.time2 & (1 << i))
{
memset( &holoRef, 0, sizeof(holoRef) );
VectorCopy(cent->lerpOrigin, elevated);
elevated[2] += 8;
VectorCopy( elevated, holoRef.lightingOrigin );
holoRef.shadowPlane = shadowPlane;
holoRef.renderfx = 0;//RF_THIRD_PERSON;
if (renderedHolos == 0)
{
angle = ((cg.time / 8) & 255) * (M_PI * 2) / 255;
dir[0] = cos(angle) * 20;
dir[1] = sin(angle) * 20;
dir[2] = cos(angle) * 20;
VectorAdd(elevated, dir, holoRef.origin);
angles[0] = sin(angle) * 30;
angles[1] = (angle * 180 / M_PI) + 90;
if (angles[1] > 360)
angles[1] -= 360;
angles[2] = 0;
AnglesToAxis( angles, holoRef.axis );
}
else if (renderedHolos == 1)
{
angle = ((cg.time / 8) & 255) * (M_PI * 2) / 255 + M_PI;
if (angle > M_PI * 2)
angle -= (float)M_PI * 2;
dir[0] = sin(angle) * 20;
dir[1] = cos(angle) * 20;
dir[2] = cos(angle) * 20;
VectorAdd(elevated, dir, holoRef.origin);
angles[0] = cos(angle - 0.5 * M_PI) * 30;
angles[1] = 360 - (angle * 180 / M_PI);
if (angles[1] > 360)
angles[1] -= 360;
angles[2] = 0;
AnglesToAxis( angles, holoRef.axis );
}
else
{
angle = ((cg.time / 6) & 255) * (M_PI * 2) / 255 + 0.5 * M_PI;
if (angle > M_PI * 2)
angle -= (float)M_PI * 2;
dir[0] = sin(angle) * 20;
dir[1] = cos(angle) * 20;
dir[2] = 0;
VectorAdd(elevated, dir, holoRef.origin);
VectorCopy(dir, holoRef.axis[1]);
VectorNormalize(holoRef.axis[1]);
VectorSet(holoRef.axis[2], 0, 0, 1);
CrossProduct(holoRef.axis[1], holoRef.axis[2], holoRef.axis[0]);
}
holoRef.modelScale[0] = 0.5;
holoRef.modelScale[1] = 0.5;
holoRef.modelScale[2] = 0.5;
ScaleModelAxis(&holoRef);
{
float wv;
addspriteArgStruct_t fxSArgs;
vec3_t holoCenter;
holoCenter[0] = holoRef.origin[0] + holoRef.axis[2][0]*18;
holoCenter[1] = holoRef.origin[1] + holoRef.axis[2][1]*18;
holoCenter[2] = holoRef.origin[2] + holoRef.axis[2][2]*18;
wv = sin( cg.time * 0.004f ) * 0.08f + 0.1f;
VectorCopy(holoCenter, fxSArgs.origin);
VectorClear(fxSArgs.vel);
VectorClear(fxSArgs.accel);
fxSArgs.scale = wv*60;
fxSArgs.dscale = wv*60;
fxSArgs.sAlpha = wv*12;
fxSArgs.eAlpha = wv*12;
fxSArgs.rotation = 0.0f;
fxSArgs.bounce = 0.0f;
fxSArgs.life = 1.0f;
fxSArgs.flags = 0x08000000|0x00000001;
if (forcePowerDarkLight[i] == FORCE_DARKSIDE)
{ //dark
fxSArgs.sAlpha *= 2;
fxSArgs.eAlpha *= 2;
fxSArgs.shader = cgs.media.redSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
}
else if (forcePowerDarkLight[i] == FORCE_LIGHTSIDE)
{ //light
fxSArgs.sAlpha *= 1.5;
fxSArgs.eAlpha *= 1.5;
fxSArgs.shader = cgs.media.redSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
fxSArgs.shader = cgs.media.greenSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
fxSArgs.shader = cgs.media.blueSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
}
else
{ //neutral
fxSArgs.sAlpha *= 0.5;
fxSArgs.eAlpha *= 0.5;
fxSArgs.shader = cgs.media.greenSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
fxSArgs.shader = cgs.media.blueSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
}
}
holoRef.hModel = trap_R_RegisterModel(forceHolocronModels[i]);
trap_R_AddRefEntityToScene( &holoRef );
renderedHolos++;
}
i++;
}
}
doEssentialOne:
// add a water splash if partially in and out of water
CG_PlayerSplash( cent );
@ -5558,7 +5357,7 @@ doEssentialTwo:
if (cent->currentState.weapon == WP_STUN_BATON && (cent->currentState.eFlags & EF_FIRING))
{ //note: This is a stupid placeholder so that it's at least the same as SP
trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, trap_S_RegisterSound("sound/weapons/saber/saberhum") );
trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin, trap_S_RegisterSound("sound/weapons/saber/saberhum1") );
}
//NOTE: All effects that should be visible during mindtrick should go above here
@ -5578,6 +5377,213 @@ doEssentialTwo:
legs.shaderRGBA[3] = 1;
}
}
if (cgs.gametype == GT_HOLOCRON && cent->currentState.time2 && (cg.renderingThirdPerson || cg.snap->ps.clientNum != cent->currentState.number))
{
int i = 0;
int renderedHolos = 0;
refEntity_t holoRef;
while (i < NUM_FORCE_POWERS && renderedHolos < 3)
{
if (cent->currentState.time2 & (1 << i))
{
memset( &holoRef, 0, sizeof(holoRef) );
VectorCopy(cent->lerpOrigin, elevated);
elevated[2] += 8;
VectorCopy( elevated, holoRef.lightingOrigin );
holoRef.shadowPlane = shadowPlane;
holoRef.renderfx = 0;//RF_THIRD_PERSON;
if (renderedHolos == 0)
{
angle = ((cg.time / 8) & 255) * (M_PI * 2) / 255;
dir[0] = cos(angle) * 20;
dir[1] = sin(angle) * 20;
dir[2] = cos(angle) * 20;
VectorAdd(elevated, dir, holoRef.origin);
angles[0] = sin(angle) * 30;
angles[1] = (angle * 180 / M_PI) + 90;
if (angles[1] > 360)
angles[1] -= 360;
angles[2] = 0;
AnglesToAxis( angles, holoRef.axis );
}
else if (renderedHolos == 1)
{
angle = ((cg.time / 8) & 255) * (M_PI * 2) / 255 + M_PI;
if (angle > M_PI * 2)
angle -= (float)M_PI * 2;
dir[0] = sin(angle) * 20;
dir[1] = cos(angle) * 20;
dir[2] = cos(angle) * 20;
VectorAdd(elevated, dir, holoRef.origin);
angles[0] = cos(angle - 0.5 * M_PI) * 30;
angles[1] = 360 - (angle * 180 / M_PI);
if (angles[1] > 360)
angles[1] -= 360;
angles[2] = 0;
AnglesToAxis( angles, holoRef.axis );
}
else
{
angle = ((cg.time / 6) & 255) * (M_PI * 2) / 255 + 0.5 * M_PI;
if (angle > M_PI * 2)
angle -= (float)M_PI * 2;
dir[0] = sin(angle) * 20;
dir[1] = cos(angle) * 20;
dir[2] = 0;
VectorAdd(elevated, dir, holoRef.origin);
VectorCopy(dir, holoRef.axis[1]);
VectorNormalize(holoRef.axis[1]);
VectorSet(holoRef.axis[2], 0, 0, 1);
CrossProduct(holoRef.axis[1], holoRef.axis[2], holoRef.axis[0]);
}
holoRef.modelScale[0] = 0.5;
holoRef.modelScale[1] = 0.5;
holoRef.modelScale[2] = 0.5;
ScaleModelAxis(&holoRef);
{
float wv;
addspriteArgStruct_t fxSArgs;
vec3_t holoCenter;
holoCenter[0] = holoRef.origin[0] + holoRef.axis[2][0]*18;
holoCenter[1] = holoRef.origin[1] + holoRef.axis[2][1]*18;
holoCenter[2] = holoRef.origin[2] + holoRef.axis[2][2]*18;
wv = sin( cg.time * 0.004f ) * 0.08f + 0.1f;
VectorCopy(holoCenter, fxSArgs.origin);
VectorClear(fxSArgs.vel);
VectorClear(fxSArgs.accel);
fxSArgs.scale = wv*60;
fxSArgs.dscale = wv*60;
fxSArgs.sAlpha = wv*12;
fxSArgs.eAlpha = wv*12;
fxSArgs.rotation = 0.0f;
fxSArgs.bounce = 0.0f;
fxSArgs.life = 1.0f;
fxSArgs.flags = 0x08000000|0x00000001;
if (forcePowerDarkLight[i] == FORCE_DARKSIDE)
{ //dark
fxSArgs.sAlpha *= 3;
fxSArgs.eAlpha *= 3;
fxSArgs.shader = cgs.media.redSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
}
else if (forcePowerDarkLight[i] == FORCE_LIGHTSIDE)
{ //light
fxSArgs.sAlpha *= 1.5;
fxSArgs.eAlpha *= 1.5;
fxSArgs.shader = cgs.media.redSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
fxSArgs.shader = cgs.media.greenSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
fxSArgs.shader = cgs.media.blueSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
}
else
{ //neutral
if (i == FP_SABERATTACK ||
i == FP_SABERDEFEND ||
i == FP_SABERTHROW)
{ //saber power
fxSArgs.sAlpha *= 1.5;
fxSArgs.eAlpha *= 1.5;
fxSArgs.shader = cgs.media.greenSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
}
else
{
fxSArgs.sAlpha *= 0.5;
fxSArgs.eAlpha *= 0.5;
fxSArgs.shader = cgs.media.greenSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
fxSArgs.shader = cgs.media.blueSaberGlowShader;
trap_FX_AddSprite(&fxSArgs);
}
}
}
holoRef.hModel = trap_R_RegisterModel(forceHolocronModels[i]);
trap_R_AddRefEntityToScene( &holoRef );
renderedHolos++;
}
i++;
}
}
if ( (cent->currentState.powerups & (1 << PW_YSALIMARI)) ||
(cgs.gametype == GT_CTY && ((cent->currentState.powerups & (1 << PW_REDFLAG)) || (cent->currentState.powerups & (1 << PW_BLUEFLAG)))) )
{
vec3_t efColors;
if (cgs.gametype == GT_CTY && (cent->currentState.powerups & (1 << PW_REDFLAG)))
{
efColors[0] = 255;
efColors[1] = 50;
efColors[2] = -1;
}
else if (cgs.gametype == GT_CTY && (cent->currentState.powerups & (1 << PW_BLUEFLAG)))
{
efColors[0] = 50;
efColors[1] = 50;
efColors[2] = 255;
}
else
{
efColors[0] = 255;
efColors[1] = 255;
efColors[2] = -1;
}
CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors);
}
if (cent->currentState.powerups & (1 << PW_FORCE_BOON))
{
vec3_t efColors;
efColors[0] = -1;
efColors[1] = -1;
efColors[2] = 255;
CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors);
}
if (cent->currentState.powerups & (1 << PW_FORCE_ENLIGHTENED_DARK))
{
vec3_t efColors;
efColors[0] = 255;
efColors[1] = -1;
efColors[2] = -1;
CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors);
}
else if (cent->currentState.powerups & (1 << PW_FORCE_ENLIGHTENED_LIGHT))
{
vec3_t efColors;
efColors[0] = 255;
efColors[1] = 255;
efColors[2] = 255;
CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors);
}
if (cent->currentState.eFlags & EF_INVULNERABLE)
{
vec3_t efColors;
efColors[0] = 0;
efColors[1] = 255;
efColors[2] = 0;
CG_DrawYsalimariSphere(cent, cent->lerpOrigin, efColors);
}
stillDoSaber:
if (cent->currentState.weapon == WP_SABER && !cent->currentState.shouldtarget)
{
@ -5586,12 +5592,12 @@ stillDoSaber:
if (cg.snap->ps.clientNum == cent->currentState.number)
{
trap_S_AddLoopingSound( cent->currentState.number, cg.refdef.vieworg, vec3_origin,
trap_S_RegisterSound( "sound/weapons/saber/saberhum.wav" ) );
trap_S_RegisterSound( "sound/weapons/saber/saberhum1.wav" ) );
}
else
{
trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, vec3_origin,
trap_S_RegisterSound( "sound/weapons/saber/saberhum.wav" ) );
trap_S_RegisterSound( "sound/weapons/saber/saberhum1.wav" ) );
}
}

View file

@ -329,8 +329,8 @@ void CG_CheckLocalSounds( playerState_t *ps, playerState_t *ops ) {
//trap_S_StartLocalSound( cgs.media.hitTeamSound, CHAN_LOCAL_SOUND );
}
// health changes of more than -1 should make pain sounds
if ( ps->stats[STAT_HEALTH] < (ops->stats[STAT_HEALTH] - 1)) {
// health changes of more than -3 should make pain sounds
if ( ps->stats[STAT_HEALTH] < (ops->stats[STAT_HEALTH] - 3)) {
if ( ps->stats[STAT_HEALTH] > 0 ) {
CG_PainEvent( &cg.predictedPlayerEntity, ps->stats[STAT_HEALTH] );
}

View file

@ -730,7 +730,7 @@ void CG_PredictPlayerState( void ) {
cg_pmove.cmd.serverTime = ((cg_pmove.cmd.serverTime + pmove_msec.integer-1) / pmove_msec.integer) * pmove_msec.integer;
}
cg_pmove.animations = cgs.clientinfo[cg.clientNum].animations;
cg_pmove.animations = bgGlobalAnimations;
cg_pmove.gametype = cgs.gametype;

View file

@ -320,6 +320,8 @@ typedef enum {
// float orientation, float red, float green, float blue, float alpha,
// qboolean alphaFade, float radius, qboolean temporary )
CG_MAP_CHANGE,
} cgameExport_t;
// CG_POINT_CONTENTS

View file

@ -84,17 +84,17 @@ static void CG_DrawClientScore( int y, score_t *score, float *color, float fade,
}
} else if ( ci->powerups & ( 1 << PW_REDFLAG ) ) {
if( largeFormat ) {
CG_DrawFlagModel( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, TEAM_RED, qfalse );
CG_DrawFlagModel( iconx, y*1.63, 32, 32, TEAM_RED, qfalse );
}
else {
CG_DrawFlagModel( iconx, y, 16, 16, TEAM_RED, qfalse );
CG_DrawFlagModel( iconx, y*1.63, 32, 32, TEAM_RED, qfalse );
}
} else if ( ci->powerups & ( 1 << PW_BLUEFLAG ) ) {
if( largeFormat ) {
CG_DrawFlagModel( iconx, y - ( 32 - BIGCHAR_HEIGHT ) / 2, 32, 32, TEAM_BLUE, qfalse );
CG_DrawFlagModel( iconx, y*1.63, 32, 32, TEAM_BLUE, qfalse );
}
else {
CG_DrawFlagModel( iconx, y, 16, 16, TEAM_BLUE, qfalse );
CG_DrawFlagModel( iconx, y*1.63, 32, 32, TEAM_BLUE, qfalse );
}
} else {
/*
@ -182,7 +182,7 @@ static void CG_DrawClientScore( int y, score_t *score, float *color, float fade,
// add the "ready" marker for intermission exiting
if ( cg.snap->ps.stats[ STAT_CLIENTS_READY ] & ( 1 << score->client ) ) {
CG_DrawBigStringColor( iconx, y, "READY", color );
CG_DrawBigStringColor( iconx-64, y+6, "READY", color );
}
}
@ -383,10 +383,12 @@ qboolean CG_DrawOldScoreboard( void ) {
}
}
/*
// load any models that have been deferred
if ( ++cg.deferredPlayerLoading > 10 ) {
CG_LoadDeferredPlayers();
}
*/
return qtrue;
}

View file

@ -175,7 +175,8 @@ CG_SetConfigValues
Called on load to set the initial values from configure strings
================
*/
void CG_SetConfigValues( void ) {
void CG_SetConfigValues( void )
{
const char *s;
cgs.scores1 = atoi( CG_ConfigString( CS_SCORES1 ) );
@ -187,6 +188,9 @@ void CG_SetConfigValues( void ) {
cgs.blueflag = s[1] - '0';
}
cg.warmup = atoi( CG_ConfigString( CS_WARMUP ) );
// Track who the jedi master is
cgs.jediMaster = atoi ( CG_ConfigString ( CS_CLIENT_JEDIMASTER ) );
}
/*
@ -259,6 +263,8 @@ static void CG_ConfigStringModified( void ) {
cgs.scores1 = atoi( str );
} else if ( num == CS_SCORES2 ) {
cgs.scores2 = atoi( str );
} else if ( num == CS_CLIENT_JEDIMASTER ) {
cgs.jediMaster = atoi ( str );
} else if ( num == CS_LEVEL_START_TIME ) {
cgs.levelStartTime = atoi( str );
} else if ( num == CS_VOTE_TIME ) {
@ -295,6 +301,10 @@ static void CG_ConfigStringModified( void ) {
if ( str[0] != '*' ) { // player specific sounds don't register here
cgs.gameSounds[ num-CS_SOUNDS] = trap_S_RegisterSound( str );
}
} else if ( num >= CS_EFFECTS && num < CS_SOUNDS+MAX_SOUNDS ) {
if ( str[0] != '*' ) { // player specific sounds don't register here
cgs.gameEffects[ num-CS_EFFECTS] = trap_FX_RegisterEffect( str );
}
} else if ( num >= CS_PLAYERS && num < CS_PLAYERS+MAX_CLIENTS ) {
CG_NewClientInfo( num - CS_PLAYERS, qtrue);
CG_BuildSpectatorString();

View file

@ -126,7 +126,7 @@ void CG_RegisterWeapon( int weaponNum) {
break;
case WP_SABER:
MAKERGB( weaponInfo->flashDlightColor, 0.6f, 0.6f, 1.0f );
weaponInfo->firingSound = trap_S_RegisterSound( "sound/weapons/saber/saberhum.wav" );
weaponInfo->firingSound = trap_S_RegisterSound( "sound/weapons/saber/saberhum.wav1" );
weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/saber/saber_w.glm" );
break;

View file

@ -118,7 +118,7 @@ CG_MapTorsoToWeaponFrame
=================
*/
static int CG_MapTorsoToWeaponFrame( clientInfo_t *ci, int frame, int animNum ) {
animation_t *animations = ci->animations;
animation_t *animations = bgGlobalAnimations;
switch( animNum )
{
@ -148,6 +148,7 @@ static int CG_MapTorsoToWeaponFrame( clientInfo_t *ci, int frame, int animNum )
case BOTH_ATTACK10:
case BOTH_ATTACK11:
case BOTH_ATTACK12:
case BOTH_THERMAL_THROW:
if ( frame >= animations[animNum].firstFrame && frame < animations[animNum].firstFrame + 6 )
{
return 1 + ( frame - animations[animNum].firstFrame );
@ -393,6 +394,7 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
weapon_t weaponNum;
weaponInfo_t *weapon;
centity_t *nonPredictedCent;
refEntity_t flash;
weaponNum = cent->currentState.weapon;
@ -484,6 +486,11 @@ Ghoul2 Insert Start
Ghoul2 Insert End
*/
memset (&flash, 0, sizeof(flash));
CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash");
VectorCopy(flash.origin, cg.lastFPFlashPoint);
// Do special charge bits
//-----------------------
if ( (ps || cg.renderingThirdPerson || cg.predictedPlayerState.clientNum != cent->currentState.number) &&
@ -496,13 +503,9 @@ Ghoul2 Insert End
float scale = 1.0f;
addspriteArgStruct_t fxSArgs;
vec3_t flashorigin, flashdir;
refEntity_t flash;
memset (&flash, 0, sizeof(flash));
if (!thirdPerson)
{
CG_PositionEntityOnTag( &flash, &gun, gun.hModel, "tag_flash");
VectorCopy(flash.origin, flashorigin);
VectorCopy(flash.axis[0], flashdir);
}
@ -1310,7 +1313,8 @@ void CG_Weapon_f( void ) {
{
if (cg.snap->ps.weaponTime < 1)
{
trap_SendClientCommand("sv_saberswitch");
//trap_SendClientCommand("sv_saberswitch");
trap_SendConsoleCommand("sv_saberswitch");
}
return;
}
@ -1332,7 +1336,7 @@ void CG_Weapon_f( void ) {
}
}
if (num > WP_DET_PACK)
if (num > WP_DET_PACK+1)
{ //other weapons are off limits due to not actually being weapon weapons
return;
}
@ -1500,6 +1504,28 @@ void CG_FireATST(centity_t *cent, qboolean altFire)
trap_S_StartSound(NULL, cent->currentState.number, CHAN_WEAPON, trap_S_RegisterSound(va("sound/weapons/atst/ATSTfire1.wav"/*, Q_irand(1,4)*/)));
}
void CG_GetClientWeaponMuzzleBoltPoint(int clIndex, vec3_t to)
{
centity_t *cent;
mdxaBone_t boltMatrix;
if (clIndex < 0 || clIndex >= MAX_CLIENTS)
{
return;
}
cent = &cg_entities[clIndex];
if (!cent || !cent->ghoul2 || !trap_G2_HaveWeGhoul2Models(cent->ghoul2) ||
!trap_G2API_HasGhoul2ModelOnIndex(&(cent->ghoul2), 1))
{
return;
}
trap_G2API_GetBoltMatrix(cent->ghoul2, 1, 0, &boltMatrix, cent->turAngles, cent->lerpOrigin, cg.time, cgs.gameModels, cent->modelScale);
trap_G2API_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, to);
}
/*
================
CG_FireWeapon

View file

@ -1,102 +0,0 @@
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 ..

View file

@ -1,44 +0,0 @@
-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

@ -1,5 +0,0 @@
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

Binary file not shown.

View file

@ -48,6 +48,126 @@ void IN_MLookUp( void ) {
}
}
void IN_GenCMD1( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_SABERSWITCH;
}
void IN_GenCMD2( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_ENGAGE_DUEL;
}
void IN_GenCMD3( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_HEAL;
}
void IN_GenCMD4( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_SPEED;
}
void IN_GenCMD5( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_PULL;
}
void IN_GenCMD6( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_DISTRACT;
}
void IN_GenCMD7( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_RAGE;
}
void IN_GenCMD8( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_PROTECT;
}
void IN_GenCMD9( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_ABSORB;
}
void IN_GenCMD10( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_HEALOTHER;
}
void IN_GenCMD11( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_FORCEPOWEROTHER;
}
void IN_GenCMD12( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_SEEING;
}
void IN_GenCMD13( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_USE_SEEKER;
}
void IN_GenCMD14( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_USE_FIELD;
}
void IN_GenCMD15( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_USE_BACTA;
}
void IN_GenCMD16( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_USE_ELECTROBINOCULARS;
}
void IN_GenCMD17( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_ZOOM;
}
void IN_GenCMD18( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_USE_SENTRY;
}
void IN_GenCMD19( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_SABERATTACKCYCLE;
}
void IN_GenCMD20( void )
{
cl.gcmdSendValue = qtrue;
cl.gcmdValue = GENCMD_FORCE_THROW;
}
void IN_KeyDown( kbutton_t *b ) {
int k;
char *c;
@ -298,7 +418,7 @@ void CL_KeyMove( usercmd_t *cmd ) {
cmd->buttons &= ~BUTTON_WALKING;
} else {
cmd->buttons |= BUTTON_WALKING;
movespeed = 64;
movespeed = 32;
}
forward = 0;
@ -491,6 +611,16 @@ void CL_FinishMove( usercmd_t *cmd ) {
cmd->forcesel = cl.cgameForceSelection;
cmd->invensel = cl.cgameInvenSelection;
if (cl.gcmdSendValue)
{
cmd->generic_cmd = cl.gcmdValue;
cl.gcmdSendValue = qfalse;
}
else
{
cmd->generic_cmd = 0;
}
// send the current server time so the amount of movement
// can be determined without allowing cheating
cmd->serverTime = cl.serverTime;
@ -962,6 +1092,27 @@ void CL_InitInput( void ) {
Cmd_AddCommand ("+mlook", IN_MLookDown);
Cmd_AddCommand ("-mlook", IN_MLookUp);
Cmd_AddCommand ("sv_saberswitch", IN_GenCMD1);
Cmd_AddCommand ("engage_duel", IN_GenCMD2);
Cmd_AddCommand ("force_heal", IN_GenCMD3);
Cmd_AddCommand ("force_speed", IN_GenCMD4);
Cmd_AddCommand ("force_pull", IN_GenCMD5);
Cmd_AddCommand ("force_distract", IN_GenCMD6);
Cmd_AddCommand ("force_rage", IN_GenCMD7);
Cmd_AddCommand ("force_protect", IN_GenCMD8);
Cmd_AddCommand ("force_absorb", IN_GenCMD9);
Cmd_AddCommand ("force_healother", IN_GenCMD10);
Cmd_AddCommand ("force_forcepowerother", IN_GenCMD11);
Cmd_AddCommand ("force_seeing", IN_GenCMD12);
Cmd_AddCommand ("use_seeker", IN_GenCMD13);
Cmd_AddCommand ("use_field", IN_GenCMD14);
Cmd_AddCommand ("use_bacta", IN_GenCMD15);
Cmd_AddCommand ("use_electrobinoculars", IN_GenCMD16);
Cmd_AddCommand ("zoom", IN_GenCMD17);
Cmd_AddCommand ("use_sentry", IN_GenCMD18);
Cmd_AddCommand ("saberAttackCycle", IN_GenCMD19);
Cmd_AddCommand ("force_throw", IN_GenCMD20);
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0);
cl_debugMove = Cvar_Get ("cl_debugMove", "0", 0);
}

View file

@ -1165,7 +1165,12 @@ void CL_KeyEvent (int key, qboolean down, unsigned time) {
return;
}
#ifdef FINAL_BUILD
if (!(cls.keyCatchers & KEYCATCH_CONSOLE) && !keys[K_SHIFT].down ) //we're not in the console
{//so we require the control keys to get in
return;
}
#endif
Con_ToggleConsole_f ();
return;
}

View file

@ -506,7 +506,14 @@ void CL_PlayDemo_f( void ) {
FS_FOpenFileRead( name, &clc.demofile, qtrue );
if (!clc.demofile) {
Com_Error( ERR_DROP, "couldn't open %s", name);
if (!Q_stricmp(arg, "(null)"))
{
Com_Error( ERR_DROP, "No demo selected.", name);
}
else
{
Com_Error( ERR_DROP, "couldn't open %s", name);
}
return;
}
Q_strncpyz( clc.demoName, Cmd_Argv(1), sizeof( clc.demoName ) );
@ -1918,7 +1925,8 @@ void CL_CheckTimeout( void ) {
&& cls.realtime - clc.lastPacketTime > cl_timeout->value*1000) {
if (++cl.timeoutcount > 5) { // timeoutcount saves debugger
Com_Printf ("\nServer connection timed out.\n");
CL_Disconnect( qtrue );
Com_Error(ERR_DROP, "Server connection timed out.");
//CL_Disconnect( qtrue );
return;
}
} else {

View file

@ -13,7 +13,8 @@ char *svc_strings[256] = {
"svc_baseline",
"svc_serverCommand",
"svc_download",
"svc_snapshot"
"svc_snapshot",
"svc_mapchange",
};
void SHOWNET( msg_t *msg, char *s) {
@ -634,6 +635,12 @@ void CL_ParseServerMessage( msg_t *msg ) {
case svc_download:
CL_ParseDownload( msg );
break;
case svc_mapchange:
if (cgvm)
{
VM_Call( cgvm, CG_MAP_CHANGE );
}
break;
}
}
}

View file

@ -96,6 +96,9 @@ typedef struct {
int cgameForceSelection;
int cgameInvenSelection;
qboolean gcmdSendValue;
byte gcmdValue;
float lastViewYaw;
// cmds[cmdNumber] is the predicted command, [cmdNumber-1] is the last

View file

@ -138,6 +138,8 @@ cvar_t *s_musicVolume;
cvar_t *s_separation;
cvar_t *s_doppler;
cvar_t *s_CPUType;
cvar_t *s_language;
static loopSound_t loopSounds[MAX_GENTITIES];
static channel_t *freelist = NULL;
@ -219,6 +221,8 @@ void S_Init( void ) {
s_show = Cvar_Get ("s_show", "0", CVAR_CHEAT);
s_testsound = Cvar_Get ("s_testsound", "0", CVAR_CHEAT);
s_language = Cvar_Get("s_language","english",CVAR_ARCHIVE | CVAR_NORESTART);
MP3_InitCvars();
s_CPUType = Cvar_Get("sys_cpuid","",0);

View file

@ -215,6 +215,81 @@ void S_LoadSound_Finalize(wavinfo_t *info, sfx_t *sfx, byte *data)
// adjust filename for foreign languages and WAV/MP3 issues.
//
// returns qfalse if failed to load, else fills in *pData
//
static qboolean S_LoadSound_FileLoadAndNameAdjuster(char *psFilename, byte **pData, int *piSize, int iNameStrlen)
{
char *psVoice = strstr(psFilename,"chars");
if (psVoice)
{
// account for foreign voices...
//
extern cvar_t* s_language;
if (s_language && stricmp("DEUTSCH",s_language->string)==0)
{
strncpy(psVoice,"chr_d",5); // same number of letters as "chars"
}
else
if (s_language && stricmp("FRANCAIS",s_language->string)==0)
{
strncpy(psVoice,"chr_f",5); // same number of letters as "chars"
}
else
{
psVoice = NULL; // use this ptr as a flag as to whether or not we substituted with a foreign version
}
}
*piSize = FS_ReadFile( psFilename, (void **)pData ); // try WAV
if ( !*pData ) {
psFilename[iNameStrlen-3] = 'm';
psFilename[iNameStrlen-2] = 'p';
psFilename[iNameStrlen-1] = '3';
*piSize = FS_ReadFile( psFilename, (void **)pData ); // try MP3
if ( !*pData )
{
//hmmm, not found, ok, maybe we were trying a foreign noise ("arghhhhh.mp3" that doesn't matter?) but it
// was missing? Can't tell really, since both types are now in sound/chars. Oh well, fall back to English for now...
if (psVoice) // were we trying to load foreign?
{
// yep, so fallback to re-try the english...
//
#ifndef FINAL_BUILD
Com_Printf(S_COLOR_YELLOW "Foreign file missing: \"%s\"! (using English...)\n",psFilename);
#endif
strncpy(psVoice,"chars",5);
psFilename[iNameStrlen-3] = 'w';
psFilename[iNameStrlen-2] = 'a';
psFilename[iNameStrlen-1] = 'v';
*piSize = FS_ReadFile( psFilename, (void **)pData ); // try English WAV
if ( !*pData )
{
psFilename[iNameStrlen-3] = 'm';
psFilename[iNameStrlen-2] = 'p';
psFilename[iNameStrlen-1] = '3';
*piSize = FS_ReadFile( psFilename, (void **)pData ); // try English MP3
}
}
if (!*pData)
{
return qfalse; // sod it, give up...
}
}
}
return qtrue;
}
//=============================================================================
/*
@ -243,34 +318,22 @@ static qboolean S_LoadSound_Actual( sfx_t *sfx )
//
char sRootName[MAX_QPATH];
char sLoadName[MAX_QPATH];
bool isMp3 = false;
COM_StripExtension(sfx->sSoundName, sRootName);
Com_sprintf(sLoadName, MAX_QPATH, "%s.wav", sRootName);
//
// 1st attempt, try whichever wav or mp3 is specified...
//
size = FS_ReadFile( sLoadName, (void **)&data );
if ( !data )
{
// 2nd attempt, try wav instead of mp3 or vice versa...
//
Com_sprintf(sLoadName, MAX_QPATH, "%s.mp3", sRootName);
const char *psExt = &sLoadName[strlen(sLoadName)-4];
size = FS_ReadFile( sLoadName, (void **)&data );
if ( !data )
{
return qfalse;
}
isMp3 = true;
if (!S_LoadSound_FileLoadAndNameAdjuster(sLoadName, &data, &size, strlen(sLoadName)))
{
return qfalse;
}
SND_TouchSFX(sfx);
sfx->iLastTimeUsed = Com_Milliseconds()+1; // why +1? Hmmm, leave it for now I guess
//=========
if (isMp3)
if (strnicmp(psExt,".mp3",4)==0)
{
// load MP3 file instead...
//

Binary file not shown.

Binary file not shown.

View file

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

View file

@ -1862,6 +1862,11 @@ int BotCanHear(bot_state_t *bs, gentity_t *en, float endist)
break;
}
checkStep:
if (BotMindTricked(bs->client, en->s.number))
{ //if mindtricked by this person, cut down on the minlen
minlen /= 4;
}
if (endist <= minlen)
{
return 1;
@ -2261,6 +2266,32 @@ gentity_t *GetNearestBadThing(bot_state_t *bs)
}
}
if (ent && !ent->client && ent->inuse && ent->damage && ent->s.weapon && ent->r.ownerNum < MAX_CLIENTS && ent->r.ownerNum >= 0)
{ //if we're in danger of a projectile belonging to someone and don't have an enemy, set the enemy to them
gentity_t *projOwner = &g_entities[ent->r.ownerNum];
if (projOwner && projOwner->inuse && projOwner->client)
{
if (!bs->currentEnemy)
{
if (PassStandardEnemyChecks(bs, projOwner))
{
if (PassLovedOneCheck(bs, projOwner))
{
VectorSubtract(bs->origin, ent->r.currentOrigin, hold);
glen = VectorLength(hold);
if (glen < 512)
{
bs->currentEnemy = projOwner;
bs->enemySeenTime = level.time + ENEMY_FORGET_MS;
}
}
}
}
}
}
i++;
}
@ -6182,11 +6213,15 @@ void StandardBotAI(bot_state_t *bs, float thinktime)
{
/*if (g_gametype.integer == GT_TOURNAMENT)*/
{ //helps them get out of messy situations
if ((level.time - bs->forceJumpChargeTime) > /*500*/3500)
/*if ((level.time - bs->forceJumpChargeTime) > 3500)
{
bs->forceJumpChargeTime = level.time + 2000;
trap_EA_MoveForward(bs->client);
}
*/
bs->jumpTime = level.time + 1500;
bs->jumpHoldTime = level.time + 1500;
bs->jDelay = 0;
}
doingFallback = BotFallbackNavigation(bs);
}
@ -6335,12 +6370,13 @@ void StandardBotAI(bot_state_t *bs, float thinktime)
}
else if (bs->saberThrowTime < level.time && !bs->cur_ps.saberInFlight &&
(bs->cur_ps.fd.forcePowersKnown & (1 << FP_SABERTHROW)) &&
InFieldOfVision(bs->viewangles, 30, a_fo))
InFieldOfVision(bs->viewangles, 30, a_fo) &&
bs->frame_Enemy_Len < BOT_SABER_THROW_RANGE)
{
bs->doAltAttack = 1;
bs->doAttack = 0;
}
else if (bs->cur_ps.saberInFlight && bs->frame_Enemy_Len > 300)
else if (bs->cur_ps.saberInFlight && bs->frame_Enemy_Len > 300 && bs->frame_Enemy_Len < BOT_SABER_THROW_RANGE)
{
bs->doAltAttack = 1;
bs->doAttack = 0;
@ -6569,9 +6605,29 @@ void StandardBotAI(bot_state_t *bs, float thinktime)
}
#endif
if (bs->forceJumpChargeTime > level.time)
{
bs->jumpHoldTime = ((bs->forceJumpChargeTime - level.time)/2) + level.time;
bs->forceJumpChargeTime = 0;
}
if (bs->jumpHoldTime > level.time)
{
bs->jumpTime = bs->jumpHoldTime;
}
if (bs->jumpTime > level.time && bs->jDelay < level.time)
{
if (!(bs->cur_ps.pm_flags & PMF_JUMP_HELD))
if (bs->jumpHoldTime > level.time)
{
trap_EA_Jump(bs->client);
trap_EA_MoveForward(bs->client);
if (g_entities[bs->client].client->ps.groundEntityNum == ENTITYNUM_NONE)
{
g_entities[bs->client].client->ps.pm_flags |= PMF_JUMP_HELD;
}
}
else if (!(bs->cur_ps.pm_flags & PMF_JUMP_HELD))
{
trap_EA_Jump(bs->client);
}

View file

@ -74,6 +74,8 @@
#define BOT_FLAG_GET_DISTANCE 256
#define BOT_SABER_THROW_RANGE 800
typedef enum
{
CTFSTATE_NONE,
@ -238,6 +240,7 @@ typedef struct bot_state_s
float beStill;
float duckTime;
float jumpTime;
float jumpHoldTime;
float forceJumping;
float jDelay;

View file

@ -104,8 +104,8 @@ int WeaponReadyAnim[WP_NUM_WEAPONS] =
TORSO_WEAPONREADY3,//TORSO_WEAPONREADY8,//WP_FLECHETTE,
TORSO_WEAPONREADY3,//TORSO_WEAPONREADY9,//WP_ROCKET_LAUNCHER,
TORSO_WEAPONREADY10,//WP_THERMAL,
TORSO_WEAPONREADY3,//TORSO_WEAPONREADY11,//WP_TRIP_MINE,
TORSO_WEAPONREADY3,//TORSO_WEAPONREADY12,//WP_DET_PACK,
TORSO_WEAPONREADY10,//TORSO_WEAPONREADY11,//WP_TRIP_MINE,
TORSO_WEAPONREADY10,//TORSO_WEAPONREADY12,//WP_DET_PACK,
//NOT VALID (e.g. should never really be used):
BOTH_STAND1,//WP_EMPLACED_GUN,
@ -126,7 +126,7 @@ int WeaponAttackAnim[WP_NUM_WEAPONS] =
BOTH_ATTACK3,//BOTH_ATTACK7,//WP_DEMP2,
BOTH_ATTACK3,//BOTH_ATTACK8,//WP_FLECHETTE,
BOTH_ATTACK3,//BOTH_ATTACK9,//WP_ROCKET_LAUNCHER,
BOTH_ATTACK10,//WP_THERMAL,
BOTH_THERMAL_THROW,//WP_THERMAL,
BOTH_ATTACK3,//BOTH_ATTACK11,//WP_TRIP_MINE,
BOTH_ATTACK3,//BOTH_ATTACK12,//WP_DET_PACK,
@ -182,7 +182,7 @@ Instant shield pickup, restores 25
{ "models/map_objects/mp/psd_sm.md3",
0, 0, 0},
/* view */ NULL,
/* icon */ "gfx/hud/w_icon_blaster",
/* icon */ "gfx/mp/small_shield",
/* pickup */ "Shield Small",
25,
IT_ARMOR,
@ -200,7 +200,7 @@ Instant shield pickup, restores 100
{ "models/map_objects/mp/psd.md3",
0, 0, 0},
/* view */ NULL,
/* icon */ "gfx/hud/w_icon_blaster",
/* icon */ "gfx/mp/large_shield",
/* pickup */ "Shield Large",
100,
IT_ARMOR,
@ -265,7 +265,7 @@ Portable shield
IT_HOLDABLE,
HI_SHIELD,
/* precache */ "",
/* sounds */ "sound/weapons/detpack/stick.wav sound/movers/doors/forcefield_on.wav sound/movers/doors/forcefield_off.wav sound/effects/bumpfield.wav",
/* sounds */ "sound/weapons/detpack/stick.wav sound/movers/doors/forcefield_on.wav sound/movers/doors/forcefield_off.wav sound/movers/doors/forcefield_lp.wav sound/effects/bumpfield.wav",
},
/*QUAKED item_medpac (.3 .3 1) (-8 -8 -0) (8 8 16) suspended
@ -723,7 +723,7 @@ Ammo for Tenloss Disruptor, Wookie Bowcaster, and the Destructive Electro Magnet
{ "models/items/power_cell.md3",
0, 0, 0},
/* view */ NULL,
/* icon */ "gfx/hud/w_icon_blaster",
/* icon */ "gfx/mp/ammo_power_cell",
/* pickup */ "Power Cell",
100,
IT_AMMO,
@ -741,7 +741,7 @@ Ammo for Imperial Heavy Repeater and the Golan Arms Flechette
{ "models/items/metallic_bolts.md3",
0, 0, 0},
/* view */ NULL,
/* icon */ "gfx/hud/w_icon_blaster",
/* icon */ "gfx/mp/ammo_metallic_bolts",
/* pickup */ "Metallic Bolts",
100,
IT_AMMO,
@ -759,7 +759,7 @@ Ammo for Merr-Sonn portable missile launcher
{ "models/items/rockets.md3",
0, 0, 0},
/* view */ NULL,
/* icon */ "gfx/hud/w_icon_blaster",
/* icon */ "gfx/mp/ammo_rockets",
/* pickup */ "Rockets",
100,
IT_AMMO,
@ -1227,6 +1227,11 @@ qboolean BG_CanItemBeGrabbed( int gametype, const entityState_t *ent, const play
case IT_HEALTH:
// small and mega healths will go over the max, otherwise
// don't pick up if already at max
if ((ps->fd.forcePowersActive & (1 << FP_RAGE)))
{
return qfalse;
}
if ( item->quantity == 5 || item->quantity == 100 ) {
if ( ps->stats[STAT_HEALTH] >= ps->stats[STAT_MAX_HEALTH] * 2 ) {
return qfalse;
@ -1449,6 +1454,7 @@ char *eventnames[] = {
"EV_GRENADE_BOUNCE", // eventParm will be the soundindex
"EV_PLAY_EFFECT",
"EV_PLAY_EFFECT_ID", //finally gave in and added it..
"EV_MUTE_SOUND",
"EV_GENERAL_SOUND",
@ -1562,7 +1568,7 @@ void BG_TouchJumpPad( playerState_t *ps, entityState_t *jumppad ) {
} else {
effectNum = 1;
}
BG_AddPredictableEventToPlayerstate( EV_JUMP_PAD, effectNum, ps );
//BG_AddPredictableEventToPlayerstate( EV_JUMP_PAD, effectNum, ps );
}
// remember hitting this jumppad this frame
ps->jumppad_ent = jumppad->number;

View file

@ -544,7 +544,7 @@ char BGPAFtext[40000];
qboolean BGPAFtextLoaded = qfalse;
animation_t bgGlobalAnimations[MAX_TOTALANIMATIONS];
qboolean BG_ParseAnimationFile( const char *filename, animation_t *animations)
qboolean BG_ParseAnimationFile(const char *filename)
{
char *text_p;
int len;
@ -554,7 +554,7 @@ qboolean BG_ParseAnimationFile( const char *filename, animation_t *animations)
int skip;
fileHandle_t f;
int animNum;
int animNum;
// load the file
@ -567,7 +567,7 @@ qboolean BG_ParseAnimationFile( const char *filename, animation_t *animations)
}
if ( len >= sizeof( BGPAFtext ) - 1 )
{
// gi.Printf( "File %s too long\n", filename );
//Com_Printf( "File %s too long\n", filename );
return qfalse;
}
@ -577,17 +577,6 @@ qboolean BG_ParseAnimationFile( const char *filename, animation_t *animations)
}
else
{
for(i = 0; i < MAX_ANIMATIONS; i++)
{
animations[i].firstFrame = bgGlobalAnimations[i].firstFrame;
animations[i].flipflop = bgGlobalAnimations[i].flipflop;
animations[i].frameLerp = bgGlobalAnimations[i].frameLerp;
animations[i].initialLerp = bgGlobalAnimations[i].initialLerp;
animations[i].loopFrames = bgGlobalAnimations[i].loopFrames;
animations[i].numFrames = bgGlobalAnimations[i].numFrames;
animations[i].reversed = bgGlobalAnimations[i].reversed;
}
return qtrue;
}
@ -600,11 +589,11 @@ qboolean BG_ParseAnimationFile( const char *filename, animation_t *animations)
//initialize anim array so that from 0 to MAX_ANIMATIONS, set default values of 0 1 0 100
for(i = 0; i < MAX_ANIMATIONS; i++)
{
animations[i].firstFrame = 0;
animations[i].numFrames = 0;
animations[i].loopFrames = -1;
animations[i].frameLerp = 100;
animations[i].initialLerp = 100;
bgGlobalAnimations[i].firstFrame = 0;
bgGlobalAnimations[i].numFrames = 0;
bgGlobalAnimations[i].loopFrames = -1;
bgGlobalAnimations[i].frameLerp = 100;
bgGlobalAnimations[i].initialLerp = 100;
}
// read information for each frame
@ -632,21 +621,21 @@ qboolean BG_ParseAnimationFile( const char *filename, animation_t *animations)
{
break;
}
animations[animNum].firstFrame = atoi( token );
bgGlobalAnimations[animNum].firstFrame = atoi( token );
token = COM_Parse( (const char **)(&text_p) );
if ( !token )
{
break;
}
animations[animNum].numFrames = atoi( token );
bgGlobalAnimations[animNum].numFrames = atoi( token );
token = COM_Parse( (const char **)(&text_p) );
if ( !token )
{
break;
}
animations[animNum].loopFrames = atoi( token );
bgGlobalAnimations[animNum].loopFrames = atoi( token );
token = COM_Parse( (const char **)(&text_p) );
if ( !token )
@ -660,25 +649,14 @@ qboolean BG_ParseAnimationFile( const char *filename, animation_t *animations)
}
if ( fps < 0 )
{//backwards
animations[animNum].frameLerp = floor(1000.0f / fps);
bgGlobalAnimations[animNum].frameLerp = floor(1000.0f / fps);
}
else
{
animations[animNum].frameLerp = ceil(1000.0f / fps);
bgGlobalAnimations[animNum].frameLerp = ceil(1000.0f / fps);
}
animations[animNum].initialLerp = ceil(1000.0f / fabs(fps));
}
for(i = 0; i < MAX_ANIMATIONS; i++)
{
bgGlobalAnimations[i].firstFrame = animations[i].firstFrame;
bgGlobalAnimations[i].flipflop = animations[i].flipflop;
bgGlobalAnimations[i].frameLerp = animations[i].frameLerp;
bgGlobalAnimations[i].initialLerp = animations[i].initialLerp;
bgGlobalAnimations[i].loopFrames = animations[i].loopFrames;
bgGlobalAnimations[i].numFrames = animations[i].numFrames;
bgGlobalAnimations[i].reversed = animations[i].reversed;
bgGlobalAnimations[animNum].initialLerp = ceil(1000.0f / fabs(fps));
}
BGPAFtextLoaded = qtrue;

View file

@ -537,6 +537,22 @@ static qboolean PM_CheckJump( void )
}
*/
if (pm->ps->fd.forcePowersActive & (1 << FP_LEVITATION))
{
if (pm->ps->fd.forcePowerDebounce[FP_LEVITATION] < pm->cmd.serverTime)
{
BG_ForcePowerDrain( pm->ps, FP_LEVITATION, 5 );
if (pm->ps->fd.forcePowerLevel[FP_LEVITATION] >= FORCE_LEVEL_2)
{
pm->ps->fd.forcePowerDebounce[FP_LEVITATION] = pm->cmd.serverTime + 300;
}
else
{
pm->ps->fd.forcePowerDebounce[FP_LEVITATION] = pm->cmd.serverTime + 200;
}
}
}
if (pm->ps->forceJumpFlip)
{
int anim = BOTH_FORCEINAIR1;
@ -1501,6 +1517,13 @@ static void PM_WalkMove( void ) {
wishspeed = pm->ps->speed * pm_duckScale;
}
}
else if ( (pm->ps->pm_flags & PMF_ROLLING) && !BG_InRoll(pm->ps, pm->ps->legsAnim) &&
!PM_InRollComplete(pm->ps, pm->ps->legsAnim))
{
if ( wishspeed > pm->ps->speed * pm_duckScale ) {
wishspeed = pm->ps->speed * pm_duckScale;
}
}
// clamp the speed lower if wading or walking on the bottom
if ( pm->waterlevel ) {
@ -2381,7 +2404,7 @@ static void PM_Footsteps( void ) {
if ( !pm->cmd.forwardmove && !pm->cmd.rightmove ) {
if ( pm->xyspeed < 5 ) {
pm->ps->bobCycle = 0; // start at beginning of cycle again
if ( pm->ps->pm_flags & PMF_DUCKED ) {
if ( (pm->ps->pm_flags & PMF_DUCKED) || (pm->ps->pm_flags & PMF_ROLLING) ) {
PM_ContinueLegsAnim( BOTH_CROUCH1IDLE );
} else {
if (pm->ps->weapon == WP_DISRUPTOR && pm->ps->zoomMode == 1)
@ -2447,7 +2470,23 @@ static void PM_Footsteps( void ) {
}
PM_ContinueLegsAnim( LEGS_BACK );
*/
} else {
}
else if ((pm->ps->pm_flags & PMF_ROLLING) && !BG_InRoll(pm->ps, pm->ps->legsAnim) &&
!PM_InRollComplete(pm->ps, pm->ps->legsAnim))
{
bobmove = 0.5; // ducked characters bob much faster
if ( pm->ps->pm_flags & PMF_BACKWARDS_RUN )
{
PM_ContinueLegsAnim( BOTH_CROUCH1WALKBACK );
}
else
{
PM_ContinueLegsAnim( BOTH_CROUCH1WALK );
}
}
else
{
if ( !( pm->cmd.buttons & BUTTON_WALKING ) ) {
bobmove = 0.4f; // faster speeds bob faster
if ( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) {
@ -2458,7 +2497,7 @@ static void PM_Footsteps( void ) {
}
footstep = qtrue;
} else {
bobmove = 0.3f; // walking bobs slow
bobmove = 0.2f; // walking bobs slow
if ( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) {
PM_ContinueLegsAnim( BOTH_WALKBACK1 );
}
@ -2638,16 +2677,27 @@ static qboolean PM_DoChargedWeapons( void )
// implement our alt-fire locking stuff
if ( (pm->cmd.buttons & BUTTON_ALT_ATTACK) && pm->ps->ammo[weaponData[pm->ps->weapon].ammoIndex] >= weaponData[pm->ps->weapon].altEnergyPerShot )
{
vec3_t muzzleOffPoint, muzzlePoint, forward, right, up;
AngleVectors( pm->ps->viewangles, forward, right, up );
charging = qtrue;
altFire = qtrue;
AngleVectors(pm->ps->viewangles, ang, NULL, NULL);
ang[0] = pm->ps->origin[0] + ang[0]*2048;
ang[1] = pm->ps->origin[1] + ang[1]*2048;
ang[2] = pm->ps->origin[2] + ang[2]*2048;
VectorCopy( pm->ps->origin, muzzlePoint );
VectorCopy(WP_MuzzlePoint[WP_ROCKET_LAUNCHER], muzzleOffPoint);
pm->trace(&tr, pm->ps->origin, NULL, NULL, ang, pm->ps->clientNum, MASK_PLAYERSOLID);
VectorMA(muzzlePoint, muzzleOffPoint[0], forward, muzzlePoint);
VectorMA(muzzlePoint, muzzleOffPoint[1], right, muzzlePoint);
muzzlePoint[2] += pm->ps->viewheight + muzzleOffPoint[2];
ang[0] = muzzlePoint[0] + ang[0]*2048;
ang[1] = muzzlePoint[1] + ang[1]*2048;
ang[2] = muzzlePoint[2] + ang[2]*2048;
pm->trace(&tr, muzzlePoint, NULL, NULL, ang, pm->ps->clientNum, MASK_PLAYERSOLID);
if (tr.fraction != 1 && tr.entityNum < MAX_CLIENTS && tr.entityNum != pm->ps->clientNum)
{
@ -2669,7 +2719,10 @@ static qboolean PM_DoChargedWeapons( void )
}
}
pm->ps->rocketTargetTime = pm->cmd.serverTime + 500;
if (pm->ps->rocketLockIndex == tr.entityNum)
{
pm->ps->rocketTargetTime = pm->cmd.serverTime + 500;
}
}
else if (pm->ps->rocketTargetTime < pm->cmd.serverTime)
{
@ -3127,6 +3180,28 @@ static void PM_Weapon( void ) {
pm->ps->saberHolstered = qfalse;
}
if (pm->ps->weapon == WP_THERMAL ||
pm->ps->weapon == WP_TRIP_MINE ||
pm->ps->weapon == WP_DET_PACK)
{
if (pm->ps->weapon == WP_THERMAL)
{
if ((pm->ps->torsoAnim&~ANIM_TOGGLEBIT) == WeaponAttackAnim[pm->ps->weapon] &&
(pm->ps->weaponTime-200) <= 0)
{
PM_StartTorsoAnim( WeaponReadyAnim[pm->ps->weapon] );
}
}
else
{
if ((pm->ps->torsoAnim&~ANIM_TOGGLEBIT) == WeaponAttackAnim[pm->ps->weapon] &&
(pm->ps->weaponTime-700) <= 0)
{
PM_StartTorsoAnim( WeaponReadyAnim[pm->ps->weapon] );
}
}
}
// don't allow attack until all buttons are up
if ( pm->ps->pm_flags & PMF_RESPAWNED ) {
return;
@ -3464,6 +3539,7 @@ static void PM_Animate( void ) {
PM_StartTorsoAnim( BOTH_TALKGESTURE3 );
pm->ps->torsoTimer = TIMER_GESTURE;
*/
pm->ps->forceHandExtend = HANDEXTEND_TAUNT;
//FIXME: random taunt anims?
@ -3471,6 +3547,8 @@ static void PM_Animate( void ) {
pm->ps->forceHandExtendTime = pm->cmd.serverTime + 1000;
pm->ps->weaponTime = 100;
PM_AddEvent( EV_TAUNT );
}
#if 0
@ -3599,7 +3677,7 @@ void PM_AdjustAttackStates( pmove_t *pm )
}
// disruptor alt-fire should toggle the zoom mode, but only bother doing this for the player?
if ( pm->ps->weapon == WP_DISRUPTOR)
if ( pm->ps->weapon == WP_DISRUPTOR && pm->ps->weaponstate == WEAPON_READY )
{
if ( !(pm->ps->eFlags & EF_ALT_FIRING) && (pm->cmd.buttons & BUTTON_ALT_ATTACK) &&
pm->cmd.upmove <= 0 && !pm->cmd.forwardmove && !pm->cmd.rightmove)

View file

@ -71,6 +71,8 @@
#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
// these are also in be_aas_def.h - argh (rjr)
#define CS_MODELS 32
#define CS_SOUNDS (CS_MODELS+MAX_MODELS)
@ -163,6 +165,8 @@ typedef struct animation_s {
int flipflop; // true if animation should flipflop back to base
} animation_t;
extern qboolean BGPAFtextLoaded;
extern animation_t bgGlobalAnimations[MAX_TOTALANIMATIONS];
// flip the togglebit every time an animation
// changes so a restart of the same anim can be detected
@ -362,6 +366,7 @@ typedef enum {
EFFECT_NONE = 0,
EFFECT_SMOKE,
EFFECT_EXPLOSION,
EFFECT_EXPLOSION_PAS,
EFFECT_SPARK_EXPLOSION,
EFFECT_EXPLOSION_TRIPMINE,
EFFECT_EXPLOSION_DETPACK,
@ -525,6 +530,7 @@ typedef enum {
EV_MISSILE_STICK, // eventParm will be the soundindex
EV_PLAY_EFFECT,
EV_PLAY_EFFECT_ID,
EV_MUTE_SOUND,
EV_GENERAL_SOUND,
@ -973,6 +979,8 @@ qboolean BG_InDeathAnim( int anim );
void BG_SaberStartTransAnim( int saberAnimLevel, int anim, float *animSpeed );
void BG_ForcePowerDrain( playerState_t *ps, forcePowers_t forcePower, int overrideAmt );
void BG_EvaluateTrajectory( const trajectory_t *tr, int atTime, vec3_t result );
void BG_EvaluateTrajectoryDelta( const trajectory_t *tr, int atTime, vec3_t result );
@ -988,7 +996,7 @@ void BG_G2PlayerAngles( vec3_t startAngles, vec3_t legs[3], vec3_t legsAngles, i
qboolean BG_PlayerTouchesItem( playerState_t *ps, entityState_t *item, int atTime );
qboolean BG_ParseAnimationFile( const char *filename, animation_t *animations);
qboolean BG_ParseAnimationFile(const char *filename);
int BG_GetItemIndexByTag(int tag, int type);

View file

@ -18,6 +18,76 @@ int PM_irand_timesync(int val1, int val2)
return i;
}
void BG_ForcePowerDrain( playerState_t *ps, forcePowers_t forcePower, int overrideAmt )
{
//take away the power
int drain = overrideAmt;
if (ps->powerups[PW_FORCE_BOON])
{
return;
}
if ( !drain )
{
drain = forcePowerNeeded[ps->fd.forcePowerLevel[forcePower]][forcePower];
}
if ( !drain )
{
return;
}
if (forcePower == FP_LEVITATION)
{ //special case
int jumpDrain = 0;
if (ps->velocity[2] > 250)
{
jumpDrain = 20;
}
else if (ps->velocity[2] > 200)
{
jumpDrain = 16;
}
else if (ps->velocity[2] > 150)
{
jumpDrain = 12;
}
else if (ps->velocity[2] > 100)
{
jumpDrain = 8;
}
else if (ps->velocity[2] > 50)
{
jumpDrain = 6;
}
else if (ps->velocity[2] > 0)
{
jumpDrain = 4;
}
if (jumpDrain)
{
jumpDrain /= ps->fd.forcePowerLevel[FP_LEVITATION];
}
ps->fd.forcePower -= jumpDrain;
if ( ps->fd.forcePower < 0 )
{
ps->fd.forcePower = 0;
}
return;
}
ps->fd.forcePower -= drain;
if ( ps->fd.forcePower < 0 )
{
ps->fd.forcePower = 0;
}
}
// Silly, but I'm replacing these macros so they are shorter!
#define AFLAG_IDLE (SETANIM_FLAG_NORMAL)
#define AFLAG_ACTIVE (/*SETANIM_FLAG_OVERRIDE | */SETANIM_FLAG_HOLD | SETANIM_FLAG_HOLDLESS)
@ -783,16 +853,20 @@ int PM_BrokenParryForParry( int move )
return LS_NONE;
}
#define BACK_STAB_DISTANCE 64
#define BACK_STAB_DISTANCE 128//64
qboolean PM_CanBackstab(void)
{
trace_t tr;
vec3_t flatAng;
vec3_t fwd, back;
vec3_t trmins = {-15, -15, -8};
vec3_t trmaxs = {15, 15, 8};
AngleVectors(pm->ps->viewangles, fwd, 0, 0);
VectorCopy(pm->ps->viewangles, flatAng);
flatAng[PITCH] = 0;
AngleVectors(flatAng, fwd, 0, 0);
back[0] = pm->ps->origin[0] - fwd[0]*BACK_STAB_DISTANCE;
back[1] = pm->ps->origin[1] - fwd[1]*BACK_STAB_DISTANCE;
@ -866,15 +940,19 @@ saberMoveName_t PM_SaberFlipOverAttackMove(trace_t *tr)
}
}
#define FLIPHACK_DISTANCE 128
#define FLIPHACK_DISTANCE 200
qboolean PM_SomeoneInFront(trace_t *tr)
{ //Also a very simplified version of the sp counterpart
vec3_t flatAng;
vec3_t fwd, back;
vec3_t trmins = {-15, -15, -8};
vec3_t trmaxs = {15, 15, 8};
AngleVectors(pm->ps->viewangles, fwd, 0, 0);
VectorCopy(pm->ps->viewangles, flatAng);
flatAng[PITCH] = 0;
AngleVectors(flatAng, fwd, 0, 0);
back[0] = pm->ps->origin[0] + fwd[0]*FLIPHACK_DISTANCE;
back[1] = pm->ps->origin[1] + fwd[1]*FLIPHACK_DISTANCE;
@ -1184,7 +1262,7 @@ void PM_WeaponLightsaber(void)
if (pm->ps->weaponstate == WEAPON_READY ||
pm->ps->weaponstate == WEAPON_IDLE)
{
if (pm->ps->saberMove != LS_READY)
if (pm->ps->saberMove != LS_READY && pm->ps->weaponTime <= 0 && !pm->ps->saberBlocked)
{
PM_SetSaberMove( LS_READY );
}

View file

@ -730,7 +730,7 @@ void ClientEvents( gentity_t *ent, int oldEventSequence ) {
case EV_FALL:
case EV_ROLL:
{
int delta = ent->s.eventParm;
int delta = client->ps.eventParms[ i & (MAX_PS_EVENTS-1) ];
if (ent->client && ent->client->ps.fallingToDeath)
{
@ -1331,7 +1331,7 @@ void ClientThink_real( gentity_t *ent ) {
pm.pmove_fixed = pmove_fixed.integer | client->pers.pmoveFixed;
pm.pmove_msec = pmove_msec.integer;
pm.animations = client->animations;//NULL;
pm.animations = bgGlobalAnimations;//NULL;
pm.gametype = g_gametype.integer;
@ -1393,6 +1393,122 @@ void ClientThink_real( gentity_t *ent ) {
Pmove (&pm);
switch(pm.cmd.generic_cmd)
{
case 0:
break;
case GENCMD_SABERSWITCH:
Cmd_ToggleSaber_f(ent);
break;
case GENCMD_ENGAGE_DUEL:
Cmd_EngageDuel_f(ent);
break;
case GENCMD_FORCE_HEAL:
ForceHeal(ent);
break;
case GENCMD_FORCE_SPEED:
ForceSpeed(ent, 0);
break;
case GENCMD_FORCE_THROW:
ForceThrow(ent, qfalse);
break;
case GENCMD_FORCE_PULL:
ForceThrow(ent, qtrue);
break;
case GENCMD_FORCE_DISTRACT:
ForceTelepathy(ent);
break;
case GENCMD_FORCE_RAGE:
ForceRage(ent);
break;
case GENCMD_FORCE_PROTECT:
ForceProtect(ent);
break;
case GENCMD_FORCE_ABSORB:
ForceAbsorb(ent);
break;
case GENCMD_FORCE_HEALOTHER:
ForceTeamHeal(ent);
break;
case GENCMD_FORCE_FORCEPOWEROTHER:
ForceTeamForceReplenish(ent);
break;
case GENCMD_FORCE_SEEING:
ForceSeeing(ent);
break;
case GENCMD_USE_SEEKER:
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_SEEKER)) &&
G_ItemUsable(&ent->client->ps, HI_SEEKER) )
{
ItemUse_Seeker(ent);
G_AddEvent(ent, EV_USE_ITEM0+HI_SEEKER, 0);
ent->client->ps.stats[STAT_HOLDABLE_ITEMS] &= ~(1 << HI_SEEKER);
}
break;
case GENCMD_USE_FIELD:
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_SHIELD)) &&
G_ItemUsable(&ent->client->ps, HI_SHIELD) )
{
ItemUse_Shield(ent);
G_AddEvent(ent, EV_USE_ITEM0+HI_SHIELD, 0);
ent->client->ps.stats[STAT_HOLDABLE_ITEMS] &= ~(1 << HI_SHIELD);
}
break;
case GENCMD_USE_BACTA:
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_MEDPAC)) &&
G_ItemUsable(&ent->client->ps, HI_MEDPAC) )
{
ItemUse_MedPack(ent);
G_AddEvent(ent, EV_USE_ITEM0+HI_MEDPAC, 0);
ent->client->ps.stats[STAT_HOLDABLE_ITEMS] &= ~(1 << HI_MEDPAC);
}
break;
case GENCMD_USE_ELECTROBINOCULARS:
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_BINOCULARS)) &&
G_ItemUsable(&ent->client->ps, HI_BINOCULARS) )
{
ItemUse_Binoculars(ent);
if (ent->client->ps.zoomMode == 0)
{
G_AddEvent(ent, EV_USE_ITEM0+HI_BINOCULARS, 1);
}
else
{
G_AddEvent(ent, EV_USE_ITEM0+HI_BINOCULARS, 2);
}
}
break;
case GENCMD_ZOOM:
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_BINOCULARS)) &&
G_ItemUsable(&ent->client->ps, HI_BINOCULARS) )
{
ItemUse_Binoculars(ent);
if (ent->client->ps.zoomMode == 0)
{
G_AddEvent(ent, EV_USE_ITEM0+HI_BINOCULARS, 1);
}
else
{
G_AddEvent(ent, EV_USE_ITEM0+HI_BINOCULARS, 2);
}
}
break;
case GENCMD_USE_SENTRY:
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_SENTRY_GUN)) &&
G_ItemUsable(&ent->client->ps, HI_SENTRY_GUN) )
{
ItemUse_Sentry(ent);
G_AddEvent(ent, EV_USE_ITEM0+HI_SENTRY_GUN, 0);
ent->client->ps.stats[STAT_HOLDABLE_ITEMS] &= ~(1 << HI_SENTRY_GUN);
}
break;
case GENCMD_SABERATTACKCYCLE:
Cmd_SaberAttackCycle_f(ent);
break;
default:
break;
}
// save results of pmove
if ( ent->client->ps.eventSequence != oldEventSequence ) {
ent->eventTime = level.time;

View file

@ -158,8 +158,52 @@ int G_GetMapTypeBits(char *type)
return typeBits;
}
qboolean G_DoesMapSupportGametype(const char *mapname, int gametype)
{
int typeBits = 0;
int thisLevel = -1;
int n = 0;
char *type = NULL;
if (!g_arenaInfos[0])
{
return qfalse;
}
if (!mapname || !mapname[0])
{
return qfalse;
}
for( n = 0; n < g_numArenas; n++ )
{
type = Info_ValueForKey( g_arenaInfos[n], "map" );
if (Q_stricmp(mapname, type) == 0)
{
thisLevel = n;
break;
}
}
if (thisLevel == -1)
{
return qfalse;
}
type = Info_ValueForKey(g_arenaInfos[thisLevel], "type");
typeBits = G_GetMapTypeBits(type);
if (typeBits & (1 << gametype))
{ //the map in question supports the gametype in question, so..
return qtrue;
}
return qfalse;
}
//rww - auto-obtain nextmap. I could've sworn Q3 had something like this, but I guess not.
void G_RefreshNextMap(int gametype)
const char *G_RefreshNextMap(int gametype, qboolean forced)
{
int typeBits = 0;
int thisLevel = 0;
@ -169,14 +213,14 @@ void G_RefreshNextMap(int gametype)
qboolean loopingUp = qfalse;
vmCvar_t mapname;
if (!g_autoMapCycle.integer)
if (!g_autoMapCycle.integer && !forced)
{
return;
return NULL;
}
if (!g_arenaInfos[0])
{
return;
return NULL;
}
trap_Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM );
@ -229,6 +273,8 @@ void G_RefreshNextMap(int gametype)
type = Info_ValueForKey( g_arenaInfos[desiredMap], "map" );
trap_Cvar_Set( "nextmap", va("map %s", type));
}
return Info_ValueForKey( g_arenaInfos[desiredMap], "map" );
}
/*
@ -270,7 +316,7 @@ static void G_LoadArenas( void ) {
Info_SetValueForKey( g_arenaInfos[n], "num", va( "%i", n ) );
}
G_RefreshNextMap(g_gametype.integer);
G_RefreshNextMap(g_gametype.integer, qfalse);
}

View file

@ -81,6 +81,8 @@ void ThrowSaberToAttacker(gentity_t *self, gentity_t *attacker)
return;
}
trap_SetConfigstring ( CS_CLIENT_JEDIMASTER, "-1" );
if (attacker && attacker->client && self->client->ps.saberInFlight)
{ //someone killed us and we had the saber thrown, so actually move this saber to the saber location
//if we killed ourselves with saber thrown, however, same suicide rules of respawning at spawn spot still
@ -211,6 +213,9 @@ void JMSaberTouch(gentity_t *self, gentity_t *other, trace_t *trace)
other->s.weapon = WP_SABER;
G_AddEvent(other, EV_BECOME_JEDIMASTER, 0);
// Track the jedi master
trap_SetConfigstring ( CS_CLIENT_JEDIMASTER, va("%i", other->s.number ) );
if (g_spawnInvulnerability.integer)
{
other->client->ps.eFlags |= EF_INVULNERABLE;
@ -973,10 +978,22 @@ void SetupGameGhoul2Model(gclient_t *client, char *modelname)
*/
//rww - just load the "standard" model for the server"
Com_sprintf( afilename, sizeof( afilename ), "models/players/kyle/model.glm" );
handle = trap_G2API_InitGhoul2Model(&client->ghoul2, afilename, 0, 0, -20, 0, 0);
if (!precachedKyle)
{
Com_sprintf( afilename, sizeof( afilename ), "models/players/kyle/model.glm" );
handle = trap_G2API_InitGhoul2Model(&precachedKyle, afilename, 0, 0, -20, 0, 0);
if (handle<0)
if (handle<0)
{
return;
}
}
if (precachedKyle && trap_G2_HaveWeGhoul2Models(precachedKyle))
{
trap_G2API_DuplicateGhoul2Instance(precachedKyle, &client->ghoul2);
}
else
{
return;
}
@ -985,38 +1002,41 @@ void SetupGameGhoul2Model(gclient_t *client, char *modelname)
GLAName[0] = 0;
//get the location of the animation.cfg
//GLAName = trap_G2API_GetGLAName( client->ghoul2, 0);
trap_G2API_GetGLAName( client->ghoul2, 0, GLAName);
if (!GLAName[0])
if (!BGPAFtextLoaded)
{
if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg", client->animations))
//get the location of the animation.cfg
//GLAName = trap_G2API_GetGLAName( client->ghoul2, 0);
trap_G2API_GetGLAName( client->ghoul2, 0, GLAName);
if (!GLAName[0])
{
Com_Printf( "Failed to load animation file %s\n", afilename );
if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg"))
{
Com_Printf( "Failed to load animation file %s\n", afilename );
return;
}
return;
}
return;
}
Q_strncpyz( afilename, GLAName, sizeof( afilename ));
slash = Q_strrchr( afilename, '/' );
if ( slash )
{
strcpy(slash, "/animation.cfg");
} // Now afilename holds just the path to the animation.cfg
else
{ // Didn't find any slashes, this is a raw filename right in base (whish isn't a good thing)
return;
}
// Try to load the animation.cfg for this model then.
if ( !BG_ParseAnimationFile( afilename, client->animations ) )
{ // The GLA's animations failed
if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg", client->animations))
Q_strncpyz( afilename, GLAName, sizeof( afilename ));
slash = Q_strrchr( afilename, '/' );
if ( slash )
{
Com_Printf( "Failed to load animation file %s\n", afilename );
strcpy(slash, "/animation.cfg");
} // Now afilename holds just the path to the animation.cfg
else
{ // Didn't find any slashes, this is a raw filename right in base (whish isn't a good thing)
return;
}
// Try to load the animation.cfg for this model then.
if ( !BG_ParseAnimationFile( afilename ) )
{ // The GLA's animations failed
if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg"))
{
Com_Printf( "Failed to load animation file %s\n", afilename );
return;
}
}
}
trap_G2API_AddBolt(client->ghoul2, 0, "*r_hand");
@ -1459,7 +1479,6 @@ void ClientSpawn(gentity_t *ent) {
// char userinfo[MAX_INFO_STRING];
forcedata_t savedForce;
void *ghoul2save;
animation_t animations[MAX_TOTALANIMATIONS];
int saveSaberNum = ENTITYNUM_NONE;
index = ent - g_entities;
@ -1543,23 +1562,10 @@ void ClientSpawn(gentity_t *ent) {
saveSaberNum = client->ps.saberEntityNum;
i = 0;
while (i < MAX_TOTALANIMATIONS)
{
animations[i] = client->animations[i];
i++;
}
memset (client, 0, sizeof(*client)); // bk FIXME: Com_Memset?
//rww - Don't wipe the ghoul2 instance or the animation data
client->ghoul2 = ghoul2save;
i = 0;
while (i < MAX_TOTALANIMATIONS)
{
client->animations[i] = animations[i];
i++;
}
//or the saber ent num
client->ps.saberEntityNum = saveSaberNum;

View file

@ -816,6 +816,10 @@ Cmd_Team_f
*/
void Cmd_ForceChanged_f( gentity_t *ent )
{
char fpChStr[1024];
const char *buf;
int i = 0;
int ccount = 0;
// Cmd_Kill_f(ent);
if (ent->client->sess.sessionTeam == TEAM_SPECTATOR)
{ //if it's a spec, just make the changes now
@ -823,7 +827,23 @@ void Cmd_ForceChanged_f( gentity_t *ent )
WP_InitForcePowers( ent );
return;
}
trap_SendServerCommand( ent-g_entities, va("print \"%s\n\"", G_GetStripEdString("SVINGAME", "FORCEPOWERCHANGED")) );
buf = G_GetStripEdString("SVINGAME", "FORCEPOWERCHANGED");
strcpy(fpChStr, buf);
while (i < 1024 && fpChStr[i])
{
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;
}
@ -1412,6 +1432,12 @@ void Cmd_CallVote_f( gentity_t *ent ) {
// this allows a player to change maps, but not upset the map rotation
char s[MAX_STRING_CHARS];
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\"" );
return;
}
trap_Cvar_VariableStringBuffer( "nextmap", s, sizeof(s) );
if (*s) {
Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s; set nextmap \"%s\"", arg1, arg2, s );
@ -1753,6 +1779,11 @@ int G_ItemUsable(playerState_t *ps, int forcedUse)
return 0;
}
if (ps->stats[STAT_HEALTH] <= 0)
{
return 0;
}
return 1;
case HI_SEEKER:
if (ps->eFlags & EF_SEEKERDRONE)
@ -1911,13 +1942,13 @@ void Cmd_SaberAttackCycle_f(gentity_t *ent)
switch ( selectLevel )
{
case FORCE_LEVEL_1:
trap_SendServerCommand( ent-g_entities, "print \"Saber Attack Set: fast\n\"" );
trap_SendServerCommand( ent-g_entities, va("print \"Saber Attack Set: %sfast\n\"", S_COLOR_GREEN) );
break;
case FORCE_LEVEL_2:
trap_SendServerCommand( ent-g_entities, "print \"Saber Attack Set: medium\n\"" );
trap_SendServerCommand( ent-g_entities, va("print \"Saber Attack Set: %smedium\n\"", S_COLOR_YELLOW) );
break;
case FORCE_LEVEL_3:
trap_SendServerCommand( ent-g_entities, "print \"Saber Attack Set: strong\n\"" );
trap_SendServerCommand( ent-g_entities, va("print \"Saber Attack Set: %sstrong\n\"", S_COLOR_RED) );
break;
}
@ -2153,8 +2184,100 @@ void ClientCommand( int clientNum ) {
}
// ignore all other commands when at intermission
if (level.intermissiontime) {
Cmd_Say_f (ent, qfalse, qtrue);
if (level.intermissiontime)
{
qboolean giveError = qfalse;
if (!Q_stricmp(cmd, "give"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "god"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "notarget"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "noclip"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "kill"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "teamtask"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "levelshot"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "follow"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "follownext"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "followprev"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "team"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "forcechanged"))
{ //special case: still update force change
Cmd_ForceChanged_f (ent);
return;
}
else if (!Q_stricmp(cmd, "where"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "callvote"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "vote"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "callteamvote"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "teamvote"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "gc"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "setviewpos"))
{
giveError = qtrue;
}
else if (!Q_stricmp(cmd, "stats"))
{
giveError = qtrue;
}
if (giveError)
{
trap_SendServerCommand( clientNum, va("print \"You cannot perform this task (%s) during the intermission.\n\"", cmd ) );
}
else
{
Cmd_Say_f (ent, qfalse, qtrue);
}
return;
}
@ -2200,112 +2323,6 @@ void ClientCommand( int clientNum ) {
Cmd_SetViewpos_f( ent );
else if (Q_stricmp (cmd, "stats") == 0)
Cmd_Stats_f( ent );
else if (Q_stricmp (cmd, "sv_saberswitch") == 0)
Cmd_ToggleSaber_f(ent);
else if (Q_stricmp (cmd, "engage_duel") == 0)
Cmd_EngageDuel_f(ent);
else if (Q_stricmp (cmd, "force_heal") == 0)
ForceHeal(ent);
else if (Q_stricmp (cmd, "force_speed") == 0)
ForceSpeed(ent, 0);
else if (Q_stricmp (cmd, "force_throw") == 0)
ForceThrow( ent, qfalse );
else if (Q_stricmp (cmd, "force_pull") == 0)
ForceThrow( ent, qtrue );
else if (Q_stricmp (cmd, "force_distract") == 0)
ForceTelepathy( ent );
else if (Q_stricmp (cmd, "force_rage") == 0)
ForceRage(ent);
else if (Q_stricmp (cmd, "force_protect") == 0)
ForceProtect(ent);
else if (Q_stricmp (cmd, "force_absorb") == 0)
ForceAbsorb(ent);
else if (Q_stricmp (cmd, "force_healother") == 0)
ForceTeamHeal(ent);
else if (Q_stricmp (cmd, "force_forcepowerother") == 0)
ForceTeamForceReplenish(ent);
else if (Q_stricmp (cmd, "force_seeing") == 0)
ForceSeeing(ent);
else if (Q_stricmp (cmd, "use_seeker") == 0)
{
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_SEEKER)) &&
G_ItemUsable(&ent->client->ps, HI_SEEKER) )
{
ItemUse_Seeker(ent);
G_AddEvent(ent, EV_USE_ITEM0+HI_SEEKER, 0);
ent->client->ps.stats[STAT_HOLDABLE_ITEMS] &= ~(1 << HI_SEEKER);
}
}
else if (Q_stricmp (cmd, "use_field") == 0)
{
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_SHIELD)) &&
G_ItemUsable(&ent->client->ps, HI_SHIELD) )
{
ItemUse_Shield(ent);
G_AddEvent(ent, EV_USE_ITEM0+HI_SHIELD, 0);
ent->client->ps.stats[STAT_HOLDABLE_ITEMS] &= ~(1 << HI_SHIELD);
}
}
else if (Q_stricmp (cmd, "use_bacta") == 0)
{
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_MEDPAC)) &&
G_ItemUsable(&ent->client->ps, HI_MEDPAC) )
{
ItemUse_MedPack(ent);
G_AddEvent(ent, EV_USE_ITEM0+HI_MEDPAC, 0);
ent->client->ps.stats[STAT_HOLDABLE_ITEMS] &= ~(1 << HI_MEDPAC);
}
}
else if (Q_stricmp (cmd, "use_electrobinoculars") == 0)
{
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_BINOCULARS)) &&
G_ItemUsable(&ent->client->ps, HI_BINOCULARS) )
{
ItemUse_Binoculars(ent);
if (ent->client->ps.zoomMode == 0)
{
G_AddEvent(ent, EV_USE_ITEM0+HI_BINOCULARS, 1);
}
else
{
G_AddEvent(ent, EV_USE_ITEM0+HI_BINOCULARS, 2);
}
}
}
else if (Q_stricmp (cmd, "zoom") == 0)
{ //cheap way of doing this
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_BINOCULARS)) &&
G_ItemUsable(&ent->client->ps, HI_BINOCULARS) )
{
ItemUse_Binoculars(ent);
if (ent->client->ps.zoomMode == 0)
{
G_AddEvent(ent, EV_USE_ITEM0+HI_BINOCULARS, 1);
}
else
{
G_AddEvent(ent, EV_USE_ITEM0+HI_BINOCULARS, 2);
}
}
}
else if (Q_stricmp (cmd, "use_sentry") == 0)
{
if ( (ent->client->ps.stats[STAT_HOLDABLE_ITEMS] & (1 << HI_SENTRY_GUN)) &&
G_ItemUsable(&ent->client->ps, HI_SENTRY_GUN) )
{
ItemUse_Sentry(ent);
G_AddEvent(ent, EV_USE_ITEM0+HI_SENTRY_GUN, 0);
ent->client->ps.stats[STAT_HOLDABLE_ITEMS] &= ~(1 << HI_SENTRY_GUN);
}
}
else if (Q_stricmp (cmd, "bot_order") == 0)
{
BotOrder(ent, atoi(ConcatArgs( 1 )), atoi(ConcatArgs( 2 )));
}
else if (Q_stricmp (cmd, "saberAttackCycle") == 0)
{
Cmd_SaberAttackCycle_f(ent);
}
else if (Q_stricmp(cmd, "#mm") == 0 && CheatsOk( ent ))
{
G_PlayerBecomeATST(ent);
@ -2361,5 +2378,14 @@ void ClientCommand( int clientNum ) {
}
*/
else
trap_SendServerCommand( clientNum, va("print \"unknown cmd %s\n\"", cmd ) );
{
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
trap_SendServerCommand( clientNum, va("print \"You can only add bots as the server.\n\"" ) );
}
else
{
trap_SendServerCommand( clientNum, va("print \"unknown cmd %s\n\"", cmd ) );
}
}
}

View file

@ -868,7 +868,7 @@ void turret_die(gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
// hack the effect angle so that explode death can orient the effect properly
VectorSet( self->s.angles, 0, 0, 1 );
G_PlayEffect(EFFECT_EXPLOSION, self->s.pos.trBase, self->s.angles);
G_PlayEffect(EFFECT_EXPLOSION_PAS, self->s.pos.trBase, self->s.angles);
G_RadiusDamage(self->s.pos.trBase, &g_entities[self->boltpoint3], 30, 256, self, MOD_UNKNOWN);
g_entities[self->boltpoint3].client->ps.fd.sentryDeployed = qfalse;
@ -910,6 +910,8 @@ void SP_PAS( gentity_t *base )
base->takedamage = qtrue;
base->die = turret_die;
base->physicsObject = qtrue;
G_Sound( base, CHAN_BODY, G_SoundIndex( "sound/chars/turret/startup.wav" ));
}
@ -1512,6 +1514,10 @@ gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity ) {
dropped->s.eType = ET_ITEM;
dropped->s.modelindex = item - bg_itemlist; // store item number in modelindex
if (dropped->s.modelindex < 0)
{
dropped->s.modelindex = 0;
}
dropped->s.modelindex2 = 1; // This is non-zero is it's a dropped item
dropped->classname = item->classname;
@ -1571,6 +1577,8 @@ gentity_t *LaunchItem( gitem_t *item, vec3_t origin, vec3_t velocity ) {
dropped->s.angles[ROLL] = -90;
}
dropped->physicsObject = qtrue;
trap_LinkEntity (dropped);
return dropped;

View file

@ -85,6 +85,9 @@ typedef enum
//============================================================================
extern void *precachedKyle;
extern void *g2SaberInstance;
typedef struct gentity_s gentity_t;
typedef struct gclient_s gclient_t;
@ -394,7 +397,6 @@ struct gclient_s {
char *areabits;
animation_t animations[MAX_TOTALANIMATIONS];
void *ghoul2; // In parallel with the centity, there is a corresponding ghoul2 model for players.
// This is an instance that is maintained on the server side that is used for
// determining saber position and per-poly collision
@ -520,6 +522,10 @@ void BroadcastTeamChange( gclient_t *client, int oldTeam );
void SetTeam( gentity_t *ent, char *s );
void Cmd_FollowCycle_f( gentity_t *ent, int dir );
void Cmd_SaberAttackCycle_f(gentity_t *ent);
int G_ItemUsable(playerState_t *ps, int forcedUse);
void Cmd_ToggleSaber_f(gentity_t *ent);
void Cmd_EngageDuel_f(gentity_t *ent);
gentity_t *G_GetDuelWinner(gclient_t *client);
//
@ -556,6 +562,7 @@ void SaveRegisteredItems( void );
//
int G_ModelIndex( char *name );
int G_SoundIndex( char *name );
int G_EffectIndex( char *name );
void G_TeamCommand( team_t team, char *cmd );
void G_KillBox (gentity_t *ent);
gentity_t *G_Find (gentity_t *from, int fieldofs, const char *match);
@ -829,7 +836,8 @@ qboolean G_BotConnect( int clientNum, qboolean restart );
void Svcmd_AddBot_f( void );
void Svcmd_BotList_f( void );
void BotInterbreedEndMatch( void );
void G_RefreshNextMap(int gametype);
qboolean G_DoesMapSupportGametype(const char *mapname, int gametype);
const char *G_RefreshNextMap(int gametype, qboolean forced);
// w_saber.c
qboolean HasSetSaberOnly(void);

View file

@ -111,7 +111,7 @@ static cvarTable_t gameCvarTable[] = {
// change anytime vars
{ &g_ff_objectives, "g_ff_objectives", "0", /*CVAR_SERVERINFO |*/ CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
{ &g_autoMapCycle, "g_autoMapCycle", "1", CVAR_SERVERINFO | CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
{ &g_autoMapCycle, "g_autoMapCycle", "0", CVAR_ARCHIVE | CVAR_NORESTART, 0, qtrue },
{ &g_dmflags, "dmflags", "0", CVAR_SERVERINFO | CVAR_ARCHIVE, 0, qtrue },
{ &g_maxForceRank, "g_maxForceRank", "0", CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH, 0, qfalse },
@ -520,6 +520,10 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) {
if( g_gametype.integer >= GT_TEAM ) {
G_CheckTeamItems();
}
else if ( g_gametype.integer == GT_JEDIMASTER )
{
trap_SetConfigstring ( CS_CLIENT_JEDIMASTER, "-1" );
}
SaveRegisteredItems();
@ -1614,7 +1618,20 @@ void CheckVote( void ) {
if (level.votingGametype)
{
G_RefreshNextMap(level.votingGametypeTo);
if (trap_Cvar_VariableIntegerValue("g_gametype") != level.votingGametypeTo)
{ //If we're voting to a different game type, be sure to refresh all the map stuff
const char *nextMap = G_RefreshNextMap(level.votingGametypeTo, qtrue);
if (nextMap && nextMap[0])
{
trap_SendConsoleCommand( EXEC_APPEND, va("map %s\n", nextMap ) );
}
}
else
{ //otherwise, just leave the map until a restart
G_RefreshNextMap(level.votingGametypeTo, qfalse);
}
level.votingGametype = qfalse;
level.votingGametypeTo = 0;
}

View file

@ -540,6 +540,8 @@ void SP_misc_holocron(gentity_t *ent)
}
}
ent->s.isJediMaster = qtrue;
VectorSet( ent->r.maxs, 8, 8, 8 );
VectorSet( ent->r.mins, -8, -8, -8 );
@ -1360,3 +1362,175 @@ int G_PlayerBecomeATST(gentity_t *ent)
return 1;
}
/*QUAKED fx_runner (0 0 1) (-8 -8 -8) (8 8 8) STARTOFF ONESHOT
STARTOFF - effect starts off, toggles on/off when used
ONESHOT - effect fires only when used
"angles" - 3-float vector, angle the effect should play (unless fxTarget is supplied)
"fxFile" - name of the effect file to play
"fxTarget" - aim the effect toward this object, otherwise defaults to up
"target" - uses its target when the fx gets triggered
"delay" - how often to call the effect, don't over-do this ( default 400 )
note that it has to send an event each time it plays, so don't kill bandwidth or I will cry
"random" - random amount of time to add to delay, ( default 0, 200 = 0ms to 200ms )
*/
#define FX_RUNNER_RESERVED 0x800000
#define FX_ENT_RADIUS 8 //32
//----------------------------------------------------------
void fx_runner_think( gentity_t *ent )
{
// call the effect with the desired position and orientation
G_AddEvent( ent, EV_PLAY_EFFECT_ID, ent->bolt_Head );
ent->nextthink = level.time + ent->delay + random() * ent->random;
if ( ent->target )
{
// let our target know that we have spawned an effect
G_UseTargets( ent, ent );
}
}
//----------------------------------------------------------
void fx_runner_use( gentity_t *self, gentity_t *other, gentity_t *activator )
{
if ( self->spawnflags & 2 ) // ONESHOT
{
// call the effect with the desired position and orientation, as a safety thing,
// make sure we aren't thinking at all.
fx_runner_think( self );
self->nextthink = -1;
if ( self->target )
{
// let our target know that we have spawned an effect
G_UseTargets( self, self );
}
}
else
{
// ensure we are working with the right think function
self->think = fx_runner_think;
// toggle our state
if ( self->nextthink == -1 )
{
// NOTE: we fire the effect immediately on use, the fx_runner_think func will set
// up the nextthink time.
fx_runner_think( self );
}
else
{
// turn off for now
self->nextthink = -1;
}
}
}
//----------------------------------------------------------
void fx_runner_link( gentity_t *ent )
{
vec3_t dir;
if ( ent->roffname && ent->roffname[0] )
{
// try to use the target to override the orientation
gentity_t *target = NULL;
target = G_Find( target, FOFS(targetname), ent->roffname );
if ( !target )
{
// Bah, no good, dump a warning, but continue on and use the UP vector
Com_Printf( "fx_runner_link: target specified but not found: %s\n", ent->roffname );
Com_Printf( " -assuming UP orientation.\n" );
}
else
{
// Our target is valid so let's override the default UP vector
VectorSubtract( target->s.origin, ent->s.origin, dir );
VectorNormalize( dir );
vectoangles( dir, ent->s.angles );
}
}
// don't really do anything with this right now other than do a check to warn the designers if the target is bogus
if ( ent->target )
{
gentity_t *target = NULL;
target = G_Find( target, FOFS(targetname), ent->target );
if ( !target )
{
// Target is bogus, but we can still continue
Com_Printf( "fx_runner_link: target was specified but is not valid: %s\n", ent->target );
}
}
G_SetAngles( ent, ent->s.angles );
if ( ent->spawnflags & 1 || ent->spawnflags & 2 ) // STARTOFF || ONESHOT
{
// We won't even consider thinking until we are used
ent->nextthink = -1;
}
else
{
// Let's get to work right now!
ent->think = fx_runner_think;
ent->nextthink = level.time + 100; // wait a small bit, then start working
}
}
//----------------------------------------------------------
void SP_fx_runner( gentity_t *ent )
{
char *fxFile;
// Get our defaults
G_SpawnInt( "delay", "400", &ent->delay );
G_SpawnFloat( "random", "0", &ent->random );
if (!ent->s.angles[0] && !ent->s.angles[1] && !ent->s.angles[2])
{
// didn't have angles, so give us the default of up
VectorSet( ent->s.angles, -90, 0, 0 );
}
// make us useable if we can be targeted
if ( ent->targetname )
{
ent->use = fx_runner_use;
}
G_SpawnString( "fxFile", "", &fxFile );
G_SpawnString( "fxTarget", "", &ent->roffname );
if ( !fxFile || !fxFile[0] )
{
Com_Printf( S_COLOR_RED"ERROR: fx_runner %s at %s has no fxFile specified\n", ent->targetname, vtos(ent->s.origin) );
G_FreeEntity( ent );
return;
}
// Try and associate an effect file, unfortunately we won't know if this worked or not
// until the CGAME trys to register it...
ent->bolt_Head = G_EffectIndex( fxFile );
//It is dirty, yes. But no one likes adding things to the entity structure.
// Give us a bit of time to spawn in the other entities, since we may have to target one of 'em
ent->think = fx_runner_link;
ent->nextthink = level.time + 300;
// Save our position and link us up!
G_SetOrigin( ent, ent->s.origin );
VectorSet( ent->r.maxs, FX_ENT_RADIUS, FX_ENT_RADIUS, FX_ENT_RADIUS );
VectorScale( ent->r.maxs, -1, ent->r.mins );
trap_LinkEntity( ent );
}

View file

@ -350,6 +350,25 @@ void G_MissileImpact( gentity_t *ent, trace_t *trace ) {
}
*/
if (other->r.contents & CONTENTS_LIGHTSABER)
{ //hit this person's saber, so..
gentity_t *otherOwner = &g_entities[other->r.ownerNum];
if (otherOwner->takedamage && otherOwner->client && otherOwner->client->ps.duelInProgress &&
otherOwner->client->ps.duelIndex != ent->r.ownerNum)
{
goto killProj;
}
}
else
{
if (other->takedamage && other->client && other->client->ps.duelInProgress &&
other->client->ps.duelIndex != ent->r.ownerNum)
{
goto killProj;
}
}
if (other->takedamage && other->client &&
ent->s.weapon != WP_ROCKET_LAUNCHER &&
ent->s.weapon != WP_THERMAL &&

View file

@ -728,7 +728,14 @@ void Blocked_Door( gentity_t *ent, gentity_t *other ) {
}
if ( ent->damage ) {
G_Damage( other, ent, ent, NULL, NULL, ent->damage, DAMAGE_NO_ARMOR, MOD_CRUSH );
if (ent->activator && ent->activator->inuse && ent->activator->client)
{
G_Damage( other, ent->activator, ent->activator, NULL, NULL, ent->damage, DAMAGE_NO_ARMOR, MOD_CRUSH );
}
else
{
G_Damage( other, ent, ent, NULL, NULL, ent->damage, DAMAGE_NO_ARMOR, MOD_CRUSH );
}
}
if ( ent->spawnflags & 4 ) {
return; // crushers don't reverse

View file

@ -173,6 +173,8 @@ void SP_misc_model_shield_power_converter( gentity_t *ent );
void SP_misc_model_ammo_power_converter( gentity_t *ent );
void SP_misc_model_health_power_converter( gentity_t *ent );
void SP_fx_runner( gentity_t *ent );
void SP_misc_holocron(gentity_t *ent);
void SP_shooter_blaster( gentity_t *ent );
@ -259,6 +261,8 @@ spawn_t spawns[] = {
{"misc_model_ammo_power_converter", SP_misc_model_ammo_power_converter},
{"misc_model_health_power_converter", SP_misc_model_health_power_converter},
{"fx_runner", SP_fx_runner},
{"misc_holocron", SP_misc_holocron},
{"shooter_blaster", SP_shooter_blaster},
@ -721,6 +725,7 @@ static char *defaultStyles[32][3] =
}
};
void *precachedKyle = 0;
/*QUAKED worldspawn (0 0 0) ?
@ -740,6 +745,31 @@ void SP_worldspawn( void )
G_Error( "SP_worldspawn: The first entity isn't 'worldspawn'" );
}
//The server will precache the standard model and animations, so that there is no hit
//when the first client connnects.
if (!BGPAFtextLoaded)
{
BG_ParseAnimationFile("models/players/_humanoid/animation.cfg");
}
if (!precachedKyle)
{
trap_G2API_InitGhoul2Model(&precachedKyle, "models/players/kyle/model.glm", 0, 0, -20, 0, 0);
}
if (!g2SaberInstance)
{
trap_G2API_InitGhoul2Model(&g2SaberInstance, "models/weapons2/saber/saber_w.glm", 0, 0, -20, 0, 0);
if (g2SaberInstance)
{
// indicate we will be bolted to model 0 (ie the player) on bolt 0 (always the right hand) when we get copied
trap_G2API_SetBoltInfo(g2SaberInstance, 0, 0);
// now set up the gun bolt on it
trap_G2API_AddBolt(g2SaberInstance, 0, "*flash");
}
}
// make some data visible to connecting client
trap_SetConfigstring( CS_GAME_VERSION, GAME_VERSION );

View file

@ -408,6 +408,15 @@ If dmg is set to -1 this brush will use the fade-kill method
*/
void hurt_use( gentity_t *self, gentity_t *other, gentity_t *activator ) {
if (activator && activator->inuse && activator->client)
{
self->activator = activator;
}
else
{
self->activator = NULL;
}
if ( self->r.linked ) {
trap_UnlinkEntity( self );
} else {
@ -468,7 +477,14 @@ void hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace ) {
}
else
{
G_Damage (other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT);
if (self->activator && self->activator->inuse && self->activator->client)
{
G_Damage (other, self->activator, self->activator, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT);
}
else
{
G_Damage (other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT);
}
}
}

View file

@ -111,6 +111,11 @@ int G_SoundIndex( char *name ) {
return G_FindConfigstringIndex (name, CS_SOUNDS, MAX_SOUNDS, qtrue);
}
int G_EffectIndex( char *name )
{
return G_FindConfigstringIndex (name, CS_EFFECTS, MAX_FX, qtrue);
}
//=====================================================================
@ -807,7 +812,7 @@ void G_MuteSound( int entnum, int channel )
te = G_TempEntity( vec3_origin, EV_MUTE_SOUND );
te->r.svFlags = SVF_BROADCAST;
te->s.eventParm = entnum;
te->s.trickedentindex2 = entnum;
te->s.trickedentindex = channel;
e = &g_entities[entnum];

View file

@ -432,6 +432,15 @@ static void WP_DisruptorMainFire( gentity_t *ent )
traceEnt = &g_entities[tr.entityNum];
if (traceEnt && traceEnt->client && traceEnt->client->ps.duelInProgress &&
traceEnt->client->ps.duelIndex != ent->s.number)
{
VectorCopy( tr.endpos, start );
ignore = tr.entityNum;
traces++;
continue;
}
if ( Jedi_DodgeEvasion( traceEnt, ent, &tr, G_GetHitLocation(traceEnt, tr.endpos) ) )
{//act like we didn't even hit him
VectorCopy( tr.endpos, start );
@ -447,6 +456,7 @@ static void WP_DisruptorMainFire( gentity_t *ent )
tent = G_TempEntity( tr.endpos, EV_DISRUPTOR_MAIN_SHOT );
VectorCopy( muzzle, tent->s.origin2 );
tent->s.eventParm = ent->s.number;
te = G_TempEntity( tr.endpos, EV_SABER_BLOCK );
VectorCopy(tr.endpos, te->s.origin);
@ -472,6 +482,7 @@ static void WP_DisruptorMainFire( gentity_t *ent )
// always render a shot beam, doing this the old way because I don't much feel like overriding the effect.
tent = G_TempEntity( tr.endpos, EV_DISRUPTOR_MAIN_SHOT );
VectorCopy( muzzle, tent->s.origin2 );
tent->s.eventParm = ent->s.number;
traceEnt = &g_entities[tr.entityNum];
@ -582,6 +593,14 @@ void WP_DisruptorAltFire( gentity_t *ent )
traceEnt = &g_entities[tr.entityNum];
if (traceEnt && traceEnt->client && traceEnt->client->ps.duelInProgress &&
traceEnt->client->ps.duelIndex != ent->s.number)
{
skip = tr.entityNum;
VectorCopy(tr.endpos, start);
continue;
}
if (Jedi_DodgeEvasion(traceEnt, ent, &tr, G_GetHitLocation(traceEnt, tr.endpos)))
{
skip = tr.entityNum;
@ -597,6 +616,7 @@ void WP_DisruptorAltFire( gentity_t *ent )
tent = G_TempEntity( tr.endpos, EV_DISRUPTOR_SNIPER_SHOT );
VectorCopy( muzzle, tent->s.origin2 );
tent->s.shouldtarget = fullCharge;
tent->s.eventParm = ent->s.number;
te = G_TempEntity( tr.endpos, EV_SABER_BLOCK );
VectorCopy(tr.endpos, te->s.origin);
@ -615,6 +635,7 @@ void WP_DisruptorAltFire( gentity_t *ent )
tent = G_TempEntity( tr.endpos, EV_DISRUPTOR_SNIPER_SHOT );
VectorCopy( muzzle, tent->s.origin2 );
tent->s.shouldtarget = fullCharge;
tent->s.eventParm = ent->s.number;
// If the beam hits a skybox, etc. it would look foolish to add impact effects
if ( render_impact )
@ -1627,6 +1648,8 @@ THERMAL DETONATOR
#define TD_ALT_MIN_CHARGE 0.15f
#define TD_ALT_TIME 3000
void thermalThinkStandard(gentity_t *ent);
//---------------------------------------------------------
void thermalDetonatorExplode( gentity_t *ent )
//---------------------------------------------------------
@ -1635,7 +1658,9 @@ void thermalDetonatorExplode( gentity_t *ent )
{
G_Sound( ent, CHAN_VOICE, G_SoundIndex( "sound/weapons/thermal/warning.wav" ) );
ent->count = 1;
ent->nextthink = level.time + 500;
ent->bolt_Head = level.time + 500;
ent->think = thermalThinkStandard;
ent->nextthink = level.time;
ent->r.svFlags |= SVF_BROADCAST;//so everyone hears/sees the explosion?
}
else
@ -1663,6 +1688,18 @@ void thermalDetonatorExplode( gentity_t *ent )
}
}
void thermalThinkStandard(gentity_t *ent)
{
if (ent->bolt_Head < level.time)
{
ent->think = thermalDetonatorExplode;
ent->nextthink = level.time;
return;
}
G_RunObject(ent);
ent->nextthink = level.time;
}
//---------------------------------------------------------
gentity_t *WP_FireThermalDetonator( gentity_t *ent, qboolean altFire )
@ -1677,8 +1714,12 @@ gentity_t *WP_FireThermalDetonator( gentity_t *ent, qboolean altFire )
bolt = G_Spawn();
bolt->physicsObject = qtrue;
bolt->classname = "thermal_detonator";
bolt->think = thermalDetonatorExplode;
bolt->think = thermalThinkStandard;
bolt->nextthink = level.time;
bolt->touch = touch_NULL;
// bolt->mass = 10; // NOTENOTE No mass implementation yet
// How 'bout we give this thing a size...
@ -1706,7 +1747,7 @@ gentity_t *WP_FireThermalDetonator( gentity_t *ent, qboolean altFire )
}
// normal ones bounce, alt ones explode on impact
bolt->nextthink = level.time + TD_TIME; // How long 'til she blows
bolt->bolt_Head = level.time + TD_TIME; // How long 'til she blows
bolt->s.pos.trType = TR_GRAVITY;
bolt->parent = ent;
bolt->r.ownerNum = ent->s.number;
@ -2141,6 +2182,9 @@ void charge_stick (gentity_t *self, gentity_t *other, trace_t *trace)
self->s.pos.trDelta[0] += vNor[0]*(tN[0]*(((float)Q_irand(1, 10))*0.1));
self->s.pos.trDelta[1] += vNor[1]*(tN[1]*(((float)Q_irand(1, 10))*0.1));
self->s.pos.trDelta[2] += vNor[1]*(tN[2]*(((float)Q_irand(1, 10))*0.1));
vectoangles(vNor, self->s.angles);
vectoangles(vNor, self->s.apos.trBase);
self->touch = charge_stick;
return;
}
@ -2272,6 +2316,8 @@ void drop_charge (gentity_t *self, vec3_t start, vec3_t dir)
bolt->r.contents = MASK_SHOT;
bolt->touch = charge_stick;
bolt->physicsObject = qtrue;
bolt->s.genericenemyindex = self->s.number+1024;
//rww - so client prediction knows we own this and won't hit it
@ -2463,6 +2509,21 @@ void WP_FireStunBaton( gentity_t *ent, qboolean alt_fire )
tr_ent = &g_entities[tr.entityNum];
if (tr_ent && tr_ent->takedamage && tr_ent->client)
{
if (tr_ent->client->ps.duelInProgress &&
tr_ent->client->ps.duelIndex != ent->s.number)
{
return;
}
if (ent->client->ps.duelInProgress &&
ent->client->ps.duelIndex != tr_ent->s.number)
{
return;
}
}
if ( tr_ent && tr_ent->takedamage )
{
G_PlayEffect( EFFECT_STUNHIT, tr.endpos, tr.plane.normal );

View file

@ -1,99 +0,0 @@
del /q vm
mkdir vm
cd vm
set cc=lcc -A -DQ3_VM -DMISSIONPACK -S -Wf-target=bytecode -Wf-g -I..\..\cgame -I..\..\game -I..\..\ui %1
%cc% ../g_main.c
@if errorlevel 1 goto quit
%cc% ../g_syscalls.c
@if errorlevel 1 goto quit
%cc% ../bg_misc.c
@if errorlevel 1 goto quit
%cc% ../bg_lib.c
@if errorlevel 1 goto quit
%cc% ../bg_pmove.c
@if errorlevel 1 goto quit
%cc% ../bg_saber.c
@if errorlevel 1 goto quit
%cc% ../bg_slidemove.c
@if errorlevel 1 goto quit
%cc% ../bg_panimate.c
@if errorlevel 1 goto quit
%cc% ../bg_weapons.c
@if errorlevel 1 goto quit
%cc% ../q_math.c
@if errorlevel 1 goto quit
%cc% ../q_shared.c
@if errorlevel 1 goto quit
%cc% ../ai_main.c
@if errorlevel 1 goto quit
%cc% ../ai_util.c
@if errorlevel 1 goto quit
%cc% ../ai_wpnav.c
@if errorlevel 1 goto quit
%cc% ../g_active.c
@if errorlevel 1 goto quit
%cc% ../g_arenas.c
@if errorlevel 1 goto quit
%cc% ../g_bot.c
@if errorlevel 1 goto quit
%cc% ../g_client.c
@if errorlevel 1 goto quit
%cc% ../g_cmds.c
@if errorlevel 1 goto quit
%cc% ../g_combat.c
@if errorlevel 1 goto quit
%cc% ../g_items.c
@if errorlevel 1 goto quit
%cc% ../g_log.c
@if errorlevel 1 goto quit
%cc% ../g_mem.c
@if errorlevel 1 goto quit
%cc% ../g_misc.c
@if errorlevel 1 goto quit
%cc% ../g_missile.c
@if errorlevel 1 goto quit
%cc% ../g_mover.c
@if errorlevel 1 goto quit
%cc% ../g_object.c
@if errorlevel 1 goto quit
%cc% ../g_saga.c
@if errorlevel 1 goto quit
%cc% ../g_session.c
@if errorlevel 1 goto quit
%cc% ../g_spawn.c
@if errorlevel 1 goto quit
%cc% ../g_svcmds.c
@if errorlevel 1 goto quit
%cc% ../g_target.c
@if errorlevel 1 goto quit
%cc% ../g_team.c
@if errorlevel 1 goto quit
%cc% ../g_trigger.c
@if errorlevel 1 goto quit
%cc% ../g_utils.c
@if errorlevel 1 goto quit
%cc% ../g_weapon.c
@if errorlevel 1 goto quit
%cc% ../w_force.c
@if errorlevel 1 goto quit
%cc% ../w_saber.c
@if errorlevel 1 goto quit
sysmaker ../g_public.h ../g_syscalls.c ../g_syscalls.asm
@if errorlevel 1 goto quit
q3asm -f ../game
@if errorlevel 1 goto quit
mkdir "..\..\base\vm"
copy *.map "..\..\base\vm"
copy *.qvm "..\..\base\vm"
:quit
cd ..

View file

@ -1,40 +0,0 @@
-o "jk2mpgame"
g_main
ai_main
ai_util
ai_wpnav
bg_lib
bg_misc
bg_pmove
bg_panimate
bg_slidemove
bg_weapons
bg_saber
g_active
g_arenas
g_bot
g_client
g_cmds
g_combat
g_items
g_log
g_mem
g_misc
g_missile
g_mover
g_object
g_saga
g_session
g_spawn
g_svcmds
..\g_syscalls
g_target
g_team
g_trigger
g_utils
g_weapon
w_force
w_saber
q_math
q_shared

View file

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

View file

@ -6,7 +6,7 @@
// q_shared.h -- included first by ALL program modules.
// A user mod should never modify this file
#define Q3_VERSION "JK2MP: v0.55"
#define Q3_VERSION "JK2MP: v0.56"
#define MAX_TEAMNAME 32
@ -1397,6 +1397,7 @@ typedef struct forcedata_s {
qboolean sentryDeployed;
int saberAnimLevel;
int saberDrawAnimLevel;
int suicides;
@ -1680,6 +1681,29 @@ typedef struct playerState_s {
#define MOVE_RUN 120 // if forwardmove or rightmove are >= MOVE_RUN,
// then BUTTON_WALKING should be set
typedef enum
{
GENCMD_SABERSWITCH = 1,
GENCMD_ENGAGE_DUEL,
GENCMD_FORCE_HEAL,
GENCMD_FORCE_SPEED,
GENCMD_FORCE_THROW,
GENCMD_FORCE_PULL,
GENCMD_FORCE_DISTRACT,
GENCMD_FORCE_RAGE,
GENCMD_FORCE_PROTECT,
GENCMD_FORCE_ABSORB,
GENCMD_FORCE_HEALOTHER,
GENCMD_FORCE_FORCEPOWEROTHER,
GENCMD_FORCE_SEEING,
GENCMD_USE_SEEKER,
GENCMD_USE_FIELD,
GENCMD_USE_BACTA,
GENCMD_USE_ELECTROBINOCULARS,
GENCMD_ZOOM,
GENCMD_USE_SENTRY,
GENCMD_SABERATTACKCYCLE
} genCmds_t;
// usercmd_t is sent to the server each client frame
typedef struct usercmd_s {
@ -1689,6 +1713,7 @@ typedef struct usercmd_s {
byte weapon; // weapon
byte forcesel;
byte invensel;
byte generic_cmd;
signed char forwardmove, rightmove, upmove;
} usercmd_t;
@ -2039,4 +2064,13 @@ typedef enum
} ForceReload_e;
enum {
FONT_NONE,
FONT_SMALL=1,
FONT_MEDIUM,
FONT_LARGE
};
#endif // __Q_SHARED_H

Binary file not shown.

View file

@ -441,9 +441,12 @@ validitycheck:
{
if (ent->client->ps.fd.forcePowersKnown & (1 << i))
{
ent->client->ps.fd.forcePowersKnown &= ~(1 << i);
ent->client->ps.fd.forcePowerLevel[i] = 0;
warnClientLimit = qtrue;
if (i != FP_SABERATTACK && i != FP_LEVITATION && i != FP_SABERDEFEND)
{
ent->client->ps.fd.forcePowersKnown &= ~(1 << i);
ent->client->ps.fd.forcePowerLevel[i] = 0;
warnClientLimit = qtrue;
}
}
}
i++;
@ -499,12 +502,15 @@ validitycheck:
if (!(ent->r.svFlags & SVF_BOT) && g_gametype.integer != GT_TOURNAMENT)
{
//Make them a spectator so they can set their powerups up without being bothered.
ent->client->sess.sessionTeam = TEAM_SPECTATOR;
ent->client->sess.spectatorState = SPECTATOR_FREE;
ent->client->sess.spectatorClient = 0;
if (g_gametype.integer < GT_TEAM || !g_teamAutoJoin.integer)
{
//Make them a spectator so they can set their powerups up without being bothered.
ent->client->sess.sessionTeam = TEAM_SPECTATOR;
ent->client->sess.spectatorState = SPECTATOR_FREE;
ent->client->sess.spectatorClient = 0;
ent->client->pers.teamState.state = TEAM_BEGIN;
ent->client->pers.teamState.state = TEAM_BEGIN;
}
}
}
ent->client->sess.setForce = qtrue;
@ -848,75 +854,6 @@ void WP_ForcePowerRegenerate( gentity_t *self, int overrideAmt )
}
}
void WP_ForcePowerDrain( gentity_t *self, forcePowers_t forcePower, int overrideAmt )
{
//take away the power
int drain = overrideAmt;
if (self->client->ps.powerups[PW_FORCE_BOON])
{
return;
}
if ( !drain )
{
drain = forcePowerNeeded[self->client->ps.fd.forcePowerLevel[forcePower]][forcePower];
}
if ( !drain )
{
return;
}
if (forcePower == FP_LEVITATION)
{ //special case
int jumpDrain = 0;
if (self->client->ps.velocity[2] > 250)
{
jumpDrain = 20;
}
else if (self->client->ps.velocity[2] > 200)
{
jumpDrain = 16;
}
else if (self->client->ps.velocity[2] > 150)
{
jumpDrain = 12;
}
else if (self->client->ps.velocity[2] > 100)
{
jumpDrain = 8;
}
else if (self->client->ps.velocity[2] > 50)
{
jumpDrain = 6;
}
else if (self->client->ps.velocity[2] > 0)
{
jumpDrain = 4;
}
if (jumpDrain)
{
jumpDrain /= self->client->ps.fd.forcePowerLevel[FP_LEVITATION];
}
self->client->ps.fd.forcePower -= jumpDrain;
if ( self->client->ps.fd.forcePower < 0 )
{
self->client->ps.fd.forcePower = 0;
}
return;
}
self->client->ps.fd.forcePower -= drain;
if ( self->client->ps.fd.forcePower < 0 )
{
self->client->ps.fd.forcePower = 0;
}
}
void WP_ForcePowerStart( gentity_t *self, forcePowers_t forcePower, int overrideAmt )
{
int duration = 0;
@ -1021,15 +958,15 @@ void WP_ForcePowerStart( gentity_t *self, forcePowers_t forcePower, int override
hearDist = 256;
if (self->client->ps.fd.forcePowerLevel[FP_RAGE] == FORCE_LEVEL_1)
{
duration = 10000;
duration = 8000;
}
else if (self->client->ps.fd.forcePowerLevel[FP_RAGE] == FORCE_LEVEL_2)
{
duration = 16000;
duration = 14000;
}
else if (self->client->ps.fd.forcePowerLevel[FP_RAGE] == FORCE_LEVEL_3)
{
duration = 23000;
duration = 20000;
}
else //shouldn't get here
{
@ -1118,11 +1055,11 @@ void WP_ForcePowerStart( gentity_t *self, forcePowers_t forcePower, int override
if ((int)forcePower == FP_SPEED && overrideAmt)
{
WP_ForcePowerDrain( self, forcePower, overrideAmt*0.025 );
BG_ForcePowerDrain( &self->client->ps, forcePower, overrideAmt*0.025 );
}
else if ((int)forcePower != FP_GRIP && (int)forcePower != FP_DRAIN)
{ //grip and drain drain as damage is done
WP_ForcePowerDrain( self, forcePower, overrideAmt );
BG_ForcePowerDrain( &self->client->ps, forcePower, overrideAmt );
}
}
@ -1157,12 +1094,36 @@ void ForceHeal( gentity_t *self )
{
self->health = self->client->ps.stats[STAT_MAX_HEALTH];
}
WP_ForcePowerDrain( self, FP_HEAL, 0 );
BG_ForcePowerDrain( &self->client->ps, FP_HEAL, 0 );
}
else if (self->client->ps.fd.forcePowerLevel[FP_HEAL] == FORCE_LEVEL_2)
{
self->health += 25;
if (self->health > self->client->ps.stats[STAT_MAX_HEALTH])
{
self->health = self->client->ps.stats[STAT_MAX_HEALTH];
}
BG_ForcePowerDrain( &self->client->ps, FP_HEAL, 0 );
}
else
{
self->health += 10;
if (self->health > self->client->ps.stats[STAT_MAX_HEALTH])
{
self->health = self->client->ps.stats[STAT_MAX_HEALTH];
}
BG_ForcePowerDrain( &self->client->ps, FP_HEAL, 0 );
}
/*
else
{
WP_ForcePowerStart( self, FP_HEAL, 0 );
}
*/
//NOTE: Decided to make all levels instant.
G_Sound( self, CHAN_ITEM, G_SoundIndex("sound/weapons/force/heal.wav") );
// No character heal voices
// G_Sound( self, CHAN_VOICE, G_SoundIndex(va( "sound/weapons/force/heal%d.mp3", Q_irand( 1, 4 ) )) );
@ -1233,7 +1194,7 @@ void ForceTeamHeal( gentity_t *self )
healthadd = 25;
}
WP_ForcePowerDrain( self, FP_TEAM_HEAL, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_TEAM_HEAL]][FP_TEAM_HEAL] );
BG_ForcePowerDrain( &self->client->ps, FP_TEAM_HEAL, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_TEAM_HEAL]][FP_TEAM_HEAL] );
i = 0;
@ -1321,7 +1282,7 @@ void ForceTeamForceReplenish( gentity_t *self )
poweradd = 25;
}
WP_ForcePowerDrain( self, FP_TEAM_FORCE, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_TEAM_FORCE]][FP_TEAM_FORCE] );
BG_ForcePowerDrain( &self->client->ps, FP_TEAM_FORCE, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_TEAM_FORCE]][FP_TEAM_FORCE] );
i = 0;
@ -1911,11 +1872,11 @@ void ForceDrainDamage( gentity_t *self, gentity_t *traceEnt, vec3_t dir, vec3_t
/*
if (self->client->ps.fd.forcePowerLevel[FP_DRAIN] == FORCE_LEVEL_1)
{
WP_ForcePowerDrain( self, FP_DRAIN, 0 );
BG_ForcePowerDrain( &self->client->ps, FP_DRAIN, 0 );
}
else
{
WP_ForcePowerDrain( self, FP_DRAIN, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_DRAIN]][FP_DRAIN]/5 );
BG_ForcePowerDrain( &self->client->ps, FP_DRAIN, forcePowerNeeded[self->client->ps.fd.forcePowerLevel[FP_DRAIN]][FP_DRAIN]/5 );
}
if (self->client->ps.fd.forcePowerLevel[FP_DRAIN] == FORCE_LEVEL_1)
@ -2077,11 +2038,11 @@ int ForceShootDrain( gentity_t *self )
/* if (self->client->ps.fd.forcePowerLevel[FP_DRAIN] == FORCE_LEVEL_1)
{
WP_ForcePowerDrain( self, FP_DRAIN, 0 );
BG_ForcePowerDrain( &self->client->ps, FP_DRAIN, 0 );
}
else*/
{
WP_ForcePowerDrain( self, FP_DRAIN, 1 );
BG_ForcePowerDrain( &self->client->ps, FP_DRAIN, 1 );
}
self->client->ps.fd.forcePowerRegenDebounceTime = level.time + 500;
@ -3720,7 +3681,7 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd
self->client->ps.fd.forceHealTime = level.time + 1000;
self->health++;
self->client->ps.fd.forceHealAmount++;
//WP_ForcePowerDrain( self, forcePower, 0 );
//BG_ForcePowerDrain( &self->client->ps, forcePower, 0 );
if ( self->health > self->client->ps.stats[STAT_MAX_HEALTH]) // Past max health
{
self->health = self->client->ps.stats[STAT_MAX_HEALTH];
@ -3751,9 +3712,10 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd
}
else
{
/*
if (self->client->ps.fd.forcePowerDebounce[FP_LEVITATION] < level.time)
{
WP_ForcePowerDrain( self, forcePower, 5 );
BG_ForcePowerDrain( &self->client->ps, forcePower, 5 );
if (self->client->ps.fd.forcePowerLevel[FP_LEVITATION] >= FORCE_LEVEL_2)
{
self->client->ps.fd.forcePowerDebounce[FP_LEVITATION] = level.time + 300;
@ -3763,6 +3725,8 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd
self->client->ps.fd.forcePowerDebounce[FP_LEVITATION] = level.time + 200;
}
}
*/
//NOTE: Now handled in bg code for prediction
}
break;
case FP_RAGE:
@ -3779,15 +3743,15 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd
if (self->client->ps.fd.forcePowerLevel[FP_RAGE] == FORCE_LEVEL_1)
{
addTime = 100;
addTime = 150;
}
else if (self->client->ps.fd.forcePowerLevel[FP_RAGE] == FORCE_LEVEL_2)
{
addTime = 250;
addTime = 300;
}
else if (self->client->ps.fd.forcePowerLevel[FP_RAGE] == FORCE_LEVEL_3)
{
addTime = 400;
addTime = 450;
}
self->client->ps.forceRageDrainTime = level.time + addTime;
}
@ -3847,7 +3811,7 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd
else
{
ForceShootLightning( self );
WP_ForcePowerDrain( self, forcePower, 0 );
BG_ForcePowerDrain( &self->client->ps, forcePower, 0 );
}
break;
case FP_TELEPATHY:
@ -3863,7 +3827,7 @@ static void WP_ForcePowerRun( gentity_t *self, forcePowers_t forcePower, usercmd
case FP_ABSORB:
if (self->client->ps.fd.forcePowerDebounce[forcePower] < level.time)
{
WP_ForcePowerDrain( self, forcePower, 1 );
BG_ForcePowerDrain( &self->client->ps, forcePower, 1 );
if (self->client->ps.fd.forcePower < 1)
{
WP_ForcePowerStop(self, forcePower);
@ -3933,7 +3897,7 @@ int WP_DoSpecificPower( gentity_t *self, usercmd_t *ucmd, forcePowers_t forcepow
if (!(self->client->ps.fd.forcePowersActive & (1 << FP_GRIP)))
{
WP_ForcePowerStart( self, FP_GRIP, 0 );
WP_ForcePowerDrain( self, FP_GRIP, GRIP_DRAIN_AMOUNT );
BG_ForcePowerDrain( &self->client->ps, FP_GRIP, GRIP_DRAIN_AMOUNT );
}
}
else
@ -4548,14 +4512,11 @@ void WP_ForcePowersUpdate( gentity_t *self, usercmd_t *ucmd )
{
self->client->ps.fd.forcePowerBaseLevel[i] = self->client->ps.fd.forcePowerLevel[i];
if (self->client->ps.fd.forcePowerLevel[i] >= FORCE_LEVEL_1 &&
self->client->ps.fd.forcePowerLevel[i] < FORCE_LEVEL_3)
if (!forcePowerDarkLight[i] ||
self->client->ps.fd.forceSide == forcePowerDarkLight[i])
{
if (!forcePowerDarkLight[i] ||
self->client->ps.fd.forceSide == forcePowerDarkLight[i])
{
self->client->ps.fd.forcePowerLevel[i]++;
}
self->client->ps.fd.forcePowerLevel[i] = FORCE_LEVEL_3;
self->client->ps.fd.forcePowersKnown |= (1 << i);
}
i++;
@ -4571,6 +4532,14 @@ void WP_ForcePowersUpdate( gentity_t *self, usercmd_t *ucmd )
while (i < NUM_FORCE_POWERS)
{
self->client->ps.fd.forcePowerLevel[i] = self->client->ps.fd.forcePowerBaseLevel[i];
if (!self->client->ps.fd.forcePowerLevel[i])
{
if (self->client->ps.fd.forcePowersActive & (1 << i))
{
WP_ForcePowerStop(self, i);
}
self->client->ps.fd.forcePowersKnown &= ~(1 << i);
}
i++;
}

View file

@ -5,7 +5,6 @@
#include "..\ghoul2\g2.h"
extern bot_state_t *botstates[MAX_CLIENTS];
extern void *g2SaberInstance;
extern qboolean InFront( vec3_t spot, vec3_t from, vec3_t fromAngles, float threshHold );
int saberSpinSound = 0;
@ -110,7 +109,7 @@ void WP_SaberInitBladeData( gentity_t *ent )
saberSpinSound = G_SoundIndex("sound/weapons/saber/saberspin.wav");
saberOffSound = G_SoundIndex("sound/weapons/saber/saberoffquick.wav");
saberOnSound = G_SoundIndex("sound/weapons/saber/saberon.wav");
saberHumSound = G_SoundIndex("sound/weapons/saber/saberhum.wav");
saberHumSound = G_SoundIndex("sound/weapons/saber/saberhum1.wav");
}
static void G_SwingAngles( float destination, float swingTolerance, float clampTolerance,
@ -546,7 +545,7 @@ qboolean WP_SabersCheckLock2( gentity_t *attacker, gentity_t *defender, sabersLo
memset (&pmv, 0, sizeof(pmv));
pmv.ps = &attacker->client->ps;
pmv.animations = attacker->client->animations;
pmv.animations = bgGlobalAnimations;
pmv.cmd = attacker->client->pers.cmd;
pmv.trace = trap_Trace;
pmv.pointcontents = trap_PointContents;
@ -555,15 +554,15 @@ qboolean WP_SabersCheckLock2( gentity_t *attacker, gentity_t *defender, sabersLo
//This is a rare exception, you should never really call PM_ utility functions from game or cgame (despite the fact that it's technically possible)
pm = &pmv;
PM_SetAnim(SETANIM_BOTH, attAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
attacker->client->ps.saberLockFrame = attacker->client->animations[attAnim].firstFrame+(attacker->client->animations[attAnim].numFrames*0.5);
attacker->client->ps.saberLockFrame = bgGlobalAnimations[attAnim].firstFrame+(bgGlobalAnimations[attAnim].numFrames*0.5);
pmv.ps = &defender->client->ps;
pmv.animations = defender->client->animations;
pmv.animations = bgGlobalAnimations;
pmv.cmd = defender->client->pers.cmd;
pm = &pmv;
PM_SetAnim(SETANIM_BOTH, defAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 0);
defender->client->ps.saberLockFrame = defender->client->animations[defAnim].firstFrame+(defender->client->animations[defAnim].numFrames*0.5);
defender->client->ps.saberLockFrame = bgGlobalAnimations[defAnim].firstFrame+(bgGlobalAnimations[defAnim].numFrames*0.5);
attacker->client->ps.saberLockHits = 0;
defender->client->ps.saberLockHits = 0;
@ -1086,7 +1085,7 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q
VectorSubtract(saberEnd, saberStart, dir);
VectorNormalize(dir);
if (tr.fraction != 1 &&
if ((tr.fraction != 1 || tr.startsolid) &&
/*(!g_entities[tr.entityNum].client || !g_entities[tr.entityNum].client->ps.usingATST) &&*/
//g_entities[tr.entityNum].client &&
g_entities[tr.entityNum].takedamage &&
@ -1103,6 +1102,20 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q
return qfalse;
}
if (g_entities[tr.entityNum].inuse && g_entities[tr.entityNum].client &&
g_entities[tr.entityNum].client->ps.duelInProgress &&
g_entities[tr.entityNum].client->ps.duelIndex != self->s.number)
{
return qfalse;
}
if (g_entities[tr.entityNum].inuse && g_entities[tr.entityNum].client &&
self->client->ps.duelInProgress &&
self->client->ps.duelIndex != g_entities[tr.entityNum].s.number)
{
return qfalse;
}
didHit = qtrue;
if (self->client->ps.saberMove == LS_A_BACK ||
@ -1143,7 +1156,7 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q
}
//our attack was blocked, so bounce back?
if (dmg > 5 && (self->client->ps.fd.saberAnimLevel < FORCE_LEVEL_3 || g_entities[tr.entityNum].client->ps.fd.forcePowerLevel[FP_SABERDEFEND] >= FORCE_LEVEL_3))
if (dmg > 5)
{
self->client->ps.weaponTime = 0;
self->client->ps.weaponstate = WEAPON_READY;
@ -1153,6 +1166,15 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q
}
self->client->ps.saberAttackWound = level.time + 300;
if (self->client->ps.fd.saberAnimLevel >= FORCE_LEVEL_3 && dmg > 5 && g_entities[tr.entityNum].client->ps.saberMove != LS_READY && g_entities[tr.entityNum].client->ps.saberMove != LS_NONE)
{
g_entities[tr.entityNum].client->ps.weaponTime = 0;
g_entities[tr.entityNum].client->ps.weaponstate = WEAPON_READY;
g_entities[tr.entityNum].client->ps.saberBlocked = BLOCKED_ATK_BOUNCE;
g_entities[tr.entityNum].client->ps.saberBlockTime = level.time + (350 - (g_entities[tr.entityNum].client->ps.fd.forcePowerLevel[FP_SABERDEFEND]*100));//300;
}
//NOTE: Actual blocking is handled in WP_SaberCanBlock
/*
if (dmg > 5)
@ -1212,7 +1234,7 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q
self->client->ps.saberAttackWound = level.time + 100;
}
}
else if (tr.fraction != 1 &&
else if ((tr.fraction != 1 || tr.startsolid) &&
(g_entities[tr.entityNum].r.contents & CONTENTS_LIGHTSABER) &&
g_entities[tr.entityNum].r.contents != -1)
{ //saber clash
@ -1220,6 +1242,7 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q
gentity_t *otherOwner = &g_entities[g_entities[tr.entityNum].r.ownerNum];
if (otherOwner &&
otherOwner->inuse &&
otherOwner->client &&
OnSameTeam(self, otherOwner) &&
!g_friendlySaber.integer)
@ -1227,6 +1250,20 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q
return qfalse;
}
if (otherOwner && otherOwner->client &&
otherOwner->client->ps.duelInProgress &&
otherOwner->client->ps.duelIndex != self->s.number)
{
return qfalse;
}
if (otherOwner && otherOwner->client &&
self->client->ps.duelInProgress &&
self->client->ps.duelIndex != otherOwner->s.number)
{
return qfalse;
}
didHit = qtrue;
te = G_TempEntity( tr.endpos, EV_SABER_BLOCK );
@ -1242,7 +1279,7 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q
return qfalse;
}
if (self->client->ps.fd.saberAnimLevel < FORCE_LEVEL_3 || otherOwner->client->ps.fd.forcePowerLevel[FP_SABERDEFEND] >= FORCE_LEVEL_3)
if (self->client->ps.fd.saberAnimLevel < FORCE_LEVEL_3)
{
self->client->ps.weaponTime = 0;
self->client->ps.weaponstate = WEAPON_READY;
@ -1261,7 +1298,13 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q
{ //block
if (otherOwner->client->ps.weaponTime < 1 || otherOwner->client->ps.fd.saberAnimLevel < FORCE_LEVEL_3)
{
WP_SaberCanBlock(otherOwner, tr.endpos, 0, MOD_SABER, qfalse, 1);
if (WP_SaberCanBlock(otherOwner, tr.endpos, 0, MOD_SABER, qfalse, 1) && dmg > 5)
{
otherOwner->client->ps.weaponTime = 0;
otherOwner->client->ps.weaponstate = WEAPON_READY;
otherOwner->client->ps.saberBlocked = BLOCKED_ATK_BOUNCE;
otherOwner->client->ps.saberBlockTime = level.time + (350 - (otherOwner->client->ps.fd.forcePowerLevel[FP_SABERDEFEND]*100));//300;
}
}
}
@ -1300,11 +1343,11 @@ qboolean CheckSaberDamage(gentity_t *self, vec3_t saberStart, vec3_t saberEnd, q
return didHit;
}
#define MIN_SABER_SLICE_DISTANCE 80
#define MIN_SABER_SLICE_DISTANCE 60
#define MIN_SABER_SLICE_RETURN_DISTANCE 30
#define SABER_THROWN_HIT_DAMAGE 60
#define SABER_THROWN_HIT_DAMAGE 40
#define SABER_THROWN_RETURN_HIT_DAMAGE 20
void thrownSaberTouch (gentity_t *saberent, gentity_t *other, trace_t *trace);
@ -1316,7 +1359,7 @@ void saberCheckRadiusDamage(gentity_t *saberent, int returning)
gentity_t *ent, *te;
gentity_t *saberOwner = &g_entities[saberent->r.ownerNum];
if (returning)
if (returning && returning != 2)
{
dist = MIN_SABER_SLICE_RETURN_DISTANCE;
}
@ -1346,6 +1389,22 @@ void saberCheckRadiusDamage(gentity_t *saberent, int returning)
vec3_t vecsub;
float veclen;
if (ent->inuse && ent->client &&
ent->client->ps.duelInProgress &&
ent->client->ps.duelIndex != saberOwner->s.number)
{
i++;
continue;
}
if (ent->inuse && ent->client &&
saberOwner->client->ps.duelInProgress &&
saberOwner->client->ps.duelIndex != ent->s.number)
{
i++;
continue;
}
VectorSubtract(saberent->r.currentOrigin, ent->client->ps.origin, vecsub);
veclen = VectorLength(vecsub);
@ -1381,6 +1440,11 @@ void saberCheckRadiusDamage(gentity_t *saberent, int returning)
VectorSubtract(tr.endpos, saberent->r.currentOrigin, dir);
VectorNormalize(dir);
if (!dir[0] && !dir[1] && !dir[2])
{
dir[1] = 1;
}
if (saberOwner->client->ps.isJediMaster)
{ //2x damage for the Jedi Master
G_Damage(ent, saberOwner, saberOwner, dir, tr.endpos, saberent->damage*2, 0, MOD_SABER);
@ -1448,7 +1512,9 @@ void saberCheckRadiusDamage(gentity_t *saberent, int returning)
}
}
void saberMoveBack( gentity_t *ent )
#define THROWN_SABER_COMP
void saberMoveBack( gentity_t *ent, qboolean goingBack )
{
vec3_t origin, oldOrg;
@ -1460,6 +1526,42 @@ void saberMoveBack( gentity_t *ent )
//Get current angles?
BG_EvaluateTrajectory( &ent->s.apos, level.time, ent->r.currentAngles );
//compensation test code..
#ifdef THROWN_SABER_COMP
if (!goingBack)
{ //acts as a fallback in case touch code fails, keeps saber from going through things between predictions
float originalLength = 0;
int iCompensationLength = 32;
trace_t tr;
vec3_t mins, maxs;
vec3_t calcComp, compensatedOrigin;
VectorSet( mins, -24.0f, -24.0f, -8.0f );
VectorSet( maxs, 24.0f, 24.0f, 8.0f );
VectorSubtract(origin, oldOrg, calcComp);
originalLength = VectorLength(calcComp);
VectorNormalize(calcComp);
compensatedOrigin[0] = oldOrg[0] + calcComp[0]*(originalLength+iCompensationLength);
compensatedOrigin[1] = oldOrg[1] + calcComp[1]*(originalLength+iCompensationLength);
compensatedOrigin[2] = oldOrg[2] + calcComp[2]*(originalLength+iCompensationLength);
trap_Trace(&tr, oldOrg, mins, maxs, compensatedOrigin, ent->r.ownerNum, MASK_PLAYERSOLID);
if ((tr.fraction != 1 || tr.startsolid || tr.allsolid) && tr.entityNum != ent->r.ownerNum)
{
VectorClear(ent->s.pos.trDelta);
//Unfortunately doing this would defeat the purpose of the compensation. We will have to settle for a jerk on the client.
//VectorCopy( origin, ent->r.currentOrigin );
thrownSaberTouch(ent, &g_entities[tr.entityNum], &tr);
return;
}
}
#endif
VectorCopy( origin, ent->r.currentOrigin );
}
@ -1549,7 +1651,7 @@ void MakeDeadSaber(gentity_t *ent)
//fall off in the direction the real saber was headed
VectorCopy(ent->s.pos.trDelta, saberent->s.pos.trDelta);
saberMoveBack(saberent);
saberMoveBack(saberent, qtrue);
saberent->s.pos.trType = TR_GRAVITY;
trap_LinkEntity(saberent);
@ -1602,8 +1704,6 @@ void saberBackToOwner(gentity_t *saberent)
return;
}
saberent->s.saberInFlight = qfalse;
saberent->r.contents = CONTENTS_LIGHTSABER;
//saberent->s.apos.trDelta[1] = 0;
@ -1616,7 +1716,7 @@ void saberBackToOwner(gentity_t *saberent)
{
VectorNormalize(dir);
saberMoveBack(saberent);
saberMoveBack(saberent, qtrue);
VectorCopy(saberent->r.currentOrigin, saberent->s.pos.trBase);
if (g_entities[saberent->r.ownerNum].client->ps.fd.forcePowerLevel[FP_SABERTHROW] >= FORCE_LEVEL_3)
@ -1640,6 +1740,12 @@ void saberBackToOwner(gentity_t *saberent)
saberent->s.pos.trTime = level.time;
}
if (ownerLen <= 256)
{
saberent->s.saberInFlight = qfalse;
saberent->s.loopSound = saberHumSound;
}
if (ownerLen <= 32)
{
saberOwner->client->ps.saberInFlight = qfalse;
@ -1654,9 +1760,16 @@ void saberBackToOwner(gentity_t *saberent)
return;
}
saberCheckRadiusDamage(saberent, 1);
if (!saberent->s.saberInFlight)
{
saberCheckRadiusDamage(saberent, 1);
}
else
{
saberCheckRadiusDamage(saberent, 2);
}
saberMoveBack(saberent);
saberMoveBack(saberent, qtrue);
//G_RunObject(saberent);
saberent->nextthink = level.time;
@ -1672,14 +1785,14 @@ void thrownSaberTouch (gentity_t *saberent, gentity_t *other, trace_t *trace)
saberent->s.apos.trDelta[1] = 800;
saberent->s.apos.trDelta[2] = 0;
saberent->s.loopSound = saberHumSound;
VectorCopy(saberent->r.currentOrigin, saberent->s.pos.trBase);
saberent->damage = SABER_THROWN_RETURN_HIT_DAMAGE;
//saberent->damage = SABER_THROWN_RETURN_HIT_DAMAGE;
saberent->think = saberBackToOwner;
saberent->nextthink = level.time;
saberent->speed = 0;
}
#define SABER_MAX_THROW_DISTANCE 700
@ -1796,7 +1909,7 @@ void saberFirstThrown(gentity_t *saberent)
VectorNormalize(dir);
saberMoveBack(saberent);
saberMoveBack(saberent, qfalse);
VectorCopy(saberent->r.currentOrigin, saberent->s.pos.trBase);
VectorScale(dir, 700, saberent->s.pos.trDelta );
@ -1834,6 +1947,18 @@ void WP_SaberPositionUpdate( gentity_t *self, usercmd_t *ucmd )
int returnAfterUpdate = 0;
float animSpeedScale = 1;
if (self && self->inuse && self->client)
{
if (self->client->saberCycleQueue)
{
self->client->ps.fd.saberDrawAnimLevel = self->client->saberCycleQueue;
}
else
{
self->client->ps.fd.saberDrawAnimLevel = self->client->ps.fd.saberAnimLevel;
}
}
if (self &&
self->inuse &&
self->client &&
@ -2130,7 +2255,7 @@ finalUpdate:
if (self->client->ps.legsAnimExecute != legsAnim)
{
trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "model_root", self->client->animations[legsAnim].firstFrame, self->client->animations[legsAnim].firstFrame+self->client->animations[legsAnim].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, -1, 150);
trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "model_root", bgGlobalAnimations[legsAnim].firstFrame, bgGlobalAnimations[legsAnim].firstFrame+bgGlobalAnimations[legsAnim].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, -1, 150);
self->client->ps.legsAnimExecute = legsAnim;
if ((self->client->ps.torsoAnim&~ANIM_TOGGLEBIT) == legsAnim)
@ -2142,7 +2267,7 @@ finalUpdate:
!BG_SaberInSpecial(self->client->ps.saberMove) &&
!BG_SaberInSpecialAttack(self->client->ps.legsAnim) )
{
trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "Motion", self->client->animations[legsAnim].firstFrame, self->client->animations[legsAnim].firstFrame+self->client->animations[legsAnim].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, -1, 150);
trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "Motion", bgGlobalAnimations[legsAnim].firstFrame, bgGlobalAnimations[legsAnim].firstFrame+bgGlobalAnimations[legsAnim].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, -1, 150);
}
}
}
@ -2152,20 +2277,20 @@ finalUpdate:
f = torsoAnim;
initialFrame = self->client->animations[f].firstFrame;
initialFrame = bgGlobalAnimations[f].firstFrame;
if (self->client->animations[f].numFrames > 20)
if (bgGlobalAnimations[f].numFrames > 20)
{
initialFrame += 6;
}
else if (self->client->animations[f].numFrames > 3)
else if (bgGlobalAnimations[f].numFrames > 3)
{ //HACK: Force it a couple frames into the animation so it doesn't lag behind the client visual position as much..
initialFrame += 2;
}
BG_SaberStartTransAnim(self->client->ps.fd.saberAnimLevel, f, &animSpeedScale);
trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "upper_lumbar", initialFrame, self->client->animations[f].firstFrame+self->client->animations[f].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, initialFrame, 150);
trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "upper_lumbar", initialFrame, bgGlobalAnimations[f].firstFrame+bgGlobalAnimations[f].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, initialFrame, 150);
self->client->ps.torsoAnimExecute = torsoAnim;
@ -2178,7 +2303,7 @@ finalUpdate:
!BG_SaberInSpecial(self->client->ps.saberMove) &&
!BG_SaberInSpecialAttack(self->client->ps.torsoAnim) )
{
trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "Motion", self->client->animations[f].firstFrame, self->client->animations[f].firstFrame+self->client->animations[f].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, initialFrame, 150);
trap_G2API_SetBoneAnim(self->client->ghoul2, 0, "Motion", bgGlobalAnimations[f].firstFrame, bgGlobalAnimations[f].firstFrame+bgGlobalAnimations[f].numFrames, BONE_ANIM_OVERRIDE_FREEZE|BONE_ANIM_BLEND, animSpeedScale, level.time, initialFrame, 150);
}
}
}
@ -2497,6 +2622,12 @@ int WP_SaberCanBlock(gentity_t *self, vec3_t point, int dflags, int mod, qboolea
return 0;
}
if (self->client->ps.saberMove != LS_READY &&
!self->client->ps.saberBlocking)
{
return 0;
}
if (self->client->ps.saberBlockTime >= level.time)
{
return 0;

View file

@ -224,16 +224,16 @@ void G2_List_Model_Bones(const char *fileName, int frame)
mdxaSkelOffsets_t *offsets;
model_t *mod_m = R_GetModelByHandle(RE_RegisterModel(fileName));
model_t *mod_a = R_GetModelByHandle(mod_m->mdxm->animIndex);
mdxaFrame_t *aframe=0;
int frameSize;
// mdxaFrame_t *aframe=0;
// int frameSize;
mdxaHeader_t *header = mod_a->mdxa;
// figure out where the offset list is
offsets = (mdxaSkelOffsets_t *)((byte *)header + sizeof(mdxaHeader_t));
frameSize = (int)( &((mdxaFrame_t *)0)->boneIndexes[ header->numBones ] );
// frameSize = (int)( &((mdxaFrame_t *)0)->boneIndexes[ header->numBones ] );
aframe = (mdxaFrame_t *)((byte *)header + header->ofsFrames + (frame * frameSize));
// aframe = (mdxaFrame_t *)((byte *)header + header->ofsFrames + (frame * frameSize));
// walk each bone and list it's name
for (x=0; x< mod_a->mdxa->numBones; x++)
{
@ -329,28 +329,35 @@ void R_TransformEachSurface( mdxmSurface_t *surface, vec3_t scale, CMiniHeap *G2
int *piBoneRefs = (int*) ((byte*)surface + surface->ofsBoneReferences);
numVerts = surface->numVerts;
v = (mdxmVertex_t *) ((byte *)surface + surface->ofsVerts);
mdxmVertexTexCoord_t *pTexCoords = (mdxmVertexTexCoord_t *) &v[numVerts];
// optimisation issue
if ((scale[0] != 1.0) || (scale[1] != 1.0) || (scale[2] != 1.0))
{
for ( j = 0; j < numVerts; j++ )
{
vec3_t tempVert, tempNormal;
mdxmWeight_t *w;
// mdxmWeight_t *w;
VectorClear( tempVert );
VectorClear( tempNormal );
w = v->weights;
for ( k = 0 ; k < v->numWeights ; k++, w++ )
// w = v->weights;
const int iNumWeights = G2_GetVertWeights( v );
for ( k = 0 ; k < iNumWeights ; k++ )
{
int iBoneIndex = G2_GetVertBoneIndex( v, k );
float fBoneWeight = G2_GetVertBoneWeight( v, k );
//bone = bonePtr + piBoneRefs[w->boneIndex];
tempVert[0] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[0][3] );
tempVert[1] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[1][3] );
tempVert[2] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[2][3] );
tempVert[0] += fBoneWeight * ( DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[0], v->vertCoords ) + bonePtr[piBoneRefs[iBoneIndex]].matrix[0][3] );
tempVert[1] += fBoneWeight * ( DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[1], v->vertCoords ) + bonePtr[piBoneRefs[iBoneIndex]].matrix[1][3] );
tempVert[2] += fBoneWeight * ( DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[2], v->vertCoords ) + bonePtr[piBoneRefs[iBoneIndex]].matrix[2][3] );
tempNormal[0] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], v->normal );
tempNormal[1] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], v->normal );
tempNormal[2] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], v->normal );
tempNormal[0] += fBoneWeight * DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[0], v->normal );
tempNormal[1] += fBoneWeight * DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[1], v->normal );
tempNormal[2] += fBoneWeight * DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[2], v->normal );
}
int pos = j * 5;
@ -359,10 +366,10 @@ void R_TransformEachSurface( mdxmSurface_t *surface, vec3_t scale, CMiniHeap *G2
TransformedVerts[pos++] = tempVert[1] * scale[1];
TransformedVerts[pos++] = tempVert[2] * scale[2];
// we will need the S & T coors too for hitlocation and hitmaterial stuff
TransformedVerts[pos++] = v->texCoords[0];
TransformedVerts[pos] = v->texCoords[1];
TransformedVerts[pos++] = pTexCoords[j].texCoords[0];
TransformedVerts[pos] = pTexCoords[j].texCoords[1];
v = (mdxmVertex_t *)&v->weights[/*v->numWeights*/surface->maxVertBoneWeights];
v++;// = (mdxmVertex_t *)&v->weights[/*v->numWeights*/surface->maxVertBoneWeights];
}
}
else
@ -370,22 +377,28 @@ void R_TransformEachSurface( mdxmSurface_t *surface, vec3_t scale, CMiniHeap *G2
for ( j = 0; j < numVerts; j++ )
{
vec3_t tempVert, tempNormal;
mdxmWeight_t *w;
// mdxmWeight_t *w;
VectorClear( tempVert );
VectorClear( tempNormal );
w = v->weights;
for ( k = 0 ; k < v->numWeights ; k++, w++ )
// w = v->weights;
const int iNumWeights = G2_GetVertWeights( v );
for ( k = 0 ; k < iNumWeights ; k++ )
{
int iBoneIndex = G2_GetVertBoneIndex( v, k );
float fBoneWeight = G2_GetVertBoneWeight( v, k );
//bone = bonePtr + piBoneRefs[w->boneIndex];
tempVert[0] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[0][3] );
tempVert[1] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[1][3] );
tempVert[2] += w->boneWeight * ( DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], v->vertCoords ) + bonePtr[piBoneRefs[w->boneIndex]].matrix[2][3] );
tempVert[0] += fBoneWeight * ( DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[0], v->vertCoords ) + bonePtr[piBoneRefs[iBoneIndex]].matrix[0][3] );
tempVert[1] += fBoneWeight * ( DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[1], v->vertCoords ) + bonePtr[piBoneRefs[iBoneIndex]].matrix[1][3] );
tempVert[2] += fBoneWeight * ( DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[2], v->vertCoords ) + bonePtr[piBoneRefs[iBoneIndex]].matrix[2][3] );
tempNormal[0] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[0], v->normal );
tempNormal[1] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[1], v->normal );
tempNormal[2] += w->boneWeight * DotProduct( bonePtr[piBoneRefs[w->boneIndex]].matrix[2], v->normal );
tempNormal[0] += fBoneWeight * DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[0], v->normal );
tempNormal[1] += fBoneWeight * DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[1], v->normal );
tempNormal[2] += fBoneWeight * DotProduct( bonePtr[piBoneRefs[iBoneIndex]].matrix[2], v->normal );
}
int pos = j * 5;
@ -394,10 +407,10 @@ void R_TransformEachSurface( mdxmSurface_t *surface, vec3_t scale, CMiniHeap *G2
TransformedVerts[pos++] = tempVert[1];
TransformedVerts[pos++] = tempVert[2];
// we will need the S & T coors too for hitlocation and hitmaterial stuff
TransformedVerts[pos++] = v->texCoords[0];
TransformedVerts[pos] = v->texCoords[1];
TransformedVerts[pos++] = pTexCoords[j].texCoords[0];
TransformedVerts[pos] = pTexCoords[j].texCoords[1];
v = (mdxmVertex_t *)&v->weights[/*v->numWeights*/surface->maxVertBoneWeights];
v++;// = (mdxmVertex_t *)&v->weights[/*v->numWeights*/surface->maxVertBoneWeights];
}
}
}

Binary file not shown.

View file

@ -1,4 +0,0 @@
xcopy/d/y release\jk2mp.exe w:\game
xcopy/d/y base\vm\cgame.* w:\game\base\vm
xcopy/d/y base\vm\jk2mpgame.* w:\game\base\vm
xcopy/d/y base\vm\ui.* w:\game\base\vm

Binary file not shown.

Binary file not shown.

View file

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

Binary file not shown.

View file

@ -1,2 +0,0 @@
xcopy /d /y release\*.dll w:\game
xcopy /d /y release\jk2mp.exe w:\game\

View file

@ -4,7 +4,9 @@
#include "qcommon.h"
#include "strip.h"
#include <setjmp.h>
#ifndef __linux__
#include <windows.h>
#endif
#define MAXPRINTMSG 4096
@ -215,8 +217,11 @@ void QDECL Com_OPrintf( const char *fmt, ...)
va_start (argptr,fmt);
vsprintf (msg,fmt,argptr);
va_end (argptr);
#ifndef __linux__
OutputDebugString(msg);
#else
printf(msg);
#endif
}
/*
@ -1522,7 +1527,7 @@ void Hunk_Log( void) {
#ifdef HUNK_DEBUG
Com_sprintf(buf, sizeof(buf), "size\t%8d\t%s\tline\t%d\t(%s)\r\n", block->size, block->file, block->line, block->label);
FS_Write(buf, strlen(buf), logfile);
// OutputDebugString(buf);
OutputDebugString(buf);
#endif
size += block->size;
numBlocks++;
@ -2533,6 +2538,9 @@ void Com_Init( char *commandLine ) {
com_introPlayed = Cvar_Get( "com_introplayed", "0", CVAR_ARCHIVE);
Cvar_Get ("com_othertasks", "0", CVAR_ROM );
Cvar_Get ("com_ignoreothertasks", "0", CVAR_ARCHIVE );
#if defined(_WIN32) && defined(_DEBUG)
com_noErrorInterrupt = Cvar_Get( "com_noErrorInterrupt", "0", 0 );
#endif

View file

@ -643,6 +643,8 @@ void MSG_WriteDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to ) {
MSG_WriteDelta( msg, from->forcesel, to->forcesel, 8 );
MSG_WriteDelta( msg, from->invensel, to->invensel, 8 );
MSG_WriteDelta( msg, from->generic_cmd, to->generic_cmd, 8 );
}
@ -668,6 +670,8 @@ void MSG_ReadDeltaUsercmd( msg_t *msg, usercmd_t *from, usercmd_t *to ) {
to->forcesel = MSG_ReadDelta( msg, from->forcesel, 8);
to->invensel = MSG_ReadDelta( msg, from->invensel, 8);
to->generic_cmd = MSG_ReadDelta( msg, from->generic_cmd, 8);
}
/*
@ -692,7 +696,8 @@ void MSG_WriteDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *
from->buttons == to->buttons &&
from->weapon == to->weapon &&
from->forcesel == to->forcesel &&
from->invensel == to->invensel) {
from->invensel == to->invensel &&
from->generic_cmd == to->generic_cmd) {
MSG_WriteBits( msg, 0, 1 ); // no change
oldsize += 7;
return;
@ -710,6 +715,8 @@ void MSG_WriteDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *
MSG_WriteDeltaKey( msg, key, from->forcesel, to->forcesel, 8 );
MSG_WriteDeltaKey( msg, key, from->invensel, to->invensel, 8 );
MSG_WriteDeltaKey( msg, key, from->generic_cmd, to->generic_cmd, 8 );
}
@ -737,6 +744,8 @@ void MSG_ReadDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *t
to->forcesel = MSG_ReadDeltaKey( msg, key, from->forcesel, 8);
to->invensel = MSG_ReadDeltaKey( msg, key, from->invensel, 8);
to->generic_cmd = MSG_ReadDeltaKey( msg, key, from->generic_cmd, 8);
} else {
to->angles[0] = from->angles[0];
to->angles[1] = from->angles[1];
@ -749,6 +758,8 @@ void MSG_ReadDeltaUsercmdKey( msg_t *msg, int key, usercmd_t *from, usercmd_t *t
to->forcesel = from->forcesel;
to->invensel = from->invensel;
to->generic_cmd = from->generic_cmd;
}
}
@ -1204,6 +1215,8 @@ netField_t playerStateFields[] =
{ PSF(fallingToDeath), 32 },
{ PSF(electrifyTime), 32 },
{ PSF(fd.forcePowerDebounce[FP_LEVITATION]), 32 },
{ PSF(saberMove), 32 }, //This value sometimes exceeds the max LS_ value and gets set to a crazy amount, so it needs 32 bits
{ PSF(saberActive), 1 },
{ PSF(saberInFlight), 1 },
@ -1213,6 +1226,7 @@ netField_t playerStateFields[] =
{ PSF(forceHandExtend), 8 },
{ PSF(forceDodgeAnim), 16 },
{ PSF(fd.saberAnimLevel), 4 },
{ PSF(fd.saberDrawAnimLevel), 4 },
{ PSF(saberAttackChainCount), 32 },
{ PSF(saberHolstered), 1 },
{ PSF(usingATST), 1 },

View file

@ -227,6 +227,7 @@ enum svc_ops_e {
svc_serverCommand, // [string] to be executed by client game module
svc_download, // [short] size [size bytes]
svc_snapshot,
svc_mapchange,
svc_EOF
};

View file

@ -154,16 +154,16 @@ sFlagPair FlagPairs[] =
sFlagPair LanguagePairs[] =
{
{ TK_TEXT_LANGUAGE1, TEXT_LANGUAGE1 },
{ TK_TEXT_LANGUAGE2, TEXT_LANGUAGE2 },
{ TK_TEXT_LANGUAGE3, TEXT_LANGUAGE3 },
{ TK_TEXT_LANGUAGE4, TEXT_LANGUAGE4 },
{ TK_TEXT_LANGUAGE5, TEXT_LANGUAGE5 },
{ TK_TEXT_LANGUAGE6, TEXT_LANGUAGE6 },
{ TK_TEXT_LANGUAGE7, TEXT_LANGUAGE7 },
{ TK_TEXT_LANGUAGE8, TEXT_LANGUAGE8 },
{ TK_TEXT_LANGUAGE9, TEXT_LANGUAGE9 },
{ TK_TEXT_LANGUAGE10, TEXT_LANGUAGE10},
{ TK_TEXT_LANGUAGE1, SP_LANGUAGE_ENGLISH },
{ TK_TEXT_LANGUAGE2, SP_LANGUAGE_FRENCH },
{ TK_TEXT_LANGUAGE3, SP_LANGUAGE_GERMAN },
{ TK_TEXT_LANGUAGE4, SP_LANGUAGE_BRITISH },
{ TK_TEXT_LANGUAGE5, SP_LANGUAGE_KOREAN },
{ TK_TEXT_LANGUAGE6, SP_LANGUAGE_TAIWANESE },
{ TK_TEXT_LANGUAGE7, SP_LANGUAGE_ITALIAN },
{ TK_TEXT_LANGUAGE8, SP_LANGUAGE_SPANISH },
{ TK_TEXT_LANGUAGE9, SP_LANGUAGE_JAPANESE },
{ TK_TEXT_LANGUAGE10, SP_LANGUAGE_10},
{ TK_INVALID, 0 }
};
@ -187,14 +187,14 @@ int FindToken(char *token, bool whole)
{
if (whole)
{
if (strcmpi(token, Tokens[token_value]) == 0)
if (Q_stricmp(token, Tokens[token_value]) == 0)
{
return token_value;
}
}
else
{
if (_strnicmp(token, Tokens[token_value], strlen(Tokens[token_value])) == 0)
if (Q_stricmpn(token, Tokens[token_value], strlen(Tokens[token_value])) == 0)
{
i = strlen(Tokens[token_value]);
while(token[i] == ' ')
@ -681,6 +681,7 @@ void cStringsED::SetNotes(char *newNotes)
strcpy(Notes, newNotes);
}
bool cStringsED::UnderstandToken(int token, char *data, cCriteria &Criteria)
{
sFlagPair *LanguagePair;
@ -816,6 +817,64 @@ void cStringsSingle::SetText(const char *newText)
strcpy(Dest, newText);
}
// fix problems caused by fucking morons entering clever "rich" chars in to new text files *after* the auto-stripper
// removed them all in the first place...
//
// ONLY DO THIS FOR ENGLISH, OR IT BREAKS ASIAN STRINGS!!!!!!!!!!!!!!!!!!!!!
//
static void FixIllegalChars(char *psText)
{
char *p;
// strXLS_Speech.Replace(va("%c",0x92),va("%c",0x27)); // "'"
while ((p=strchr(psText,0x92))!=NULL) // "rich" (and illegal) apostrophe
{
*p = 0x27;
}
// strXLS_Speech.Replace(va("%c",0x93),"\""); // smart quotes -> '"'
while ((p=strchr(psText,0x93))!=NULL) // "rich" (and illegal) apostrophe
{
*p = '"';
}
// strXLS_Speech.Replace(va("%c",0x94),"\""); // smart quotes -> '"'
while ((p=strchr(psText,0x94))!=NULL) // "rich" (and illegal) apostrophe
{
*p = '"';
}
// strXLS_Speech.Replace(va("%c",0x0B),"."); // full stop
while ((p=strchr(psText,0x0B))!=NULL) // "rich" (and illegal) apostrophe
{
*p = '.';
}
// strXLS_Speech.Replace(va("%c",0x85),"..."); // "..."-char -> 3-char "..."
while ((p=strchr(psText,0x85))!=NULL) // "rich" (and illegal) apostrophe
{
*p = '.'; // can't do in-string replace of "." with "...", so just forget it
}
// strXLS_Speech.Replace(va("%c",0x91),va("%c",0x27)); // "'"
while ((p=strchr(psText,0x91))!=NULL) // "rich" (and illegal) apostrophe
{
*p = 0x27;
}
// strXLS_Speech.Replace(va("%c",0x96),va("%c",0x2D)); // "-"
while ((p=strchr(psText,0x96))!=NULL)
{
*p = 0x2D;
}
// strXLS_Speech.Replace(va("%c",0x97),va("%c",0x2D)); // "-"
while ((p=strchr(psText,0x97))!=NULL)
{
*p = 0x2D;
}
}
bool cStringsSingle::UnderstandToken(int token, char *data)
{
sFlagPair *LanguagePair;
@ -823,15 +882,24 @@ bool cStringsSingle::UnderstandToken(int token, char *data)
// switch(token)
// {
// default:
for(LanguagePair = LanguagePairs; LanguagePair->Name != TK_INVALID; LanguagePair++)
{
if (LanguagePair->Name == TK_TEXT_LANGUAGE1 && token == TK_TEXT_LANGUAGE1 && !Text)
{ // default to english in case there is no foreign
if (LanguagePair->Name == TK_TEXT_LANGUAGE1)
{
FixIllegalChars(data);
}
SetText(data);
return true;
}
else if (LanguagePair->Name == token && LanguagePair->Value == (int)sp_language->value)
{
if (LanguagePair->Name == TK_TEXT_LANGUAGE1)
{
FixIllegalChars(data);
}
SetText(data);
return true;
}
@ -1412,7 +1480,7 @@ cStringPackageSingle *SP_Register(const char *inPackage, unsigned char Registrat
assert(SP_ListByName.size() == SP_ListByID.size());
Q_strncpyz(Package, inPackage, MAX_QPATH);
strupr(Package);
Q_strupr(Package);
i = SP_ListByName.find(Package);
if (i != SP_ListByName.end())
@ -1616,11 +1684,7 @@ static void SP_UpdateLanguage(void)
void SP_Init(void)
{
sp_language = Cvar_Get("sp_language", va("%d", TEXT_LANGUAGE1), CVAR_ARCHIVE);
if (sp_language->integer>= TK_TEXT_LANGUAGE1){ // error correction for badly archived old stuff
sp_language->integer = TEXT_LANGUAGE1;
}
sp_language = Cvar_Get("sp_language", va("%d", SP_LANGUAGE_ENGLISH), CVAR_ARCHIVE);
sp_show_strip = Cvar_Get ("sv_show_strip", "0", 0);
SP_UpdateLanguage();

View file

@ -36,31 +36,13 @@ enum
SP_LANGUAGE_TAIWANESE,
SP_LANGUAGE_ITALIAN,
SP_LANGUAGE_SPANISH,
SP_LANGUAGE_9,
SP_LANGUAGE_JAPANESE,
SP_LANGUAGE_10,
SP_LANGUGAGE_MAX,
SP_LANGUAGE_ALL = 255
};
enum
{
TEXT_LANGUAGE1 = 0,
TEXT_LANGUAGE2,
TEXT_LANGUAGE3,
TEXT_LANGUAGE4,
TEXT_LANGUAGE5,
TEXT_LANGUAGE6,
TEXT_LANGUAGE7,
TEXT_LANGUAGE8,
TEXT_LANGUAGE9,
TEXT_LANGUAGE10,
TEXT_MAX,
TEXT_ALL = 255
};
#define SP_PACKAGE 0xff00
#define SP_STRING 0x00ff
@ -90,7 +72,7 @@ class cCriteria
public:
int WhichLanguage;
cCriteria(int initWhichLanguage = TEXT_ALL);
cCriteria(int initWhichLanguage = SP_LANGUAGE_ALL);
};
#ifdef _STRIPED_
@ -102,7 +84,7 @@ class cCriteriaED : public cCriteria
public:
cStringPackageED *Merge;
cCriteriaED(int initWhichLanguage = TEXT_ALL, cStringPackageED *initMerge = NULL);
cCriteriaED(int initWhichLanguage = SP_LANGUAGE_ALL, cStringPackageED *initMerge = NULL);
};
@ -325,5 +307,6 @@ void SP_Init(void);
#endif
extern int Language_GetIntegerValue(void);
#endif // __STRIP_H

File diff suppressed because it is too large Load diff

Binary file not shown.

View file

@ -216,7 +216,7 @@ void MC_UnCompress(float mat[3][4],const unsigned char * comp)
}
void MC_UnCompressQuat(float mat[3][4],const unsigned short * pwIn)
void MC_UnCompressQuat(float mat[3][4],const unsigned char * comp)
{
float w,x,y,z,f;
float fTx;
@ -232,6 +232,8 @@ void MC_UnCompressQuat(float mat[3][4],const unsigned short * pwIn)
float fTyz;
float fTzz;
const unsigned short *pwIn = (unsigned short *) comp;
w = *pwIn++;
w/=16383.0f;
w-=2.0f;

View file

@ -21,7 +21,8 @@ extern "C"
void MC_Compress(const float mat[3][4],unsigned char * comp);
void MC_UnCompress(float mat[3][4],const unsigned char * comp);
void MC_UnCompressQuat(float mat[3][4],const unsigned short * pwIn);
void MC_UnCompressQuat(float mat[3][4],const unsigned char * comp);
#ifdef __cplusplus

View file

@ -25,9 +25,8 @@
//
// normal version numbers...
//
#define MDXM_VERSION 4
#define MDXA_VERSION 4
#define MDXA_VERSION_QUAT 5
#define MDXM_VERSION 6
#define MDXA_VERSION 6
// (Note that since there is now a "<modelname>_info.txt" file written out by carcass any changes made in here that
// introduce new data should also be reflected in the info-output)
@ -54,12 +53,19 @@
// triangle side-ordering stuff for tags...
//
#define iG2_TRISIDE_MIDDLE 1
#define iG2_TRISIDE_LONGEST 0
#define iG2_TRISIDE_SHORTEST 2
#define iG2_TRISIDE_MIDDLE 1
#define iG2_TRISIDE_LONGEST 0
#define iG2_TRISIDE_SHORTEST 2
#define fG2_BONEWEIGHT_RECIPROCAL_MULT ((float)(1.0f/1023.0f))
#define iG2_BITS_PER_BONEREF 5
#define iMAX_G2_BONEREFS_PER_SURFACE (1<<iG2_BITS_PER_BONEREF) // (32)
#define iMAX_G2_BONEWEIGHTS_PER_VERT 4 // can't just be blindly increased, affects cache size etc
#define iG2_BONEWEIGHT_TOPBITS_SHIFT ((iG2_BITS_PER_BONEREF * iMAX_G2_BONEWEIGHTS_PER_VERT) - 8) // 8 bits because of 8 in the BoneWeight[] array entry
#define iG2_BONEWEIGHT_TOPBITS_AND 0x300 // 2 bits, giving 10 total, or 10 bits, for 1023/1024 above
#define MAX_G2_BONEREFS_PER_SURFACE 28 // currently only enforced when compiling Q3/G2 models, not xmen view-only tests
#define sDEFAULT_GLA_NAME "*default" // used when making special simple ghoul2 models, usually from MD3 files
@ -67,12 +73,29 @@
//
// these structs are defined here purely because of structure dependancy order...
//
typedef struct {
/*
#ifdef __cplusplus
struct mdxmWeight_t
#else
typedef struct
#endif
{
int boneIndex; // these are indexes into the surface boneReferences, not the global bone index
float boneWeight; // not the global per-frame bone list
} mdxmWeight_t;
// I'm defining this '<' operator so this struct can be used with an STL <set>...
// (note that I've defined it using '>' internally, so it sorts with higher weights being "less", for distance weight-culling
//
#ifdef __cplusplus
bool operator < (const mdxmWeight_t& _X) const {return (boneWeight>_X.boneWeight);}
#endif
}
#ifndef __cplusplus
mdxmWeight_t
#endif
;
*/
/*
#ifdef __cplusplus
struct mdxaCompBone_t
#else
@ -91,7 +114,7 @@ typedef struct
mdxaCompBone_t
#endif
;
*/
#ifdef __cplusplus
struct mdxaCompQuatBone_t
#else
@ -206,8 +229,6 @@ typedef struct {
int numTriangles;
int ofsTriangles;
int maxVertBoneWeights; // ... per vertex for hardware to reference. This number subtract the vert->numWeights gives # pad weights (which software will ignore)
// Bone references are a set of ints representing all the bones
// present in any vertex weights for this surface. This is
// needed because a model may have surfaces that need to be
@ -235,17 +256,72 @@ typedef struct {
// for each vert... (mdxmSurface_t->numVerts)
// {
// mdxVertex_t - this is an array with number of verts from the surface definition as its bounds. It contains normal info, texture coors and number of weightings for this bone
// (this is now kept at 32 bytes for cache-aligning)
typedef struct {
vec3_t normal;
vec3_t vertCoords;
vec2_t texCoords;
int numWeights; // remember, this is for software counts, look at mdxmSurface_t->numActualWeights for skipping purposes to account for padded weights
mdxmWeight_t weights[1]; // variable sized
// packed int...
unsigned int uiNmWeightsAndBoneIndexes; // 32 bits. format:
// 31 & 30: 0..3 (= 1..4) weight count
// 29 & 28 (spare)
// 2 bit pairs at 20,22,24,26 are 2-bit overflows from 4 BonWeights below (20=[0], 22=[1]) etc)
// 5-bits each (iG2_BITS_PER_BONEREF) for boneweights
// effectively a packed int, each bone weight converted from 0..1 float to 0..255 int...
// promote each entry to float and multiply by fG2_BONEWEIGHT_RECIPROCAL_MULT to convert.
byte BoneWeightings[iMAX_G2_BONEWEIGHTS_PER_VERT]; // 4
} mdxmVertex_t;
// } vert
#ifdef __cplusplus
// these are convenience functions that I can invoked in code. Do NOT change them (because this is a shared file),
// but if you want to copy the logic out and use your own versions then fine...
//
static inline int G2_GetVertWeights( const mdxmVertex_t *pVert )
{
int iNumWeights = (pVert->uiNmWeightsAndBoneIndexes >> 30)+1; // 1..4 count
return iNumWeights;
}
static inline int G2_GetVertBoneIndex( const mdxmVertex_t *pVert, const int iWeightNum)
{
int iBoneIndex = (pVert->uiNmWeightsAndBoneIndexes>>(iG2_BITS_PER_BONEREF*iWeightNum))&((1<<iG2_BITS_PER_BONEREF)-1);
return iBoneIndex;
}
static inline float G2_GetVertBoneWeight( const mdxmVertex_t *pVert, const int iWeightNum )
{
int iTemp = pVert->BoneWeightings[iWeightNum];
iTemp|= (pVert->uiNmWeightsAndBoneIndexes >> (iG2_BONEWEIGHT_TOPBITS_SHIFT+(iWeightNum*2)) ) & iG2_BONEWEIGHT_TOPBITS_AND;
float fBoneWeight = fG2_BONEWEIGHT_RECIPROCAL_MULT * iTemp;
if (fBoneWeight == 0.0f)
{
// special case to fix flatten-to-zero cases for extremely light weightings. Could probably be omitted if desperate...
//
fBoneWeight = 0.00045f;
}
return fBoneWeight;
}
#endif
// for each vert... (mdxmSurface_t->numVerts) (seperated from mdxmVertex_t struct for cache reasons)
// {
// mdxVertex_t - this is an array with number of verts from the surface definition as its bounds. It contains normal info, texture coors and number of weightings for this bone
typedef struct {
vec2_t texCoords;
} mdxmVertexTexCoord_t;
// } vert
// } surface
// } LOD
@ -271,7 +347,7 @@ typedef struct {
// frames and bones are shared by all levels of detail
//
int numFrames;
int ofsFrames;
int ofsFrames; // points at mdxaFrame_t array
int numBones; // (no offset to these since they're inside the frames array)
int ofsCompBonePool; // offset to global compressed-bone pool that all frames use
int ofsSkel; // offset to mdxaSkel_t info
@ -307,18 +383,24 @@ typedef struct {
// }
// for each frame... (mdxaHeader_t->numFrames)
// {
// mdxaFrame_t - which contains the header for the bones for this surface, plus the actual bone matrices themselves
typedef struct {
// (used to contain frame bounds info etc as well, doesn't now)
//
int boneIndexes[1]; // [numBones] ... into compressed bone pool
} mdxaFrame_t; // struct size = (int)( &((mdxaFrame_t *)0)->bones[ mdxaHeader_t->numBones ] );
// }
// (offset @ mdxaHeader_t->ofsFrames)
//
// array of 3 byte indices here (hey, 25% saving over 4-byte really adds up)...
//
//
// access as follows to get the index for a given <iFrameNum, iBoneNum>
//
// (iFrameNum * mdxaHeader_t->numBones * 3) + (iBoneNum * 3)
//
// then read the int at that location and AND it with 0x00FFFFFF. I use the struct below simply for easy searches
typedef struct
{
int iIndex; // this struct for pointing purposes, need to and with 0x00FFFFFF to be meaningful
} mdxaIndex_t;
//
// (note that there's then an alignement-pad here to get the next struct back onto 32-bit alignement)
//
// this index then points into the following...
// Compressed-bone pool that all frames use (mdxaHeader_t->ofsCompBonePool) (defined at end because size unknown until end)

View file

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

View file

@ -1,2 +0,0 @@
EXPORTS
GetRefAPI

View file

@ -1,914 +0,0 @@
# Microsoft Developer Studio Project File - Name="renderer" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=renderer - Win32 Debug TA
!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 "renderer.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 "renderer.mak" CFG="renderer - Win32 Debug TA"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "renderer - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "renderer - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "renderer - Win32 Release TA" (based on "Win32 (x86) Static Library")
!MESSAGE "renderer - Win32 Debug TA" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/MissionPack/code/renderer", EJBAAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "renderer - 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 /G6 /W4 /GX /O2 /Ob2 /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)" == "renderer - 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 /G5 /MTd /W3 /Gm /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
!ELSEIF "$(CFG)" == "renderer - Win32 Release TA"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "renderer___Win32_Release_TA"
# PROP BASE Intermediate_Dir "renderer___Win32_Release_TA"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release_TA"
# PROP Intermediate_Dir "Release_TA"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G6 /W4 /GX /O2 /Ob2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "__USEA3D" /D "__A3D_GEOM" /YX /FD /c
# ADD CPP /nologo /G6 /W4 /GX /O2 /Ob2 /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)" == "renderer - Win32 Debug TA"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "renderer___Win32_Debug_TA"
# PROP BASE Intermediate_Dir "renderer___Win32_Debug_TA"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug_TA"
# PROP Intermediate_Dir "Debug_TA"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /G5 /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "__USEA3D" /D "__A3D_GEOM" /FR /YX /FD /GZ /c
# ADD CPP /nologo /G5 /MTd /W3 /Gm /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 "renderer - Win32 Release"
# Name "renderer - Win32 Debug"
# Name "renderer - Win32 Release TA"
# Name "renderer - Win32 Debug TA"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\ref_trin.def
# End Source File
# Begin Source File
SOURCE=.\tr_animation.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_backend.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_bsp.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_cmds.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_curve.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_flares.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_font.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_image.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_init.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_light.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_main.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_marks.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_mesh.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_model.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_noise.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_scene.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_shade.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_shade_calc.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_shader.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_shadows.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_sky.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_surface.cpp
# End Source File
# Begin Source File
SOURCE=.\tr_world.cpp
# End Source File
# Begin Source File
SOURCE=..\win32\win_gamma.cpp
# End Source File
# Begin Source File
SOURCE=..\win32\win_glimp.cpp
# End Source File
# Begin Source File
SOURCE=..\win32\win_qgl.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\qcommon\cm_public.h
# End Source File
# Begin Source File
SOURCE=..\win32\glw_win.h
# End Source File
# Begin Source File
SOURCE=..\game\q_shared.h
# 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=.\qgl.h
# End Source File
# Begin Source File
SOURCE=..\game\surfaceflags.h
# End Source File
# Begin Source File
SOURCE=.\tr_local.h
# End Source File
# Begin Source File
SOURCE=.\tr_public.h
# End Source File
# Begin Source File
SOURCE=..\cgame\tr_types.h
# End Source File
# Begin Source File
SOURCE=..\win32\win_local.h
# End Source File
# End Group
# Begin Group "jpeg"
# PROP Default_Filter ""
# Begin Group "Source Files No. 1"
# PROP Default_Filter ""
# Begin Source File
SOURCE="..\jpeg-6\jcapimin.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jccoefct.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jccolor.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jcdctmgr.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jchuff.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jcinit.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jcmainct.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jcmarker.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jcmaster.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jcomapi.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jcparam.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jcphuff.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jcprepct.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jcsample.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jctrans.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdapimin.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdapistd.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdatadst.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdatasrc.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdcoefct.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdcolor.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jddctmgr.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdhuff.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdinput.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdmainct.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdmarker.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdmaster.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdpostct.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdsample.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdtrans.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jerror.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jfdctflt.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jidctflt.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jmemmgr.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jmemnobs.cpp"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jutils.cpp"
# End Source File
# End Group
# Begin Group "Header Files No. 1"
# PROP Default_Filter ""
# Begin Source File
SOURCE="..\jpeg-6\jchuff.h"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jconfig.h"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdct.h"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jdhuff.h"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jerror.h"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jinclude.h"
# End Source File
# Begin Source File
SOURCE="..\jpeg-6\jmemsys.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="..\jpeg-6\jversion.h"
# End Source File
# Begin Source File
SOURCE=..\ft2\sfdriver.h
# End Source File
# Begin Source File
SOURCE=..\ft2\sfobjs.h
# End Source File
# Begin Source File
SOURCE=..\ft2\ttcmap.h
# End Source File
# Begin Source File
SOURCE=..\ft2\ttload.h
# End Source File
# Begin Source File
SOURCE=..\ft2\ttpost.h
# End Source File
# Begin Source File
SOURCE=..\ft2\ttsbit.h
# End Source File
# End Group
# End Group
# Begin Group "FreeType2"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Group "Include files"
# PROP Default_Filter "*.h"
# Begin Source File
SOURCE=..\ft2\ahangles.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ahglobal.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ahglyph.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ahhint.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ahloader.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ahmodule.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ahoptim.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ahtypes.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\autohint.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\freetype.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftbbox.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftcalc.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftconfig.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftdebug.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftdriver.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\fterrors.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftextend.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftglyph.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftgrays.h
# End Source File
# Begin Source File
SOURCE=..\ft2\ftimage.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftlist.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftmemory.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftmm.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftmodule.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftnames.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftobjs.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftoption.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftoutln.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftraster.h
# End Source File
# Begin Source File
SOURCE=..\ft2\ftrend1.h
# End Source File
# Begin Source File
SOURCE=..\ft2\ftrender.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftsmooth.h
# End Source File
# Begin Source File
SOURCE=..\ft2\ftstream.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ftsystem.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\fttypes.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\psnames.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\sfnt.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\t1errors.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\t1tables.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\t1types.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\t2errors.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\t2types.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ttdriver.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\tterrors.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ttgload.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ttinterp.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ttnameid.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ttobjs.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\ttpload.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\tttables.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\tttags.h
# PROP Exclude_From_Build 1
# End Source File
# Begin Source File
SOURCE=..\ft2\tttypes.h
# PROP Exclude_From_Build 1
# End Source File
# End Group
# Begin Source File
SOURCE=..\ft2\ahangles.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ahglobal.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ahglyph.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ahhint.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ahmodule.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ahoptim.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftcalc.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftdebug.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftextend.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftglyph.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftgrays.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftinit.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftlist.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftmm.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftnames.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftobjs.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftoutln.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftraster.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftrend1.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftsmooth.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftstream.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ftsystem.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\sfdriver.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\sfobjs.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ttcmap.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ttdriver.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ttgload.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ttinterp.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ttload.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ttobjs.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ttpload.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ttpost.cpp
# End Source File
# Begin Source File
SOURCE=..\ft2\ttsbit.cpp
# End Source File
# End Group
# End Target
# End Project

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