mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2025-01-19 16:11:28 +00:00
Elder:
Code for 0-12-00 VMs Client-side
This commit is contained in:
parent
94e995d561
commit
1b12240f15
8 changed files with 528 additions and 23 deletions
|
@ -561,6 +561,71 @@ void CG_BleedSpray ( vec3_t start, vec3_t end, int entityNum, int numBursts )
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_EjectBloodSplat
|
||||
|
||||
Drop a splat
|
||||
=================
|
||||
*/
|
||||
|
||||
void CG_EjectBloodSplat ( vec3_t origin, vec3_t velocity, int amount, int duration )
|
||||
{
|
||||
int i;
|
||||
localEntity_t *blood;
|
||||
vec3_t bOrigin;
|
||||
vec3_t bVelocity;
|
||||
|
||||
if ( !cg_blood.integer )
|
||||
return;
|
||||
|
||||
for (i = 0; i < amount; i++)
|
||||
{
|
||||
VectorCopy( origin, bOrigin );
|
||||
VectorCopy( velocity, bVelocity );
|
||||
bOrigin[0] += rand() % 6 - 3;
|
||||
bOrigin[1] += rand() % 6 - 3;
|
||||
bVelocity[0] += rand() % 6 - 3;
|
||||
bVelocity[1] += rand() % 6 - 3;
|
||||
|
||||
blood = CG_SmokePuff( bOrigin, bVelocity, 4,
|
||||
1, 1, 1, 0.6f,
|
||||
duration + rand() % 250, cg.time, 0,
|
||||
LEF_TUMBLE|LEF_PUFF_DONT_SCALE,
|
||||
cgs.media.bloodTrailShader);
|
||||
blood->refEntity.rotation = rand() % 360;
|
||||
blood->leType = LE_FRAGMENT;
|
||||
blood->leType = LE_FRAGMENT;
|
||||
blood->leMarkType = LEMT_BLOOD;
|
||||
blood->pos.trType = TR_GRAVITY;
|
||||
blood->bounceFactor = 0.4f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_BleedParticleSpray
|
||||
|
||||
This is a particle blood spray not unlike Quake 2's
|
||||
Err, it's not working well right now :/
|
||||
=================
|
||||
*/
|
||||
|
||||
void CG_BleedParticleSpray ( vec3_t start, vec3_t dir, int fleshEntityNum, int amount, int duration)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( !cg_RQ3_bloodStyle.integer || !cg_blood.integer)
|
||||
return;
|
||||
|
||||
for (i = 0; i < amount; i++)
|
||||
{
|
||||
CG_Particle_Bleed(cgs.media.bloodExplosionShader, start, dir, fleshEntityNum, duration + rand() % 250);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CG_Bleed
|
||||
|
|
|
@ -2050,7 +2050,13 @@ void CG_EntityEvent( centity_t *cent, vec3_t position ) {
|
|||
|
||||
case EV_EJECTBLOOD:
|
||||
DEBUGNAME("EV_EJECTBLOOD");
|
||||
// Eject a blood splat
|
||||
// Straight up
|
||||
dir[0] = 0;
|
||||
dir[1] = 0;
|
||||
dir[2] = 20;
|
||||
// Eject blood splats
|
||||
CG_EjectBloodSplat ( es->pos.trBase, dir, 1, 1500);
|
||||
//CG_BleedParticleSpray( es->pos.trBase, dir, es->otherEntityNum, 25, 1500 );
|
||||
break;
|
||||
|
||||
case EV_SHOTGUN:
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#define DUCK_TIME 100
|
||||
#define PAIN_TWITCH_TIME 200
|
||||
#define WEAPON_SELECT_TIME 1400
|
||||
#define KICK_TIME 40 // Elder: default kick time, added for kick decay
|
||||
// Elder: decreased from 1000
|
||||
#define ITEM_SCALEUP_TIME 250
|
||||
#define ZOOM_TIME 150
|
||||
|
@ -386,6 +387,19 @@ typedef struct {
|
|||
} clientInfo_t;
|
||||
|
||||
|
||||
// Elder: maximum sizes
|
||||
#define MAX_RELOAD_SOUNDS 5
|
||||
#define MAX_OTHER_SOUNDS 5
|
||||
// Circular, singly-linked list
|
||||
struct sfxSyncInfo_s {
|
||||
int frame;
|
||||
sfxHandle_t sound;
|
||||
struct sfxSyncInfo_s *next;
|
||||
};
|
||||
|
||||
typedef struct sfxSyncInfo_s sfxSyncInfo_t;
|
||||
|
||||
|
||||
// each WP_* weapon enum has an associated weaponInfo_t
|
||||
// that contains media references necessary to present the
|
||||
// weapon and its effects
|
||||
|
@ -427,6 +441,14 @@ typedef struct weaponInfo_s {
|
|||
|
||||
sfxHandle_t readySound;
|
||||
sfxHandle_t firingSound;
|
||||
|
||||
// Elder: sounds to queue
|
||||
sfxSyncInfo_t activateSound[2]; // last one is an endpoint node
|
||||
sfxSyncInfo_t disarmSound[2]; // last one is an endpoint node
|
||||
sfxSyncInfo_t reloadSounds[MAX_RELOAD_SOUNDS];
|
||||
sfxSyncInfo_t otherSounds[MAX_OTHER_SOUNDS];
|
||||
|
||||
// Deprecated
|
||||
sfxHandle_t reloadSound1; // Elder: for various reload stages such as
|
||||
sfxHandle_t reloadSound2; // Clip in, clip out, sliding, sliding bolt,
|
||||
sfxHandle_t reloadSound3; // etc. Three should be enough
|
||||
|
@ -655,6 +677,8 @@ typedef struct {
|
|||
|
||||
vec3_t kick_angles; // weapon kicks
|
||||
vec3_t kick_origin;
|
||||
int kick_time; // Elder: added to decay the kicks more smoothly
|
||||
int kick_duration; // Elder: some need more
|
||||
|
||||
// temp working variables for player view
|
||||
float bobfracsin;
|
||||
|
@ -679,7 +703,9 @@ typedef struct {
|
|||
qboolean laserSight; //Whether to draw local laser sight
|
||||
localEntity_t *laserEnt; //Local model -- NULL if not in-use
|
||||
qboolean rq3_irvision; // Elder: enabled IR vision
|
||||
int akimboFlash; // Alternate between two tags for flash (0 or 1)
|
||||
int akimboFlash; // Alternate between two tags for flash (0 or 1)
|
||||
|
||||
sfxSyncInfo_t *curSyncSound; // Shifts after a sound is played
|
||||
|
||||
} cg_t;
|
||||
|
||||
|
@ -849,6 +875,9 @@ typedef struct {
|
|||
qhandle_t redKamikazeShader;
|
||||
qhandle_t blueKamikazeShader;
|
||||
|
||||
// Elder: rq3 misc shaders
|
||||
qhandle_t irPlayerShader;
|
||||
|
||||
// weapon effect models
|
||||
qhandle_t bulletFlashModel;
|
||||
qhandle_t ringFlashModel;
|
||||
|
@ -1563,6 +1592,8 @@ void CG_BreakGlass( vec3_t playerOrigin, int glassParm, int type );
|
|||
void CG_Bleed( vec3_t origin, int entityNum );
|
||||
//Elder: for SSG shots
|
||||
void CG_BleedSpray ( vec3_t start, vec3_t end, int entityNum, int numBursts );
|
||||
void CG_BleedParticleSpray ( vec3_t start, vec3_t dir, int fleshEntityNum, int amount, int duration);
|
||||
void CG_EjectBloodSplat ( vec3_t origin, vec3_t velocity, int amount, int duration );
|
||||
|
||||
localEntity_t *CG_MakeExplosion( vec3_t origin, vec3_t dir,
|
||||
qhandle_t hModel, qhandle_t shader, int msec,
|
||||
|
|
|
@ -942,6 +942,9 @@ static void CG_RegisterGraphics( void ) {
|
|||
cgs.media.regenShader = trap_R_RegisterShader("powerups/regen" );
|
||||
cgs.media.hastePuffShader = trap_R_RegisterShader("hasteSmokePuff" );
|
||||
|
||||
// Elder: RQ3 misc. shaders
|
||||
cgs.media.irPlayerShader = trap_R_RegisterShader("powerups/irdetail");
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
if ( cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF || cgs.gametype == GT_HARVESTER || cg_buildScript.integer ) {
|
||||
#else
|
||||
|
|
|
@ -2364,14 +2364,13 @@ void CG_AddRefEntityWithPowerups( refEntity_t *ent, entityState_t *state, int te
|
|||
trap_R_AddRefEntityToScene( ent );
|
||||
}
|
||||
|
||||
//Elder: IR Vision -- only on players
|
||||
//Elder: IR Vision -- only on players that are alive
|
||||
if (state->eType == ET_PLAYER)
|
||||
{
|
||||
if (bg_itemlist[cg.snap->ps.stats[STAT_HOLDABLE_ITEM]].giTag == HI_BANDOLIER &&
|
||||
cg.rq3_irvision && !(state->eFlags & EF_DEAD))
|
||||
{
|
||||
//Temporary heh
|
||||
ent->customShader = cgs.media.quadShader;
|
||||
ent->customShader = cgs.media.irPlayerShader;
|
||||
trap_R_AddRefEntityToScene( ent );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,6 +244,7 @@ void CG_Respawn( void ) {
|
|||
//Elder: added to reset zoom stuff LOCALLY
|
||||
CG_RQ3_Zoom1x();
|
||||
|
||||
cg.curSyncSound = 0;
|
||||
}
|
||||
|
||||
extern char *eventnames[];
|
||||
|
@ -572,6 +573,12 @@ void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ) {
|
|||
cg.duckTime = cg.time;
|
||||
}
|
||||
|
||||
// Elder: reset sync sounds
|
||||
if ( ps->weaponstate != ops->weaponstate )
|
||||
{
|
||||
cg.curSyncSound = 0;
|
||||
}
|
||||
|
||||
//Elder: grenade message
|
||||
if (ps->weapon == WP_GRENADE &&
|
||||
ps->weaponstate == WEAPON_COCKED && ops->weaponstate != WEAPON_COCKED)
|
||||
|
|
|
@ -418,6 +418,41 @@ static void CG_OffsetFirstPersonView( void ) {
|
|||
VectorMA( cg.refdef.vieworg, NECK_LENGTH, up, cg.refdef.vieworg );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Weapon kick management
|
||||
if (cg.kick_time)
|
||||
{
|
||||
int duration;
|
||||
|
||||
if (cg.kick_duration)
|
||||
duration = cg.kick_duration;
|
||||
else
|
||||
duration = KICK_TIME;
|
||||
|
||||
if ( cg.time - cg.kick_time >= duration )
|
||||
{
|
||||
// Elder: clear kick origin and angles
|
||||
VectorClear(cg.kick_angles);
|
||||
VectorClear(cg.kick_origin);
|
||||
cg.kick_time = 0;
|
||||
cg.kick_duration = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Decay them
|
||||
cg.kick_angles[0] = cg.kick_angles[0] * (1 - (float)(cg.time - cg.kick_time) / duration);
|
||||
cg.kick_angles[1] = cg.kick_angles[1] * (1 - (float)(cg.time - cg.kick_time) / duration);
|
||||
cg.kick_angles[2] = cg.kick_angles[2] * (1 - (float)(cg.time - cg.kick_time) / duration);
|
||||
cg.kick_origin[0] = cg.kick_origin[0] * (1 - (float)(cg.time - cg.kick_time) / duration);
|
||||
cg.kick_origin[1] = cg.kick_origin[1] * (1 - (float)(cg.time - cg.kick_time) / duration);
|
||||
cg.kick_origin[2] = cg.kick_origin[2] * (1 - (float)(cg.time - cg.kick_time) / duration);
|
||||
}
|
||||
/*
|
||||
CG_Printf("Kick Angles: (%f %f %f) Origin: (%f %f %f)\n",
|
||||
cg.kick_angles[0], cg.kick_angles[1], cg.kick_angles[2],
|
||||
cg.kick_origin[0], cg.kick_origin[1], cg.kick_origin[2]);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
|
|
@ -2,6 +2,136 @@
|
|||
//
|
||||
// cg_weapons.c -- events and effects dealing with weapons
|
||||
#include "cg_local.h"
|
||||
|
||||
/*
|
||||
==========================
|
||||
CG_ParseWeaponSoundFile
|
||||
|
||||
Added by Elder
|
||||
Reads information for frame-sound timing
|
||||
==========================
|
||||
*/
|
||||
static qboolean CG_ParseWeaponSoundFile( const char *filename, weaponInfo_t *weapon ) {
|
||||
char *text_p;
|
||||
int len;
|
||||
int i;
|
||||
char *token;
|
||||
float fps;
|
||||
int skip; // Elder: What's this for?
|
||||
char text[20000];
|
||||
fileHandle_t f;
|
||||
animation_t *animations;
|
||||
sfxSyncInfo_t *reloadSounds;
|
||||
|
||||
|
||||
animations = weapon->animations;
|
||||
reloadSounds = weapon->reloadSounds;
|
||||
|
||||
// load the file
|
||||
len = trap_FS_FOpenFile( filename, &f, FS_READ );
|
||||
if ( len <= 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( len >= sizeof( text ) - 1 ) {
|
||||
CG_Printf( "File %s too long\n", filename );
|
||||
return qfalse;
|
||||
}
|
||||
trap_FS_Read( text, len, f );
|
||||
text[len] = 0;
|
||||
trap_FS_FCloseFile( f );
|
||||
|
||||
// parse the text
|
||||
text_p = text;
|
||||
// Elder: uhh, what was this for?
|
||||
skip = 0; // quite the compiler warning
|
||||
|
||||
// read information for each phase of a reload
|
||||
for ( i = 0 ; i < MAX_RELOAD_SOUNDS ; i++ )
|
||||
{
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token ) break;
|
||||
// handle "0"/blank listings
|
||||
if ( !atoi( token ) )
|
||||
{
|
||||
// set these to the end frames
|
||||
reloadSounds[i].frame = animations[WP_ANIM_RELOAD].firstFrame + animations[WP_ANIM_RELOAD].numFrames;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
reloadSounds[i].frame = atoi( token );
|
||||
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token ) break;
|
||||
reloadSounds[i].sound = trap_S_RegisterSound(token, qfalse);
|
||||
|
||||
}
|
||||
|
||||
if ( i != MAX_RELOAD_SOUNDS ) {
|
||||
CG_Printf( "Error parsing weapon sound file in reload stage: %s", filename );
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
// link our reload sound nodes
|
||||
for ( i = 0; i < MAX_RELOAD_SOUNDS ; i++ )
|
||||
{
|
||||
// end frames
|
||||
if (reloadSounds[i].frame == animations[WP_ANIM_RELOAD].firstFrame + animations[WP_ANIM_RELOAD].numFrames)
|
||||
reloadSounds[i].next = &reloadSounds[0];
|
||||
// normal case
|
||||
else if (i + 1 < MAX_RELOAD_SOUNDS && reloadSounds[i+1].frame != 0)
|
||||
reloadSounds[i].next = &reloadSounds[i+1];
|
||||
// shouldn't be here
|
||||
else
|
||||
reloadSounds[i].next = &reloadSounds[0];
|
||||
}
|
||||
|
||||
// disarm sound
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token ) {
|
||||
CG_Printf( "Error parsing weapon sound file in disarm stage: %s", filename );
|
||||
return qfalse;
|
||||
}
|
||||
if ( !atoi( token ) )
|
||||
CG_Printf( "No disarm sound for %s\n", weapon->item->pickup_name);
|
||||
else
|
||||
{
|
||||
weapon->disarmSound[0].frame = atoi( token );
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token ) {
|
||||
CG_Printf( "Error parsing weapon sound file in disarm stage: %s", filename );
|
||||
return qfalse;
|
||||
}
|
||||
weapon->disarmSound[0].sound = trap_S_RegisterSound( token, qfalse );
|
||||
weapon->disarmSound[0].next = &weapon->disarmSound[1];
|
||||
weapon->disarmSound[1].frame = animations[WP_ANIM_DISARM].firstFrame + animations[WP_ANIM_DISARM].numFrames;
|
||||
weapon->disarmSound[1].next = &weapon->disarmSound[0];
|
||||
}
|
||||
|
||||
// activate sound
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token ) {
|
||||
CG_Printf( "Error parsing weapon sound file in activate stage: %s", filename );
|
||||
return qfalse;
|
||||
}
|
||||
if ( !atoi( token ) )
|
||||
CG_Printf( "No activate sound for %s\n", weapon->item->pickup_name);
|
||||
else
|
||||
{
|
||||
weapon->activateSound[0].frame = atoi( token );
|
||||
token = COM_Parse( &text_p );
|
||||
if ( !token ) {
|
||||
CG_Printf( "Error parsing weapon sound file in activate stage: %s", filename );
|
||||
return qfalse;
|
||||
}
|
||||
weapon->activateSound[0].sound = trap_S_RegisterSound( token, qfalse );
|
||||
weapon->activateSound[0].next = &weapon->activateSound[1];
|
||||
weapon->activateSound[1].frame = animations[WP_ANIM_ACTIVATE].firstFrame + animations[WP_ANIM_ACTIVATE].numFrames;
|
||||
weapon->activateSound[1].next = &weapon->activateSound[0];
|
||||
}
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/* [QUARANTINE] - Weapon Animations - CG_ParseWeaponAnimFile
|
||||
==========================
|
||||
CG_ParseWeaponAnimFile
|
||||
|
@ -660,6 +790,7 @@ void CG_RegisterWeapon( int weaponNum ) {
|
|||
// END
|
||||
|
||||
int i;
|
||||
qboolean weapAnimLoad = qtrue;
|
||||
|
||||
weaponInfo = &cg_weapons[weaponNum];
|
||||
|
||||
|
@ -758,15 +889,42 @@ void CG_RegisterWeapon( int weaponNum ) {
|
|||
MAKERGB( weaponInfo->flashDlightColor, 1, 1, 0 );
|
||||
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/mk23/mk23fire.wav", qfalse );
|
||||
weaponInfo->ejectBrassFunc = CG_MachineGunEjectBrass;
|
||||
weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/mk23/mk23out.wav", qfalse );
|
||||
weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/mk23/mk23in.wav", qfalse );
|
||||
weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/mk23/mk23slide.wav", qfalse );
|
||||
//weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/mk23/mk23out.wav", qfalse );
|
||||
//weaponInfo->reloadSound2 = trap_S_RegisterSound( "sound/weapons/mk23/mk23in.wav", qfalse );
|
||||
//weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/mk23/mk23slide.wav", qfalse );
|
||||
cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" );
|
||||
|
||||
// Load the animation information
|
||||
Com_sprintf( filename, sizeof(filename), "models/weapons2/mk23/animation.cfg" );
|
||||
if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) {
|
||||
Com_Printf("Failed to load weapon animation file %s\n", filename);
|
||||
weapAnimLoad = qfalse;
|
||||
}
|
||||
|
||||
// Load sound information -- ALWAYS DO THIS AFTER THE ANIMATION
|
||||
if (weapAnimLoad)
|
||||
{
|
||||
Com_sprintf( filename, sizeof(filename), "models/weapons2/mk23/sound.cfg" );
|
||||
if ( !CG_ParseWeaponSoundFile(filename, weaponInfo) ) {
|
||||
Com_Printf("Failed to load weapon sound file %s\n", filename);
|
||||
}
|
||||
else {
|
||||
// Temporarily print the info
|
||||
int k;
|
||||
Com_Printf("Sync Sound Status:\n");
|
||||
for (k = 0; k < MAX_RELOAD_SOUNDS; k++)
|
||||
{
|
||||
Com_Printf("%i: Frame %i Has sfxHandle: %s\n",
|
||||
k, weaponInfo->reloadSounds[k].frame,
|
||||
weaponInfo->reloadSounds[k].sound? "yes":"no");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Com_Printf("Could not load sound.cfg because animation.cfg loading failed\n");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case WP_KNIFE:
|
||||
|
@ -774,6 +932,13 @@ void CG_RegisterWeapon( int weaponNum ) {
|
|||
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/knife/slash.wav", qfalse );
|
||||
weaponInfo->missileModel = trap_R_RegisterModel("models/weapons2/knife/knife.md3");
|
||||
|
||||
// Load the animation information
|
||||
Com_sprintf( filename, sizeof(filename), "models/weapons2/knife/animation.cfg" );
|
||||
if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) {
|
||||
Com_Printf("Failed to load weapon animation file %s\n", filename);
|
||||
weapAnimLoad = qfalse;
|
||||
}
|
||||
|
||||
//weaponInfo->missileTrailFunc = CG_GrenadeTrail;
|
||||
//cgs.media.grenadeExplosionShader = trap_R_RegisterShader( "grenadeExplosion" );
|
||||
//weaponInfo->wiTrailTime = 700;
|
||||
|
@ -785,13 +950,23 @@ void CG_RegisterWeapon( int weaponNum ) {
|
|||
MAKERGB( weaponInfo->flashDlightColor, 1, 1, 0 );
|
||||
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/m4/m4fire.wav", qfalse );
|
||||
weaponInfo->ejectBrassFunc = CG_MachineGunEjectBrass;
|
||||
weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/m4/m4out.wav", qfalse );
|
||||
weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/m4/m4in.wav", qfalse );
|
||||
//weaponInfo->reloadSound1 = trap_S_RegisterSound( "sound/weapons/m4/m4out.wav", qfalse );
|
||||
//weaponInfo->reloadSound3 = trap_S_RegisterSound( "sound/weapons/m4/m4in.wav", qfalse );
|
||||
cgs.media.bulletExplosionShader = trap_R_RegisterShader( "bulletExplosion" );
|
||||
|
||||
Com_sprintf( filename, sizeof(filename), "models/weapons2/m4/animation.cfg" );
|
||||
if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) {
|
||||
Com_Printf("Failed to load weapon animation file %s\n", filename);
|
||||
weapAnimLoad = qfalse;
|
||||
}
|
||||
|
||||
if (weapAnimLoad) {
|
||||
Com_sprintf( filename, sizeof(filename), "models/weapons2/m4/sound.cfg" );
|
||||
if ( !CG_ParseWeaponSoundFile(filename, weaponInfo) ) {
|
||||
Com_Printf("Failed to load weapon sound file %s\n", filename);
|
||||
}
|
||||
} else {
|
||||
Com_Printf("Could not load sound.cfg because animation.cfg loading failed\n");
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -863,19 +1038,37 @@ void CG_RegisterWeapon( int weaponNum ) {
|
|||
Com_sprintf( filename, sizeof(filename), "models/weapons2/akimbo/animation.cfg" );
|
||||
if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) {
|
||||
Com_Printf("Failed to load weapon animation file %s\n", filename);
|
||||
weapAnimLoad = qfalse;
|
||||
}
|
||||
|
||||
// Load sound information -- ALWAYS DO THIS AFTER THE ANIMATION
|
||||
if (weapAnimLoad) {
|
||||
Com_sprintf( filename, sizeof(filename), "models/weapons2/akimbo/sound.cfg" );
|
||||
if ( !CG_ParseWeaponSoundFile(filename, weaponInfo) ) {
|
||||
Com_Printf("Failed to load weapon sound file %s\n", filename);
|
||||
}
|
||||
} else {
|
||||
Com_Printf("Could not load sound.cfg because animation.cfg loading failed\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case WP_GRENADE:
|
||||
//Changed from _3rd
|
||||
weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/grenade/grenade.md3" );
|
||||
//Elder: removed for the last time!! ;
|
||||
//Use the projectile model
|
||||
weaponInfo->missileModel = trap_R_RegisterModel( "models/weapons2/grenade/gren_projectile.md3" );
|
||||
//Elder: removed for the last time! :)
|
||||
//weaponInfo->missileTrailFunc = CG_GrenadeTrail;
|
||||
weaponInfo->wiTrailTime = 700;
|
||||
weaponInfo->trailRadius = 32;
|
||||
MAKERGB( weaponInfo->flashDlightColor, 1, 0.70f, 0 );
|
||||
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/grenade/grenlf1a.wav", qfalse );
|
||||
weaponInfo->flashSound[0] = trap_S_RegisterSound( "sound/weapons/grenade/gren_throw.wav", qfalse );
|
||||
cgs.media.grenadeExplosionShader = trap_R_RegisterShader( "grenadeExplosion" );
|
||||
|
||||
// Load the animation information
|
||||
Com_sprintf( filename, sizeof(filename), "models/weapons2/grenade/animation.cfg" );
|
||||
if ( !CG_ParseWeaponAnimFile(filename, weaponInfo) ) {
|
||||
Com_Printf("Failed to load weapon animation file %s\n", filename);
|
||||
weapAnimLoad = qfalse;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1287,6 +1480,37 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
|
|||
else {
|
||||
CG_WeaponAnimation( cent, &gun.oldframe, &gun.frame, &gun.backlerp );
|
||||
CG_PositionWeaponOnTag( &gun, parent, parent->hModel, "tag_weapon");
|
||||
|
||||
// Elder: Local sound events will sync perfectly here
|
||||
// However, we must remember to ignore the ones pmove will generate
|
||||
// (for other clients to hear) or we'll get some nasty echo
|
||||
|
||||
// Temp hack because it isn't fully implemented
|
||||
if ( weapon->item->giTag == WP_PISTOL ||
|
||||
weapon->item->giTag == WP_AKIMBO ||
|
||||
weapon->item->giTag == WP_M4)
|
||||
{
|
||||
if ( ps->weaponstate == WEAPON_RELOADING ) {
|
||||
if ( !cg.curSyncSound || cg.curSyncSound->frame == 0)
|
||||
cg.curSyncSound = &weapon->reloadSounds[0];
|
||||
}
|
||||
else if ( ps->weaponstate == WEAPON_RAISING ) {
|
||||
if ( !cg.curSyncSound || cg.curSyncSound->frame == 0)
|
||||
cg.curSyncSound = &weapon->activateSound[0];
|
||||
}
|
||||
else if ( ps->weaponstate == WEAPON_DROPPING ) {
|
||||
if ( !cg.curSyncSound || cg.curSyncSound->frame == 0)
|
||||
cg.curSyncSound = &weapon->disarmSound[0];
|
||||
}
|
||||
|
||||
if (cg.curSyncSound && cg.curSyncSound->frame == gun.frame) {
|
||||
if ( cg.curSyncSound->sound ) {
|
||||
CG_Printf("Playing a timed sound (%i %i %1.1f)\n", gun.frame, gun.oldframe, gun.backlerp);
|
||||
trap_S_StartLocalSound ( cg.curSyncSound->sound, CHAN_WEAPON );
|
||||
cg.curSyncSound = cg.curSyncSound->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Elder: break off here so we still have weapon animations on bolt out
|
||||
|
@ -1381,15 +1605,17 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
|
|||
if ( cg_RQ3_flash.integer ) {
|
||||
if (ps) {
|
||||
// Elder: draw flash based on first-person view
|
||||
// choose tag for akimbo
|
||||
if (ps->weapon == WP_AKIMBO && ps->stats[STAT_BURST])
|
||||
if (ps->weapon == WP_AKIMBO)
|
||||
{
|
||||
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->firstModel, "tag_flash2");
|
||||
// choose tag for akimbos
|
||||
if (ps->stats[STAT_BURST])
|
||||
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->firstModel, "tag_flash");
|
||||
else
|
||||
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->firstModel, "tag_flash2");
|
||||
}
|
||||
else
|
||||
{
|
||||
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->firstModel, "tag_flash");
|
||||
}
|
||||
|
||||
// Make flash larger to compensate for depth hack
|
||||
VectorScale( flash.axis[0], 2.0f, flash.axis[0] );
|
||||
VectorScale( flash.axis[1], 2.0f, flash.axis[1] );
|
||||
|
@ -1398,8 +1624,14 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
|
|||
}
|
||||
else {
|
||||
//Elder: draw flash based on 3rd-person view
|
||||
if (cg.akimboFlash)
|
||||
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash2");
|
||||
if ( weapon->item->giTag == WP_AKIMBO)
|
||||
{
|
||||
// choose tag for akimbos
|
||||
if (cg.akimboFlash)
|
||||
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash");
|
||||
else
|
||||
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash2");
|
||||
}
|
||||
else
|
||||
CG_PositionRotatedEntityOnTag( &flash, &gun, weapon->weaponModel, "tag_flash");
|
||||
}
|
||||
|
@ -1558,7 +1790,9 @@ void CG_AddViewWeapon( playerState_t *ps ) {
|
|||
ps->weapon == WP_HANDCANNON ||
|
||||
ps->weapon == WP_SSG3000 ||
|
||||
ps->weapon == WP_M4 ||
|
||||
ps->weapon == WP_AKIMBO) {
|
||||
ps->weapon == WP_AKIMBO ||
|
||||
ps->weapon == WP_GRENADE ||
|
||||
ps->weapon == WP_KNIFE) {
|
||||
// development tool
|
||||
hand.frame = hand.oldframe = cg_gun_frame.integer;
|
||||
hand.backlerp = 0;
|
||||
|
@ -2181,7 +2415,7 @@ Caused by an EV_FIRE_WEAPON event
|
|||
*/
|
||||
void CG_FireWeapon( centity_t *cent, int weapModification ) {
|
||||
entityState_t *ent;
|
||||
int c;
|
||||
int c, i;
|
||||
weaponInfo_t *weap;
|
||||
|
||||
ent = ¢->currentState;
|
||||
|
@ -2274,6 +2508,131 @@ void CG_FireWeapon( centity_t *cent, int weapModification ) {
|
|||
if ( weap->ejectBrassFunc && cg_brassTime.integer > 0 ) {
|
||||
weap->ejectBrassFunc( cent );
|
||||
}
|
||||
|
||||
/*
|
||||
// MK23
|
||||
//Calculate the kick angles
|
||||
for (i=1 ; i<3 ; i++)
|
||||
{
|
||||
ent->client->kick_origin[i] = crandom() * 0.35;
|
||||
ent->client->kick_angles[i] = crandom() * 0.7;
|
||||
}
|
||||
ent->client->kick_origin[0] = crandom() * 0.35;
|
||||
|
||||
// Akimbo
|
||||
//Calculate the kick angles
|
||||
for (i=1 ; i<3 ; i++)
|
||||
{
|
||||
ent->client->kick_origin[i] = crandom() * 0.25;
|
||||
ent->client->kick_angles[i] = crandom() * 0.5;
|
||||
}
|
||||
ent->client->kick_origin[0] = crandom() * 0.35;
|
||||
|
||||
// Handcannon
|
||||
AngleVectors (ent->client->v_angle, forward, right, NULL);
|
||||
|
||||
VectorScale (forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -2;
|
||||
|
||||
// Knives
|
||||
AngleVectors (ent->client->v_angle, forward, right, NULL);
|
||||
|
||||
VectorScale (forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -2;
|
||||
|
||||
// M3
|
||||
AngleVectors (ent->client->v_angle, forward, right, NULL);
|
||||
|
||||
VectorScale (forward, -2, ent->client->kick_origin);
|
||||
ent->client->kick_angles[0] = -2;
|
||||
|
||||
// M4 -- we already add the ride-up angles in pmove
|
||||
//Calculate the kick angles
|
||||
for (i=1 ; i<3 ; i++)
|
||||
{
|
||||
ent->client->kick_origin[i] = crandom() * 0.25;
|
||||
ent->client->kick_angles[i] = crandom() * 0.5;
|
||||
}
|
||||
ent->client->kick_origin[0] = crandom() * 0.35;
|
||||
|
||||
// MP5
|
||||
//Calculate the kick angles
|
||||
for (i=1 ; i<3 ; i++)
|
||||
{
|
||||
ent->client->kick_origin[i] = crandom() * 0.25;
|
||||
ent->client->kick_angles[i] = crandom() * 0.5;
|
||||
}
|
||||
ent->client->kick_origin[0] = crandom() * 0.35;
|
||||
|
||||
// SSG3000 has no kick
|
||||
*/
|
||||
|
||||
|
||||
// View kicks -- note this doesn't affect aim which is handled on the server-side
|
||||
// even though it probably should
|
||||
if (ent->clientNum == cg.snap->ps.clientNum)
|
||||
{
|
||||
vec3_t forward;
|
||||
|
||||
switch ( cg.snap->ps.weapon )
|
||||
{
|
||||
case WP_KNIFE:
|
||||
AngleVectors(cg.predictedPlayerState.viewangles, forward, NULL, NULL);
|
||||
VectorScale ( forward, -2, cg.kick_origin );
|
||||
cg.kick_angles[0] = -2;
|
||||
cg.kick_time = cg.time;
|
||||
cg.kick_duration = 200;
|
||||
break;
|
||||
case WP_PISTOL:
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
cg.kick_origin[i] = crandom() * 0.35f;
|
||||
cg.kick_angles[i] = crandom() * 0.7f;
|
||||
}
|
||||
cg.kick_origin[0] = crandom() * 0.35f;
|
||||
cg.kick_time = cg.time;
|
||||
break;
|
||||
case WP_M3:
|
||||
AngleVectors(cg.predictedPlayerState.viewangles, forward, NULL, NULL);
|
||||
VectorScale ( forward, -2, cg.kick_origin );
|
||||
cg.kick_angles[0] = -2;
|
||||
cg.kick_time = cg.time;
|
||||
break;
|
||||
case WP_M4:
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
cg.kick_origin[i] = crandom() * 0.25f;
|
||||
cg.kick_angles[i] = crandom() * 0.5f;
|
||||
}
|
||||
cg.kick_origin[0] = crandom() * 0.35f;
|
||||
cg.kick_time = cg.time;
|
||||
break;
|
||||
case WP_MP5:
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
cg.kick_origin[i] = crandom() * 0.25f;
|
||||
cg.kick_angles[i] = crandom() * 0.5f;
|
||||
}
|
||||
cg.kick_origin[0] = crandom() * 0.35f;
|
||||
cg.kick_time = cg.time;
|
||||
break;
|
||||
case WP_HANDCANNON:
|
||||
AngleVectors(cg.predictedPlayerState.viewangles, forward, NULL, NULL);
|
||||
VectorScale ( forward, -2, cg.kick_origin );
|
||||
cg.kick_angles[0] = -2;
|
||||
cg.kick_time = cg.time;
|
||||
break;
|
||||
case WP_AKIMBO:
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
cg.kick_origin[i] = crandom() * 0.25f;
|
||||
cg.kick_angles[i] = crandom() * 0.5f;
|
||||
}
|
||||
cg.kick_origin[0] = crandom() * 0.35f;
|
||||
cg.kick_time = cg.time;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue