Support for more muzzleflashes

Fixes and cleanups regarding effects, networking
All sorts of other cool things
This commit is contained in:
Marco Cawthorne 2017-01-14 16:00:31 +01:00
parent e67ab0380f
commit bf1adc491a
28 changed files with 680 additions and 99 deletions

View File

@ -182,10 +182,8 @@ Available options:
#define FTE_FORCEINFOKEY /* Provides an easy way to change a user's userinfo from the server. */
#define FTE_GFX_QUAKE3SHADERS /* specifies that the engine has full support for vanilla quake3 shaders */
#define FTE_GFX_REMAPSHADER /* With the raw power of stuffcmds, the r_remapshader console command is exposed! This mystical command can be used to remap any shader to another. Remapped shaders that specify $diffuse etc in some form will inherit the textures implied by the surface. */
#define FTE_GFX_MODELEVENTS /* Provides a query for per-animation events in model files, including from progs/foo.mdl.events files. */
#define FTE_ISBACKBUFFERED /* Allows you to check if a client has too many reliable messages pending. */
#define FTE_MEMALLOC /* Allows dynamically allocating memory. Use pointers to access this memory. Memory will not be saved into saved games. */
#define FTE_MEDIA_AVI /* playfilm command supports avi files. */
#define FTE_MEDIA_CIN /* playfilm command supports q2 cin files. */
#define FTE_MEDIA_ROQ /* playfilm command supports q3 roq files. */
#define FTE_MULTIPROGS /* Multiple progs.dat files can be loaded inside the same qcvm. Insert new ones with addprogs inside the 'init' function, and use externvalue+externset to rewrite globals (and hook functions) to link them together. Note that the result is generally not very clean unless you carefully design for it beforehand. */
@ -1973,10 +1971,14 @@ float(float modidx, string framename) frameforname = #276; /* Part of FTE_CSQC_S
float(float modidx, float framenum) frameduration = #277; /* Part of FTE_CSQC_SKELETONOBJECTS
Retrieves the duration (in seconds) of the specified framegroup. */
float(float modidx, float framenum, __inout float basetime, float targettime, __inout float code, __inout string data) getnextmodelevent = #0:getnextmodelevent; /* Part of FTE_GFX_MODELEVENTS
Reports the next event within a model's animation. Returns a boolean if an event was found between basetime and targettime. Writes to basetime,code,data arguments (if an event was found, basetime is set to the event's time, otherwise to targettime). WARNING: this builtin cannot deal with multiple events with the same timestamp (only the first will be reported). */
void(float modidx, float framenum, __inout float basetime, float targettime, void(float timestamp, int code, string data) callback) processmodelevents = #0:processmodelevents; /*
Calls a callback for each event that has been reached. Basetime is set to targettime. */
float(float modidx, float framenum, int eventidx, __out float timestamp, __out int code, __out string data) getmodeleventidx = #0:getmodeleventidx; /*
float(float modidx, float framenum, __inout float basetime, float targettime, __inout int code, __inout string data) getnextmodelevent = #0:getnextmodelevent; /*
Reports the next event within a model's animation. Returns a boolean if an event was found between basetime and targettime. Writes to basetime,code,data arguments (if an event was found, basetime is set to the event's time, otherwise to targettime).
WARNING: this builtin cannot deal with multiple events with the same timestamp (only the first will be reported). */
float(float modidx, float framenum, int eventidx, __inout float timestamp, __inout int code, __inout string data) getmodeleventidx = #0:getmodeleventidx; /*
Reports an indexed event within a model's animation. Writes to timestamp,code,data arguments on success. Returns false if the animation/event/model was out of range/invalid. Does not consider looping animations (retry from index 0 if it fails and you know that its a looping animation). This builtin is more annoying to use than getnextmodelevent, but can be made to deal with multiple events with the exact same timestamp. */
#endif

View File

@ -45,6 +45,7 @@ var float PARTICLE_PIECES_BLACK;
var float PARTICLE_SMOKE_GREY;
var float PARTICLE_SMOKE_BROWN;
var float PARTICLE_BLOOD;
var float DECAL_SHOT;
vector vHUDColor; // Defined in HUD_Draw (HUD.c)
vector vVGUIColor; // Defined in HUD_Draw (VGUI.c)

View File

