Hit-location based death animations

Fix related to shotguns having an insane accuracy
This commit is contained in:
Marco Cawthorne 2017-01-08 15:11:34 +01:00
parent 9a46190fbd
commit 427e2d300d
13 changed files with 101 additions and 55 deletions

View file

@ -170,7 +170,6 @@ void HUD_DrawWeaponSelect_Forward( void ) {
fHUDWeaponSelected = HUD_DrawWeaponSelect_GetWeapon( HUD_DrawWeaponSelect_NextItem( wptTable[ fHUDWeaponSelected ].iSlot ) ); fHUDWeaponSelected = HUD_DrawWeaponSelect_GetWeapon( HUD_DrawWeaponSelect_NextItem( wptTable[ fHUDWeaponSelected ].iSlot ) );
} }
print( sprintf( "Selected %f\n", fHUDWeaponSelected ) );
fHUDWeaponSelectTime = time + 3; fHUDWeaponSelectTime = time + 3;
} }

View file

@ -26,6 +26,11 @@ Comparable to worldspawn in SSQC in that it's mostly used for precaches
================= =================
*/ */
void CSQC_Init(float apilevel, string enginename, float engineversion) { void CSQC_Init(float apilevel, string enginename, float engineversion) {
//static float PlayerFrame( float fIsNew ) {
// self.basebone = 40;
// return TRUE;
//}
precache_model( HUD_NUMFILE ); precache_model( HUD_NUMFILE );
precache_model( "sprites/radar640.spr" ); precache_model( "sprites/radar640.spr" );
precache_model( "sprites/640hud1.spr" ); precache_model( "sprites/640hud1.spr" );
@ -46,12 +51,16 @@ void CSQC_Init(float apilevel, string enginename, float engineversion) {
precache_model( sViewModels[ i ] ); precache_model( sViewModels[ i ] );
} }
//for( int i = 1; i < 9; i++ ) {
// deltalisten( sCSPlayers[ i ], PlayerFrame, 0);
//}
PARTICLE_SPARK = particleeffectnum( "part_spark" ); PARTICLE_SPARK = particleeffectnum( "part_spark" );
PARTICLE_PIECES_BLACK = particleeffectnum( "part_pieces_black" ); PARTICLE_PIECES_BLACK = particleeffectnum( "part_pieces_black" );
PARTICLE_SMOKE_GREY = particleeffectnum( "part_smoke_grey" ); PARTICLE_SMOKE_GREY = particleeffectnum( "part_smoke_grey" );
PARTICLE_SMOKE_BROWN = particleeffectnum( "part_smoke_brown" ); PARTICLE_SMOKE_BROWN = particleeffectnum( "part_smoke_brown" );
PARTICLE_BLOOD = particleeffectnum( "part_blood" ); PARTICLE_BLOOD = particleeffectnum( "part_blood" );
Radio_InitSounds(); Radio_InitSounds();
CSQC_ConsoleCommand_Init(); CSQC_ConsoleCommand_Init();

View file

@ -1,6 +1,6 @@
/* /*
OpenCS Project OpenCS Project
Copyright (C) 2015 Marco "eukara" Hladik Copyright (C) 2016, 2017 Marco "eukara" Hladik
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
@ -22,6 +22,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PLAYER_SENDFLAG_UPDATE 1 #define PLAYER_SENDFLAG_UPDATE 1
#define PLAYER_SENDFLAG_INGAME 2 #define PLAYER_SENDFLAG_INGAME 2
string sCSPlayers[9] = {
"",
"models/player/terror/terror.mdl",
"models/player/leet/leet.mdl",
"models/player/arctic/arctic.mdl",
"models/player/guerilla/guerilla.mdl",
"models/player/urban/urban.mdl",
"models/player/gsg9/gsg9.mdl",
"models/player/sas/sas.mdl",
"models/player/gign/gign.mdl"
};
// Stuff that applies to all codebases // Stuff that applies to all codebases
enum { enum {
TEAM_SPECTATOR, TEAM_SPECTATOR,

View file

@ -1,6 +1,6 @@
/* /*
OpenCS Project OpenCS Project
Copyright (C) 2015 Marco "eukara" Hladik Copyright (C) 2016, 2017 Marco "eukara" Hladik
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License

View file

@ -18,6 +18,8 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
.float baseframe_time;
enum { enum {
ANIM_DUMMY1, ANIM_DUMMY1,
ANIM_IDLE, ANIM_IDLE,
@ -117,9 +119,11 @@ enum {
}; };
void Animation_PlayerUpdate( void ) { void Animation_PlayerUpdate( void ) {
self.basebone = 40;
// self.basebone = 40; if ( self.baseframe_time < time ) {
// self.baseframe = ANIM_AIM_SHOTGUN; self.baseframe = ANIM_AIM_SHOTGUN;
}
if ( vlen( self.velocity ) == 0 ) { if ( vlen( self.velocity ) == 0 ) {
if ( self.flags & FL_CROUCHING ) { if ( self.flags & FL_CROUCHING ) {
@ -145,3 +149,8 @@ void Animation_PlayerUpdate( void ) {
self.frame = ANIM_JUMP; self.frame = ANIM_JUMP;
} }
} }
void Animation_PlayerTop( float fFrame, float fTime ) {
self.baseframe = fFrame;
self.baseframe_time = time + fTime;
}

View file

@ -82,7 +82,7 @@ void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos
iDamage *= 0.4; iDamage *= 0.4;
} }
bprint( sprintf( "[DEBUG] Hit Bodypart: %s\n", Damage_GetHitLocation( trace_surface_id ) ) ); dprint( sprintf( "[DEBUG] Hit Bodypart: %s\n", Damage_GetHitLocation( trace_surface_id ) ) );
// Target is dead and a client.... // Target is dead and a client....
if ( eTarget.health <= 0 ) { if ( eTarget.health <= 0 ) {
@ -103,19 +103,9 @@ void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos
if ( self.health <= 0 ) { if ( self.health <= 0 ) {
self.health = 0; self.health = 0;
self.vDeath(); self.vDeath( trace_surface_id );
// Make a cooky death sound
if ( self.classname == "player" ) {
if ( trace_surface_id == BODY_HEAD ) {
sound( self, CHAN_VOICE, sprintf( "player/headshot%d.wav", floor( ( random() * 3 ) + 1 ) ), 1, ATTN_NORM );
} else {
sound( self, CHAN_VOICE, sprintf( "player/die%d.wav", floor( ( random() * 3 ) + 1 ) ), 1, ATTN_NORM );
}
}
} else { } else {
self.vPain(); self.vPain( trace_surface_id );
} }
self = eOld; self = eOld;
@ -127,14 +117,14 @@ void Damage_Radius( vector vOrigin, entity eAttacker, float fDamage, float fRadi
while( eDChain ) { while( eDChain ) {
if ( eDChain.takedamage == DAMAGE_YES ) { if ( eDChain.takedamage == DAMAGE_YES ) {
float fDiff = vlen( vOrigin - eDChain.origin ); float fDiff = vlen( vOrigin - eDChain.origin );
fDiff = ( fRadius - fDiff ) / fRadius; fDiff = ( fRadius - fDiff ) / fRadius;
fDamage = fDamage * fDiff; fDamage = fDamage * fDiff;
if ( fDiff > 0 ) { if ( fDiff > 0 ) {
Damage_Apply( eDChain, eAttacker, fDamage, eDChain.origin ); Damage_Apply( eDChain, eAttacker, fDamage, eDChain.origin );
} }
} }
eDChain = eDChain.chain; eDChain = eDChain.chain;

View file

@ -92,8 +92,8 @@ int iBombPlanted;
// Generic entity fields // Generic entity fields
.int iUsable; .int iUsable;
.int iBleeds; .int iBleeds;
.void() vPain; .void( int iHitBody ) vPain;
.void() vDeath; .void( int iHitBody ) vDeath;
.float fRespawns; .float fRespawns;
.entity eUser; .entity eUser;
@ -108,18 +108,6 @@ entity eActivator;
.float renderamt; .float renderamt;
.float alpha; .float alpha;
string sCSPlayers[9] = {
"",
"models/player/terror/terror.mdl",
"models/player/leet/leet.mdl",
"models/player/arctic/arctic.mdl",
"models/player/guerilla/guerilla.mdl",
"models/player/urban/urban.mdl",
"models/player/gsg9/gsg9.mdl",
"models/player/sas/sas.mdl",
"models/player/gign/gign.mdl"
};
void Rules_RoundOver( int iTeamWon, int iMoneyReward, float fSilent ); void Rules_RoundOver( int iTeamWon, int iMoneyReward, float fSilent );
float Rules_BuyingPossible( void ); float Rules_BuyingPossible( void );
void Timer_Begin( float fTime, float fMode); void Timer_Begin( float fTime, float fMode);

View file

@ -37,14 +37,15 @@ entity hostage_waypoint( void ) {
} }
// Called whenver a hostage is shot // Called whenver a hostage is shot
void hostage_pain( void ) { void hostage_pain( int iHitBody ) {
self.frame = 13 - floor( random( 1, 6 ) ); self.frame = 13 - floor( random( 1, 6 ) );
} }
// hosdown.wav // hosdown.wav
void hostage_die( void ) { void hostage_die( int iHitBody ) {
Radio_BroadcastMessage( RADIO_HOSDOWN ); Radio_BroadcastMessage( RADIO_HOSDOWN );
self.frame = 30 + floor( random( 1, 6 ) ); self.frame = 30 + floor( random( 1, 6 ) );
self.solid = SOLID_NOT; self.solid = SOLID_NOT;
self.takedamage = DAMAGE_NO; self.takedamage = DAMAGE_NO;
//skel_delete( self.skeletonindex ); //skel_delete( self.skeletonindex );

View file

@ -19,7 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
// Entity information from http://twhl.info/wiki.php?id=164 // Entity information from http://twhl.info/wiki.php?id=164
/* /*
Flags Flags
@ -37,7 +36,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
.float material; .float material;
// Whenever it gets damaged // Whenever it gets damaged
void func_breakable_pain( void ) { void func_breakable_pain( int iNull ) {
string sTypeSample = ""; string sTypeSample = "";
int iTypeCount = 0; int iTypeCount = 0;
@ -73,7 +72,7 @@ void func_breakable_pain( void ) {
} }
// Whenever it.. dies // Whenever it.. dies
void func_breakable_die( void ) { void func_breakable_die( int iNull ) {
string sTypeSample = ""; string sTypeSample = "";
int iTypeCount = 0; int iTypeCount = 0;
@ -116,6 +115,10 @@ void func_breakable_die( void ) {
Entities_Remove(); Entities_Remove();
} }
static void func_breakable_use( void ) {
func_breakable_die( 0 );
}
void func_breakable_touch( void ) { void func_breakable_touch( void ) {
static void func_breakable_touch_NULL( void ) { } static void func_breakable_touch_NULL( void ) { }
@ -124,24 +127,23 @@ void func_breakable_touch( void ) {
} }
if ( self.spawnflags & SF_TOUCH ) { if ( self.spawnflags & SF_TOUCH ) {
int fDamage = (float)(vlen( self.velocity ) * 0.01); int fDamage = (float)(vlen( self.velocity ) * 0.01f );
if ( fDamage >= self.health ) { if ( fDamage >= self.health ) {
self.touch = func_breakable_touch_NULL; self.touch = func_breakable_touch_NULL;
Damage_Apply( self, other, fDamage, self.absmin ); Damage_Apply( self, other, fDamage, self.absmin );
if ( self.material == MATERIAL_GLASS || self.material == MATERIAL_COMPUTER ) { if ( ( self.material == MATERIAL_GLASS ) || ( self.material == MATERIAL_COMPUTER ) ) {
Damage_Apply( other, self, fDamage/4, other.origin ); Damage_Apply( other, self, fDamage / 4, other.origin );
} }
} }
} }
if ( ( self.spawnflags & SF_PRESSURE ) && other.absmin_z >= self.maxs_z - 2 ) { if ( ( self.spawnflags & SF_PRESSURE ) && other.absmin_z >= self.maxs_z - 2 ) {
self.think = func_breakable_die; self.think = func_breakable_use;
if ( self.delay == 0 ) { if ( self.delay == 0 ) {
self.delay = 0.1; self.delay = 0.1f;
} }
self.nextthink = self.ltime + self.delay; self.nextthink = self.ltime + self.delay;
@ -170,7 +172,7 @@ void func_breakable( void ) {
self.touch = func_breakable_touch; self.touch = func_breakable_touch;
} }
self.vUse = func_breakable_die; self.vUse = func_breakable_use;
} }
func_wall(); func_wall();

View file

@ -46,12 +46,24 @@ string sPainSounds[5] = {
"player/pl_pain7.wav" "player/pl_pain7.wav"
}; };
void Player_Pain( void ) { void Player_Pain( int iHitBody ) {
if ( iHitBody == BODY_HEAD ) {
Animation_PlayerTop( ANIM_HEAD_FLINCH, 0.1f );
} else {
Animation_PlayerTop( ANIM_GUT_FLINCH, 0.1f );
}
sound( self, CHAN_VOICE, sPainSounds[ floor( random() * 5 ) ], 1, ATTN_IDLE ); sound( self, CHAN_VOICE, sPainSounds[ floor( random() * 5 ) ], 1, ATTN_IDLE );
self.velocity = '0 0 0'; self.velocity = '0 0 0';
} }
void Player_Death( void ) { void Player_Death( int iHitBody ) {
if ( iHitBody == BODY_HEAD ) {
sound( self, CHAN_VOICE, sprintf( "player/headshot%d.wav", floor( ( random() * 3 ) + 1 ) ), 1, ATTN_NORM );
} else {
sound( self, CHAN_VOICE, sprintf( "player/die%d.wav", floor( ( random() * 3 ) + 1 ) ), 1, ATTN_NORM );
}
// Drop a corpse // Drop a corpse
entity eCorpse = spawn(); entity eCorpse = spawn();
setorigin( eCorpse, self.origin ); setorigin( eCorpse, self.origin );
@ -59,7 +71,31 @@ void Player_Death( void ) {
setsize( eCorpse, self.mins, self.maxs ); setsize( eCorpse, self.mins, self.maxs );
eCorpse.angles = [ 0, self.angles_y, 0 ]; eCorpse.angles = [ 0, self.angles_y, 0 ];
eCorpse.movetype = MOVETYPE_BOUNCE; eCorpse.movetype = MOVETYPE_BOUNCE;
eCorpse.frame = 93; // TODO: Pick the right frame
if ( self.flags & FL_CROUCHING ) {
eCorpse.frame = ANIM_CROUCH_DIE;
} else {
switch ( iHitBody ) {
case BODY_HEAD:
eCorpse.frame = ANIM_DIE_HEAD;
break;
case BODY_STOMACH:
eCorpse.frame = ANIM_DIE_GUT;
break;
case BODY_LEGLEFT:
case BODY_ARMLEFT:
eCorpse.frame = ANIM_DIE_LEFT;
break;
case BODY_LEGRIGHT:
case BODY_ARMRIGHT:
eCorpse.frame = ANIM_DIE_RIGHT;
break;
default:
eCorpse.frame = ANIM_DEATH1 + floor( random() * 3 );
break;
}
}
Spawn_MakeSpectator(); Spawn_MakeSpectator();
self.classname = "player"; self.classname = "player";

View file

@ -88,7 +88,7 @@ void OpenCSGunBase_Draw( void ) {
} }
void OpenCSGunBase_AccuracyCalc( void ) { void OpenCSGunBase_AccuracyCalc( void ) {
self.fAccuracy = self.iShotMultiplier / wptTable[ self.weapon ].fAccuracyDivisor; self.fAccuracy = ( self.iShotMultiplier / wptTable[ self.weapon ].fAccuracyDivisor ) * wptTable[ self.weapon ].iBullets;
} }
// Returns whether or not to play an animation // Returns whether or not to play an animation

Binary file not shown.

Binary file not shown.