@ -56,7 +56,10 @@ weaponiconinfo_t wpIconTable[ CS_WEAPON_COUNT ] = {
{ "sprites/640hud1.spr_0.tga", '0.75 0.5625', '0.1875 0.0625' }, //WEAPON_G3SG1
{ "sprites/640hud16.spr_0.tga", '0.75 0.1875', '0.125 0.0625' }, //WEAPON_SG550
{ "sprites/640hud1.spr_0.tga", '0.75 0.625', '0.1875 0.0625' }, //WEAPON_PARA
{ "", '0 0', '-1 0.0625' } //WEAPON_C4BOMB
{ "", '0 0', '-1 0.0625' }, //WEAPON_C4BOMB
{ "", '0 0', '-1 0.0625' }, //WEAPON_FLASHBANG
{ "", '0 0', '-1 0.0625' }, //WEAPON_HEGRENADE
{ "", '0 0', '-1 0.0625' } //WEAPON_SMOKEGRENADE
};
typedef struct {

View File

@ -48,7 +48,10 @@ weaponsymbolinfo_t wpSymbolTable[ CS_WEAPON_COUNT ] = {
{ "sprites/640hud2.spr_0.tga", '0 0.703125' }, //WEAPON_G3SG1
{ "sprites/640hud14.spr_0.tga", '0 0.703125' }, //WEAPON_SG550
{ "sprites/640hud3.spr_0.tga", '0 0' }, //WEAPON_PARA
{ "sprites/640hud1.spr_0.tga", '0 0' } //WEAPON_C4BOMB
{ "sprites/640hud1.spr_0.tga", '0 0' }, //WEAPON_C4BOMB
{ "sprites/640hud3.spr_0.tga", '0 0.3515625' }, //WEAPON_FLASHBANG
{ "sprites/640hud3.spr_0.tga", '0 0.17578125' }, //WEAPON_HEGRENADE
{ "sprites/640hud3.spr_0.tga", '0 0.52734375' } //WEAPON_SMOKEGRENADE
};
vector vHUDSlotNumPos[ 4 ] = {

View File

@ -51,15 +51,17 @@ void CSQC_Init(float apilevel, string enginename, float engineversion) {
precache_sound( "debris/bustglass1.wav" );
precache_sound( "debris/bustglass2.wav" );
precache_sound( "debris/bustglass3.wav" );
precache_sound( "debris/bustcrate1.wav" );
precache_sound( "debris/bustcrate2.wav" );
precache_sound( "debris/bustcrate3.wav" );
precache_sound( "debris/bustmetal1.wav" );
precache_sound( "debris/bustmetal2.wav" );
precache_sound( "debris/bustflesh1.wav" );
precache_sound( "debris/bustflesh2.wav" );
precache_sound( "debris/bustconcrete1.wav" );
precache_sound( "debris/bustconcrete2.wav" );
precache_sound( "debris/bustceiling1.wav" );
precache_sound( "debris/bustceiling.wav" );
for ( int i = 0; i < ( CS_WEAPON_COUNT - 1 ); i++ ) {
precache_model( sViewModels[ i ] );
@ -74,6 +76,7 @@ void CSQC_Init(float apilevel, string enginename, float engineversion) {
PARTICLE_SMOKE_GREY = particleeffectnum( "part_smoke_grey" );
PARTICLE_SMOKE_BROWN = particleeffectnum( "part_smoke_brown" );
PARTICLE_BLOOD = particleeffectnum( "part_blood" );
DECAL_SHOT = particleeffectnum( "decal_shot1" );
Radio_InitSounds();

View File

@ -42,7 +42,10 @@ string sViewModels[ CS_WEAPON_COUNT - 1 ] = {
"models/v_g3sg1.mdl",
"models/v_sg550.mdl",
"models/v_m249.mdl",
"models/v_c4.mdl"
"models/v_c4.mdl",
"models/v_flashbang.mdl",
"models/v_hegrenade.mdl",
"models/v_smokegrenade.mdl"
};
/*
@ -81,36 +84,67 @@ float View_CalcBob( void ) {
return fBob;
}
entity eViewModel;
entity eMuzzleflash;
float fNumBones;
void View_ProcessEvent( float fTimeStamp, int iCode, string sData ) {
if ( iCode == 5004 ) {
localsound( sData, CHAN_AUTO, 1.0 );
} else if ( iCode == 5001 ) {
eMuzzleflash.alpha = 1.0f;
eMuzzleflash.scale = 0.5;
eMuzzleflash.skin = fNumBones;
setmodel( eMuzzleflash, sprintf( "sprites/muzzleflash%s.spr", substring( sData, 1, 1 ) ) );
} else if( iCode == 5011 ) {
eMuzzleflash.alpha = 1.0f;
eMuzzleflash.scale = 0.5;
eMuzzleflash.skin = fNumBones + 1;
setmodel( eMuzzleflash, sprintf( "sprites/muzzleflash%s.spr", substring( sData, 1, 1 ) ) );
} else if ( iCode == 5021 ) {
eMuzzleflash.alpha = 1.0f;
eMuzzleflash.scale = 0.5;
eMuzzleflash.skin = fNumBones + 2;
setmodel( eMuzzleflash, sprintf( "sprites/muzzleflash%s.spr", substring( sData, 1, 1 ) ) );
} else if ( iCode == 5031 ) {
eMuzzleflash.alpha = 1.0f;
eMuzzleflash.scale = 0.5;
eMuzzleflash.skin = fNumBones + 3;
setmodel( eMuzzleflash, sprintf( "sprites/muzzleflash%s.spr", substring( sData, 1, 1 ) ) );
}
}
void View_DrawViewModel( void ) {
static float fLastTime;
static float fBob;
static float fLastWeapon;
if( !eViewModel ) {
eViewModel = spawn();
eViewModel.renderflags = RF_DEPTHHACK;
eMuzzleflash = spawn();
setmodel( eMuzzleflash, "sprites/muzzleflash1.spr" );
eMuzzleflash.renderflags = RF_DEPTHHACK | RF_ADDITIVE;
}
if ( getstatf( STAT_HEALTH ) <= 0 ) {
return;
}
// Don't update when paused
if ( time != fLastTime ) {
fBob = View_CalcBob();
if( getstatf( STAT_ACTIVEWEAPON ) < CS_WEAPON_COUNT ) {
if ( fLastWeapon != getstatf( STAT_ACTIVEWEAPON ) ) {
setmodel( eViewModel, sViewModels[ getstatf( STAT_ACTIVEWEAPON ) - 1 ] );
eMuzzleflash.skeletonindex = skel_create( eViewModel.modelindex );
eMuzzleflash.skin = skel_get_numbones( eMuzzleflash.skeletonindex ) + 1;
fLastWeapon = getstatf( STAT_ACTIVEWEAPON );
if ( fLastWeapon ) {
setmodel( eViewModel, sViewModels[ getstatf( STAT_ACTIVEWEAPON ) - 1 ] );
skel_delete( eMuzzleflash.skeletonindex );
eMuzzleflash.skeletonindex = skel_create( eViewModel.modelindex );
fNumBones = skel_get_numbones( eMuzzleflash.skeletonindex ) + 1;
}
}
}
@ -120,16 +154,7 @@ void View_DrawViewModel( void ) {
}
static float fBaseTime;
static float fCode;
static string sData ;
getnextmodelevent( eViewModel.modelindex, eViewModel.frame, fBaseTime, eViewModel.frame1time - 0.001, fCode, sData );
if ( fCode == 5004 ) {
localsound( sData, CHAN_AUTO, 1.0 );
} else if ( fCode == 5001 ) {
eMuzzleflash.alpha = 1.0f;
eMuzzleflash.scale = stof( sData ) * 0.01;
}
processmodelevents( eViewModel.modelindex, eViewModel.frame, fBaseTime, eViewModel.frame1time, View_ProcessEvent );
eViewModel.frame1time += frametime;
}

View File

@ -17,8 +17,10 @@ Defs.h
../Shared/WeaponDeagle.c
../Shared/WeaponElites.c
../Shared/WeaponFiveSeven.c
../Shared/WeaponFlashbang.c
../Shared/WeaponG3SG1.c
../Shared/WeaponGlock18.c
../Shared/WeaponHEGrenade.c
../Shared/WeaponKnife.c
../Shared/WeaponM3.c
../Shared/WeaponM4A1.c
@ -30,6 +32,7 @@ Defs.h
../Shared/WeaponScout.c
../Shared/WeaponSG550.c
../Shared/WeaponSG552.c
../Shared/WeaponSmokeGrenade.c
../Shared/WeaponTMP.c
../Shared/WeaponUMP45.c
../Shared/WeaponUSP45.c

View File

@ -76,7 +76,7 @@ enum {
GAME_END
};
#define CS_WEAPON_COUNT 25
#define CS_WEAPON_COUNT 28
enum {
WEAPON_NONE = 0,
WEAPON_KNIFE,
@ -102,7 +102,10 @@ enum {
WEAPON_G3SG1,
WEAPON_SG550,
WEAPON_PARA,
WEAPON_C4BOMB
WEAPON_C4BOMB,
WEAPON_FLASHBANG,
WEAPON_HEGRENADE,
WEAPON_SMOKEGRENADE
};
#define CS_EQUIPMENT_COUNT 7

View File

@ -158,7 +158,7 @@ void Client_SendEvent( entity eClient, float fEVType ) {
WriteByte( MSG_MULTICAST, fEVType );
msg_entity = eClient;
multicast( '0 0 0', MULTICAST_ONE );
multicast( '0 0 0', MULTICAST_ALL );
}
/*
@ -183,5 +183,5 @@ void Client_TriggerCamera( entity eTarget, vector vPos, vector vEndPos, float fR
WriteFloat( MSG_MULTICAST, fResetTime );
msg_entity = eTarget;
multicast( '0 0 0', MULTICAST_ONE );
multicast( '0 0 0', MULTICAST_ALL );
}

View File

@ -73,6 +73,19 @@ string Damage_GetHitLocation( int iSurface ) {
}
}
int Damage_ShouldDamage( float fTargetTeam, float fAttackerTeam ) {
if ( fTargetTeam == TEAM_VIP ) {
fTargetTeam = TEAM_CT;
} else if ( fAttackerTeam == TEAM_VIP ) {
fAttackerTeam = TEAM_CT;
}
if ( fTargetTeam == fAttackerTeam ) {
return FALSE;
}
return TRUE;
}
/*
=================
@ -120,8 +133,14 @@ void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos
}
if ( ( eTarget.flags & FL_CLIENT ) && ( eAttacker.flags & FL_CLIENT ) ) {
eAttacker.frags++;
Money_AddMoney( eAttacker, 300 );
// Don't encourage them to kill their own team members for $$$
if ( Damage_ShouldDamage( eTarget.team, eAttacker.team ) == TRUE ) {
eAttacker.frags++;
Money_AddMoney( eAttacker, 300 );
} else {
eAttacker.frags--;
}
Damage_CastOrbituary( eAttacker, eTarget, eAttacker.weapon, FALSE );
}
}

View File

@ -38,10 +38,27 @@ Spawns a new waypoint for the hostage
entity hostage_waypoint( void ) {
entity ePoint = spawn();
setorigin( ePoint, self.eUser.origin );
//setmodel( ePoint, "models/chick.mdl" ); // Visual feedback...
setsize( ePoint, self.mins, self.maxs );
ePoint.classname = "remove_me";
ePoint.movetype = MOVETYPE_TOSS;
// setmodel( ePoint, "models/chick.mdl" ); // Visual feedback...
return ePoint;
}
/*
=================
hostage_waypoint_needed
Determines when we need to spawn a new waypoint
=================
*/
float hostage_waypoint_needed( void ) {
if ( self.eUser.fStepTime > time ) {
return FALSE;
}
return TRUE;
}
/*
=================
hostage_pain
@ -152,7 +169,7 @@ void hostage_physics( void ) {
self.fAttackFinished = time + 0.1;
// We only ever need to create waypoints when we run
if ( self.fStepTime < time ) {
if ( hostage_waypoint_needed() == TRUE ) {
if ( self.eTargetPoint == self.eUser ) {
// Create the first waypoint
self.eTargetPoint = hostage_waypoint();
@ -176,14 +193,14 @@ void hostage_physics( void ) {
self.frame = 2;
} else {
input_movevalues = '0 0 0';
if ( fTurn > 0 ) {
self.frame = 5;
} else if ( fTurn < 0 ){
self.frame = 6;
} else {
self.frame = 13;
}
}
if ( fTurn > 0.01 ) {
self.frame = 5;
} else if ( fTurn < -0.01 ){
self.frame = 6;
} else {
self.frame = 13;
}
}

View File

@ -18,8 +18,6 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
.float fSteptime;
/*
=================
Footsteps_Update
@ -34,7 +32,7 @@ void Footsteps_Update( void ) {
string sStepSound = "";
if ( ( self.movetype == MOVETYPE_WALK ) && ( self.flags & FL_ONGROUND ) ) {
if ( ( self.velocity_x == 0 && self.velocity_y == 0 ) || self.fSteptime > time ) {
if ( ( self.velocity_x == 0 && self.velocity_y == 0 ) || self.fStepTime > time ) {
return;
}
@ -85,6 +83,6 @@ void Footsteps_Update( void ) {
}
sound( self, CHAN_BODY, sStepSound, 0.5, ATTN_IDLE );
self.fSteptime = time + fDelay;
self.fStepTime = time + fDelay;
}
}

View File

@ -40,38 +40,30 @@ func_breakable_pain
=================
*/
void func_breakable_pain( int iNull ) {
string sTypeSample = "";
int iTypeCount = 0;
switch ( self.material ) {
case MATERIAL_GLASS:
case MATERIAL_COMPUTER:
case MATERIAL_GLASS_UNBREAKABLE:
sTypeSample = "debris/glass";
iTypeCount = 3;
sound( self, CHAN_VOICE, sprintf( "debris/glass%d.wav", random( 1, 4 ) ), 1.0, ATTN_NORM );
break;
case MATERIAL_WOOD:
sTypeSample = "debris/wood";
iTypeCount = 3;
sound( self, CHAN_VOICE, sprintf( "debris/wood%d.wav", random( 1, 4 ) ), 1.0, ATTN_NORM );
break;
case MATERIAL_METAL:
sTypeSample = "debris/metal";
iTypeCount = 3;
sound( self, CHAN_VOICE, sprintf( "debris/metal%d.wav", random( 1, 4 ) ), 1.0, ATTN_NORM );
break;
case MATERIAL_FLESH:
sTypeSample = "debris/flesh";
iTypeCount = 7;
float fRand = floor( random( 1, 8 ) );
if ( fRand == 4 ) { // sigh
fRand = 5;
}
sound( self, CHAN_VOICE, sprintf( "debris/flesh%d.wav", fRand ), 1.0, ATTN_NORM );
break;
case MATERIAL_CINDER:
case MATERIAL_ROCK:
sTypeSample = "debris/concrete";
iTypeCount = 3;
sound( self, CHAN_VOICE, sprintf( "debris/concrete%d.wav", random( 1, 4 ) ), 1.0, ATTN_NORM );
break;
}
if ( iTypeCount >= 1 ) {
sound( self, CHAN_VOICE, sprintf( "%s%d.wav", sTypeSample, floor( random( 1, (float)iTypeCount ) + 1 ) ), 1.0, ATTN_NORM );
}
}
/*

View File

@ -33,10 +33,13 @@ void func_hostage_rescue_touch( void ) {
Money_AddMoney( other.eUser, 1000 );
Money_QueTeamReward( TEAM_CT, 800 );
if ( other.eTargetPoint != other.eUser ) {
remove( other.eTargetPoint );
}
other.eTargetPoint = other.eUser = world;
entity eOld = self;
self = other;
Entities_Remove();

View File

@ -297,7 +297,6 @@ void worldspawn( void ) {
precache_sound( "debris/flesh1.wav" );
precache_sound( "debris/flesh2.wav" );
precache_sound( "debris/flesh3.wav" );
precache_sound( "debris/flesh4.wav" );
precache_sound( "debris/flesh5.wav" );
precache_sound( "debris/flesh6.wav" );
precache_sound( "debris/flesh7.wav" );

257
Source/Server/PhysicsMove.c Normal file
View File

@ -0,0 +1,257 @@
#define movevars_stepheight 22
#define movevars_friction 4
#define movevars_gravity 800
#define movevars_accelerate 10
#define movevars_stopspeed 100
#define movevars_maxspeed 320
#define movevars_jumpheight 270
.float pmove_flags;
.float gravity;
enumflags {
PMF_JUMP_HELD,
PMF_RESERVED,
PMF_ONGROUND
};
static void dotouch( entity tother ) {
entity oself;
if (tother.touch == __NULL__)
return;
oself = self;
other = self;
self = tother;
self.touch();
self = oself;
}
void PhysicsMove_Rebound(vector surfnorm) {
float v;
v = self.velocity*surfnorm;
self.velocity = self.velocity - surfnorm*(v);
}
//move forwards (preferably on the level) (does step ups)
void PhysicsMove_Move(void) {
vector dest;
vector saved_plane_normal;
float stepped;
float movetime;
float attempts;
//we need to bounce off surfaces (in order to slide along them), so we need at 2 attempts
for (attempts = 3, movetime = input_timelength; movetime>0 && attempts; attempts--)
{
dest = self.origin + self.velocity*movetime;
tracebox(self.origin, self.mins, self.maxs, dest, FALSE, self); //try going straight there
self.origin = trace_endpos;
if (trace_fraction < 1)
{
saved_plane_normal = trace_plane_normal;
movetime -= movetime * trace_fraction;
if (movetime)
{
//step up if we can
trace_endpos = self.origin;
trace_endpos_z += movevars_stepheight;
tracebox( self.origin, self.mins, self.maxs, trace_endpos, FALSE, self );
stepped = trace_endpos_z - self.origin_z;
dest = trace_endpos + self.velocity*movetime;
dest_z = trace_endpos_z;
//move forwards
tracebox(trace_endpos, self.mins, self.maxs, dest, FALSE, self);
//if we got anywhere, make this raised-step move count
if (trace_fraction != 0)
{
if (trace_fraction < 1)
PhysicsMove_Rebound(trace_plane_normal);
//move down
dest = trace_endpos;
dest_z -= stepped+1;
tracebox(trace_endpos, self.mins, self.maxs, dest, FALSE, self);
if (trace_fraction < 1)
PhysicsMove_Rebound(trace_plane_normal);
self.origin = trace_endpos;
movetime -= movetime * input_timelength;
continue;
}
}
//stepping failed, just bounce off
PhysicsMove_Rebound(saved_plane_normal);
dotouch(trace_ent);
}
else
break;
}
}
/*
void(vector dest) PhysicsMove_StepMove =
{
//we hit something...
//step up
src = trace_endpos;
trace_endpos_z += movevars_stepheight;
tracebox(src, self.mins, self.maxs, dest, FALSE, self);
stepped = trace_endpos_z - src_z;
dest_z += stepped;
//move forwards
tracebox(trace_endpos, self.mins, self.maxs, dest, FALSE, self);
//move down
dest_z -= stepped;
tracebox(trace_endpos, self.mins, self.maxs, dest, FALSE, self);
}
*/
void PhysicsMove_ApplyFriction( void ) {
float newspeed, oldspeed;
oldspeed = vlen(self.velocity);
if (oldspeed < 1)
{
self.velocity = '0 0 0';
return;
}
//calculate what their new speed should be
newspeed = oldspeed - oldspeed*movevars_friction*input_timelength;
//and slow them
if (newspeed < 0)
newspeed = 0;
self.velocity = self.velocity * (newspeed/oldspeed);
}
void PhysicsMove_Accelerate(vector wishdir, float wishspeed, float accel) {
float addspeed, accelspeed;
float d;
d = self.velocity*wishdir;
addspeed = wishspeed - (d);
if (addspeed <= 0)
return;
accelspeed = accel*input_timelength*wishspeed;
if (accelspeed > addspeed)
accelspeed = addspeed;
self.velocity = self.velocity + accelspeed*wishdir;
}
void PhysicsMove_InAirAccelerate( void ) {
vector hforward;
vector hright;
vector desireddir;
float desiredspeed;
hforward = v_forward;
hforward_z = 0;
hforward = normalize(hforward);
hright = v_right;
hright_z = 0;
hright = normalize(hright);
desireddir = hforward*input_movevalues_x + hright*input_movevalues_y;
desiredspeed = vlen(desireddir);
desireddir = normalize(desireddir);
if (desiredspeed > movevars_maxspeed)
desiredspeed = movevars_maxspeed;
if (self.pmove_flags & PMF_ONGROUND)
{
if (input_buttons & 2)
{
if (!(self.pmove_flags & PMF_JUMP_HELD))
{
self.velocity_z += movevars_jumpheight;
self.pmove_flags (+) PMF_ONGROUND;
}
}
}
if (self.pmove_flags & PMF_ONGROUND)
{
PhysicsMove_ApplyFriction();
PhysicsMove_Accelerate(desireddir, desiredspeed, movevars_accelerate);
}
else
{
//there's no friction in air...
if (desiredspeed > 30)
desiredspeed = 30;
PhysicsMove_Accelerate(desireddir, desiredspeed, movevars_accelerate);
if (self.gravity)
self.velocity_z -= self.gravity * movevars_gravity * input_timelength;
else
self.velocity_z -= movevars_gravity * input_timelength;
}
}
void PhysicsMove_NoclipAccelerate( void ) {
vector desireddir;
float desiredspeed;
desireddir = v_forward*input_movevalues_x + v_right*input_movevalues_y+v_up*input_movevalues_z;
desiredspeed = vlen(desireddir);
desireddir = normalize(desireddir);
PhysicsMove_ApplyFriction();
PhysicsMove_Accelerate(desireddir, desiredspeed, movevars_accelerate);
}
void PhysicsMove_Categorise( void ) {
//if we're moving up, we're not on the ground
if (self.velocity_z > 0)
self.pmove_flags (-) PMF_ONGROUND;
else
{
//don't know, maybe we are, maybe we're not
tracebox(self.origin, self.mins, self.maxs, self.origin-'0 0 1', FALSE, self);
if (trace_fraction == 1 || trace_plane_normal_z < 0.7) {
self.pmove_flags (-) PMF_ONGROUND;
// self.groundentity = trace_ent;
}
else
self.pmove_flags (+) PMF_ONGROUND;
}
}
void PhysicsMove( entity eEnt ) {
self = eEnt;
makevectors(input_angles);
if (!(input_buttons & PMF_JUMP_HELD))
self.pmove_flags (-) PMF_JUMP_HELD;
PhysicsMove_Categorise();
switch ( self.movetype ) {
case MOVETYPE_WALK:
PhysicsMove_InAirAccelerate();
PhysicsMove_Move();
break;
case MOVETYPE_FLY:
PhysicsMove_NoclipAccelerate();
PhysicsMove_Move();
break;
case MOVETYPE_NOCLIP:
PhysicsMove_NoclipAccelerate();
self.origin += self.velocity*input_timelength;
break;
case MOVETYPE_NONE:
break;
}
}

View File

@ -83,6 +83,9 @@ void Player_Death( int iHitBody ) {
eCorpse.angles = [ 0, self.angles_y, 0 ];
eCorpse.movetype = MOVETYPE_BOUNCE;
// Make ourselves disappear
self.modelindex = 0;
if ( self.flags & FL_CROUCHING ) {
eCorpse.frame = ANIM_CROUCH_DIE;
} else {
@ -124,13 +127,19 @@ void Player_Death( int iHitBody ) {
return;
}
if ( ( iAlivePlayers_T == 0 ) && ( iAlivePlayers_CT == 0 ) && ( iBombPlanted == FALSE ) ) {
Rules_RoundOver( FALSE, 3600, FALSE );
if ( ( iAlivePlayers_T == 0 ) && ( iAlivePlayers_CT == 0 ) ) {
if ( ( iBombPlanted == FALSE ) || ( iBombZones > 0 ) ) {
Rules_RoundOver( FALSE, 3600, FALSE );
} else {
Rules_RoundOver( TEAM_T, 3600, FALSE );
}
} else {
// If the bomb has been planted, T deaths don't matter anymore
if ( ( iAlivePlayers_T == 0 ) && ( iBombPlanted == FALSE ) ) {
Rules_RoundOver( TEAM_CT, 3600, FALSE );
} else if ( iAlivePlayers_CT == 0 ) {
if ( ( self.team == TEAM_T ) && ( iAlivePlayers_T == 0 ) ) {
if ( ( iBombPlanted == FALSE ) || ( iBombZones == 0 ) ) {
Rules_RoundOver( TEAM_CT, 3600, FALSE );
}
} else if ( ( self.team == TEAM_CT ) && ( iAlivePlayers_CT == 0 ) ) {
Rules_RoundOver( TEAM_T, 3600, FALSE );
}
}
@ -237,7 +246,7 @@ void Player_UseDown( void ) {
if ( trace_ent.iUsable ) {
if ( ( trace_ent.classname != "c4bomb" ) && ( trace_ent.classname != "func_pushable" ) ) {
self.flags = ( self.flags - FL_USERELEASED );
sound( self, CHAN_WEAPON, "common/wpn_select.wav", 0.25, ATTN_IDLE );
sound( self, CHAN_ITEM, "common/wpn_select.wav", 0.25, ATTN_IDLE );
}
eActivator = self;
@ -246,7 +255,7 @@ void Player_UseDown( void ) {
self.vUse();
self = eOriginalSelf;
} else {
sound( self, CHAN_WEAPON, "common/wpn_denyselect.wav", 0.25, ATTN_IDLE );
sound( self, CHAN_ITEM, "common/wpn_denyselect.wav", 0.25, ATTN_IDLE );
self.flags = ( self.flags - FL_USERELEASED );
}
}

View File

@ -11,6 +11,7 @@ Defs.h
Money.c
Animations.c
PhysicsMove.c
../Shared/Radio.c
../Shared/WeaponAK47.c
../Shared/WeaponAUG.c
@ -19,8 +20,10 @@ Animations.c
../Shared/WeaponDeagle.c
../Shared/WeaponElites.c
../Shared/WeaponFiveSeven.c
../Shared/WeaponFlashbang.c
../Shared/WeaponG3SG1.c
../Shared/WeaponGlock18.c
../Shared/WeaponHEGrenade.c
../Shared/WeaponKnife.c
../Shared/WeaponM3.c
../Shared/WeaponM4A1.c
@ -32,6 +35,7 @@ Animations.c
../Shared/WeaponScout.c
../Shared/WeaponSG550.c
../Shared/WeaponSG552.c
../Shared/WeaponSmokeGrenade.c
../Shared/WeaponTMP.c
../Shared/WeaponUMP45.c
../Shared/WeaponUSP45.c

View File

@ -61,6 +61,7 @@ void Effect_Impact( int iType, vector vPos, vector vNormal ) {
switch ( iType ) {
case IMPACT_MELEE:
pointparticles( DECAL_SHOT, vPos, vNormal, 1 );
pointparticles( PARTICLE_PIECES_BLACK, vPos, vNormal, 1 );
pointsound( vPos, "weapons/knife_hitwall1.wav", 1, ATTN_STATIC );
break;
@ -70,11 +71,13 @@ void Effect_Impact( int iType, vector vPos, vector vNormal ) {
pointparticles( PARTICLE_PIECES_BLACK, vPos, vNormal, 1 );
break;
case IMPACT_WOOD:
pointparticles( DECAL_SHOT, vPos, vNormal, 1 );
pointparticles( PARTICLE_SPARK, vPos, vNormal, 1 );
pointparticles( PARTICLE_PIECES_BLACK, vPos, vNormal, 1 );
pointparticles( PARTICLE_SMOKE_BROWN, vPos, vNormal, 1 );
break;
case IMPACT_METAL:
pointparticles( DECAL_SHOT, vPos, vNormal, 1 );
pointparticles( PARTICLE_SPARK, vPos, vNormal, 1 );
pointparticles( PARTICLE_SPARK, vPos, vNormal, 1 );
pointparticles( PARTICLE_PIECES_BLACK, vPos, vNormal, 1 );
@ -83,6 +86,7 @@ void Effect_Impact( int iType, vector vPos, vector vNormal ) {
pointparticles( PARTICLE_BLOOD, vPos, vNormal, 1 );
break;
case IMPACT_DEFAULT:
pointparticles( DECAL_SHOT, vPos, vNormal, 1 );
pointparticles( PARTICLE_SPARK, vPos, vNormal, 1 );
pointparticles( PARTICLE_PIECES_BLACK, vPos, vNormal, 1 );
pointparticles( PARTICLE_SMOKE_GREY, vPos, vNormal, 1 );
@ -126,10 +130,10 @@ void Effect_BreakModel( vector vMins, vector vMaxs, vector vVel, float fStyle )
#else
static void Effect_BreakModel_Remove( void ) { remove( self ) ; }
float fCount = 20; // TODO: Generate gibcount based around size
float fModelCount;
vector vPos;
string sModel = "";
float fCount = 20;
switch ( fStyle ) {
case MATERIAL_GLASS:
@ -168,47 +172,34 @@ void Effect_BreakModel( vector vMins, vector vMaxs, vector vVel, float fStyle )
break;
}
string sTypeSample = "";
int iTypeCount;
vector vWorldPos;
vWorldPos_x = vMins_x + ( 0.5 * ( vMaxs_x - vMins_x ) );
vWorldPos_y = vMins_y + ( 0.5 * ( vMaxs_y - vMins_y ) );
vWorldPos_z = vMins_z + ( 0.5 * ( vMaxs_z - vMins_z ) );
switch ( fStyle ) {
case MATERIAL_GLASS:
case MATERIAL_GLASS_UNBREAKABLE:
sTypeSample = "debris/bustglass";
iTypeCount = 2;
pointsound( vWorldPos, sprintf( "debris/bustglass%d.wav", random( 1, 4 ) ), 1.0f, ATTN_NORM );
break;
case MATERIAL_WOOD:
sTypeSample = "debris/bustcrate";
iTypeCount = 2;
pointsound( vWorldPos, sprintf( "debris/bustcrate%d.wav", random( 1, 4 ) ), 1.0f, ATTN_NORM );
break;
case MATERIAL_METAL:
case MATERIAL_COMPUTER:
sTypeSample = "debris/bustmetal";
iTypeCount = 2;
pointsound( vWorldPos, sprintf( "debris/bustmetal%d.wav", random( 1, 3 ) ), 1.0f, ATTN_NORM );
break;
case MATERIAL_FLESH:
sTypeSample = "debris/bustflesh";
iTypeCount = 2;
pointsound( vWorldPos, sprintf( "debris/bustflesh%d.wav", random( 1, 3 ) ), 1.0f, ATTN_NORM );
break;
case MATERIAL_CINDER:
case MATERIAL_ROCK:
sTypeSample = "debris/bustconcrete";
iTypeCount = 2;
pointsound( vWorldPos, sprintf( "debris/bustconcrete%d.wav", random( 1, 4 ) ), 1.0f, ATTN_NORM );
break;
case MATERIAL_TILE:
sTypeSample = "debris/bustceiling";
iTypeCount = 1;
pointsound( vWorldPos, "debris/bustceiling.wav", 1.0f, ATTN_NORM );
break;
}
if ( iTypeCount > 0 ) {
vector vWorldPos;
vWorldPos_x = vMins_x + ( 0.5 * ( vMaxs_x - vMins_x ) );
vWorldPos_y = vMins_y + ( 0.5 * ( vMaxs_y - vMins_y ) );
vWorldPos_z = vMins_z + ( 0.5 * ( vMaxs_z - vMins_z ) );
pointsound( vWorldPos, sprintf( "%s%d.wav", sTypeSample, floor( random( 1, (float)iTypeCount ) + 1 ) ), 1.0f, ATTN_NORM );
}
while ( fCount > 0 ) {
entity eGib = spawn();

View File

@ -43,7 +43,10 @@ weaponinfo_t wptTable[ CS_WEAPON_COUNT ] = {
wptG3SG1,
wptSG550,
wptPARA,
wptC4BOMB
wptC4BOMB,
wptFLASHBANG,
wptHEGRENADE,
wptSMOKEGRENADE
};
#ifdef SSQC

View File

@ -0,0 +1,74 @@
/*
OpenCS Project
Copyright (C) 2016, 2017 Marco "eukara" Hladik
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
.int iMag_GLOCK18;
// Weapon Info
weaponinfo_t wptFLASHBANG = {
WEAPON_FLASHBANG, // Identifier
SLOT_GRENADE, // Slot
0, // Price
0, // Caliber ID
1.0, // Max Player Speed
1, // Bullets Per Shot
1, // Clip/MagSize
50, // Damage Per Bullet
1, // Penetration Multiplier
64, // Bullet Range
0.75, // Range Modifier
TYPE_SEMI, // Firing Type
1.0, // Attack-Delay
1.0, // Reload-Delay
iAmmo_9MM, // Caliber Pointer
iMag_GLOCK18, // Clip Pointer
1, // Accuracy Divisor
1.0, // Accuracy Offset
1.0, // Max Inaccuracy
7, // Minimum Crosshair Distance
3, // Crosshair Movement Delta
1.0, // Armor penetration ratio
ATYPE_GRENADE // Animation Type
};
// Anim Table
enum {
ANIM_FLASHBANG_IDLE1,
ANIM_FLASHBANG_PULLPIN,
ANIM_FLASHBANG_THROW,
ANIM_FLASHBANG_DRAW,
};
void WeaponFLASHBANG_Draw( void ) {
#ifdef SSQC
BaseMelee_Draw();
#else
View_PlayAnimation( ANIM_FLASHBANG_DRAW );
#endif
}
void WeaponFLASHBANG_PrimaryFire( void ) {
#ifdef SSQC
Client_SendEvent( self, EV_WEAPON_PRIMARYATTACK );
Animation_ShootWeapon();
self.fAttackFinished = time + wptFLASHBANG.fAttackFinished;
#else
View_PlayAnimation( ANIM_FLASHBANG_PULLPIN );
#endif
}

View File

@ -0,0 +1,74 @@
/*
OpenCS Project
Copyright (C) 2016, 2017 Marco "eukara" Hladik
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
.int iMag_HEGRENADE;
// Weapon Info
weaponinfo_t wptHEGRENADE = {
WEAPON_HEGRENADE, // Identifier
SLOT_GRENADE, // Slot
0, // Price
0, // Caliber ID
1.0, // Max Player Speed
1, // Bullets Per Shot
1, // Clip/MagSize
50, // Damage Per Bullet
1, // Penetration Multiplier
64, // Bullet Range
0.75, // Range Modifier
TYPE_SEMI, // Firing Type
1.0, // Attack-Delay
1.0, // Reload-Delay
iAmmo_9MM, // Caliber Pointer
iMag_HEGRENADE, // Clip Pointer
1, // Accuracy Divisor
1.0, // Accuracy Offset
1.0, // Max Inaccuracy
7, // Minimum Crosshair Distance
3, // Crosshair Movement Delta
1.0, // Armor penetration ratio
ATYPE_GRENADE // Animation Type
};
// Anim Table
enum {
ANIM_HEGRENADE_IDLE1,
ANIM_HEGRENADE_PULLPIN,
ANIM_HEGRENADE_THROW,
ANIM_HEGRENADE_DRAW,
};
void WeaponHEGRENADE_Draw( void ) {
#ifdef SSQC
BaseMelee_Draw();
#else
View_PlayAnimation( ANIM_HEGRENADE_DRAW );
#endif
}
void WeaponHEGRENADE_PrimaryFire( void ) {
#ifdef SSQC
Client_SendEvent( self, EV_WEAPON_PRIMARYATTACK );
Animation_ShootWeapon();
self.fAttackFinished = time + wptHEGRENADE.fAttackFinished;
#else
View_PlayAnimation( ANIM_HEGRENADE_PULLPIN );
#endif
}

View File

@ -0,0 +1,74 @@
/*
OpenCS Project
Copyright (C) 2016, 2017 Marco "eukara" Hladik
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
.int iMag_SMOKEGRENADE;
// Weapon Info
weaponinfo_t wptSMOKEGRENADE = {
WEAPON_SMOKEGRENADE, // Identifier
SLOT_GRENADE, // Slot
0, // Price
0, // Caliber ID
1.0, // Max Player Speed
1, // Bullets Per Shot
1, // Clip/MagSize
50, // Damage Per Bullet
1, // Penetration Multiplier
64, // Bullet Range
0.75, // Range Modifier
TYPE_SEMI, // Firing Type
1.0, // Attack-Delay
1.0, // Reload-Delay
iAmmo_9MM, // Caliber Pointer
iMag_SMOKEGRENADE, // Clip Pointer
1, // Accuracy Divisor
1.0, // Accuracy Offset
1.0, // Max Inaccuracy
7, // Minimum Crosshair Distance
3, // Crosshair Movement Delta
1.0, // Armor penetration ratio
ATYPE_GRENADE // Animation Type
};
// Anim Table
enum {
ANIM_SMOKEGRENADE_IDLE1,
ANIM_SMOKEGRENADE_PULLPIN,
ANIM_SMOKEGRENADE_THROW,
ANIM_SMOKEGRENADE_DRAW,
};
void WeaponSMOKEGRENADE_Draw( void ) {
#ifdef SSQC
BaseMelee_Draw();
#else
View_PlayAnimation( ANIM_SMOKEGRENADE_DRAW );
#endif
}
void WeaponSMOKEGRENADE_PrimaryFire( void ) {
#ifdef SSQC
Client_SendEvent( self, EV_WEAPON_PRIMARYATTACK );
Animation_ShootWeapon();
self.fAttackFinished = time + wptSMOKEGRENADE.fAttackFinished;
#else
View_PlayAnimation( ANIM_SMOKEGRENADE_PULLPIN );
#endif
}

View File

@ -46,7 +46,10 @@ string sWeaponModels[ CS_WEAPON_COUNT ] = {
"models/w_g3sg1.mdl",
"models/w_sg550.mdl",
"models/w_m249.mdl",
"models/w_c4.mdl"
"models/w_c4.mdl",
"models/w_flashbang.mdl",
"models/w_hegrenade.mdl",
"models/w_smokegrenade.mdl"
};
#endif
@ -80,7 +83,10 @@ weaponfunc_t wpnFuncTable[ CS_WEAPON_COUNT ] = {
{ WeaponG3SG1_Draw, WeaponG3SG1_PrimaryFire, WeaponG3SG1_SecondaryFire, WeaponG3SG1_Reload },
{ WeaponSG550_Draw, WeaponSG550_PrimaryFire, WeaponSG550_SecondaryFire, WeaponSG550_Reload },
{ WeaponPARA_Draw, WeaponPARA_PrimaryFire, Temp_Nothing, WeaponPARA_Reload },
{ WeaponC4BOMB_Draw, WeaponC4BOMB_PrimaryFire, Temp_Nothing, Temp_Nothing }
{ WeaponC4BOMB_Draw, WeaponC4BOMB_PrimaryFire, Temp_Nothing, Temp_Nothing },
{ WeaponFLASHBANG_Draw, WeaponFLASHBANG_PrimaryFire, Temp_Nothing, Temp_Nothing },
{ WeaponHEGRENADE_Draw, WeaponHEGRENADE_PrimaryFire, Temp_Nothing, Temp_Nothing },
{ WeaponFLASHBANG_Draw, WeaponFLASHBANG_PrimaryFire, Temp_Nothing, Temp_Nothing }
};
/*

Binary file not shown.

Binary file not shown.

View File

@ -89,3 +89,21 @@ r_part part_blood
friction 0.3
gravity 800
}
r_part decal_shot1
{
type decal
blend premul_subtract
texture "particles/decal_shot"
tcoords 0 0 0.125 1 1 8 0.125
rgbf 1 1 1
alpha 1
alphadelta -0.05
scale 8 8
scalefactor 1
stretchfactor 1
die 20 20
orgwrand 6 6 6
randomvel 0 0 0
rotationstart -180 180
}

Binary file not shown.