diff --git a/Source/Server/Client.c b/Source/Server/Client.c index c76a1693..8e154b2c 100644 --- a/Source/Server/Client.c +++ b/Source/Server/Client.c @@ -52,15 +52,6 @@ void ClientDisconnect( void ) { } } -void PlayerPreThink( void ) { - Input_Handle(); - OpenCSGunBase_ShotMultiplierUpdate(); -} - -void PlayerPostThink( void ) { - Animation_PlayerUpdate(); -} - void PutClientInServer( void ) { entity eTarget = world; diff --git a/Source/Server/Damage.c b/Source/Server/Damage.c index 9c63ddd1..0f6f07e4 100644 --- a/Source/Server/Damage.c +++ b/Source/Server/Damage.c @@ -31,6 +31,34 @@ void Damage_CastOrbituary( entity eAttacker, entity eTarget, float fWeapon, floa multicast( '0 0 0', MULTICAST_ALL ); } +string Damage_GetHitLocation( int iSurface ) { + switch ( iSurface ) { + case BODY_HEAD: + return "Head"; + break; + case BODY_CHEST: + return "Chest"; + break; + case BODY_STOMACH: + return "Stomach"; + break; + case BODY_ARMLEFT: + return "Left Arm"; + break; + case BODY_ARMRIGHT: + return "Right Arm"; + break; + case BODY_LEGLEFT: + return "Left leg"; + break; + case BODY_LEGRIGHT: + return "Right Leg"; + break; + default: + return "Generic"; + } +} + void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos ) { eTarget.health = eTarget.health - iDamage; // TODO: Body part multipliers @@ -44,10 +72,24 @@ void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos } } + if ( trace_surface_id == BODY_HEAD ) { + iDamage *= 4; + } else if ( iDamage == BODY_STOMACH ) { + iDamage *= 0.9; + } else if ( iDamage == BODY_LEGLEFT ) { + iDamage *= 0.9; + } else if ( iDamage == BODY_LEGRIGHT ) { + iDamage *= 0.9; + } + + bprint( sprintf( "[DEBUG] Hit Bodypart: %s\n", Damage_GetHitLocation( trace_surface_id ) ) ); + // Don't be like Q1 and make everything bleed. if ( eTarget.iBleeds == TRUE ) { makevectors( eAttacker.angles ); pointparticles( EFFECT_BLOOD, vHitPos, v_forward * -1, 1 ); + } else { + pointparticles( EFFECT_GUNSHOT, trace_endpos, trace_plane_normal, 1 ); } // Target is dead and a client.... diff --git a/Source/Server/Defs.h b/Source/Server/Defs.h index 8fbb03c7..5a9d8f85 100644 --- a/Source/Server/Defs.h +++ b/Source/Server/Defs.h @@ -34,6 +34,18 @@ var float autocvar_mp_c4timer = 45; var float autocvar_mp_roundtime = 5; var float autocvar_mp_fillweapons = 0; +// Hit Group standards +enum { + BODY_DEFAULT, + BODY_HEAD, + BODY_CHEST, + BODY_STOMACH, + BODY_ARMLEFT, + BODY_ARMRIGHT, + BODY_LEGLEFT, + BODY_LEGRIGHT +}; + // Particle Fields float EFFECT_GUNSHOT; float EFFECT_BLOOD; @@ -68,6 +80,7 @@ float fGameTime; .float fSlotMelee, fSlotPrimary, fSlotSecondary, fSlotGrenade; .float fAttackFinished; .float fAccuracy; +.float fFallVelocity; // Game specific fields int iHostagesMax; @@ -126,15 +139,22 @@ void OpenCSGunBase_AccuracyCalc( void ); void OpenCSGunBase_Draw( void ); float OpenCSGunBase_PrimaryFire( void ); float OpenCSGunBase_Reload( void ); + +void BaseMelee_Draw( void ); +void BaseMelee_Attack( void ); + float Player_GetMaxSpeed( float fWeapon ); void TraceAttack_FireBullets( int iShots ); void Damage_Radius( vector vOrigin, entity eAttacker, float fDamage, float fRadius ); +void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos ); void Entities_InitRespawnable( void() vRespawnFunc ); void Entities_Respawn( void ); void Ammo_BuyPrimary( float fFree ); void Ammo_BuySecondary( float fFree ); + +void Input_Handle( void ); // WIP string __fullspawndata; diff --git a/Source/Server/EntHostage.c b/Source/Server/EntHostage.c index 3dfc00d9..1f6faabc 100644 --- a/Source/Server/EntHostage.c +++ b/Source/Server/EntHostage.c @@ -47,6 +47,7 @@ void hostage_die( void ) { self.frame = 30 + floor( random( 1, 6 ) ); self.solid = SOLID_NOT; self.takedamage = DAMAGE_NO; + //skel_delete( self.skeletonindex ); if ( other.eTargetPoint != other.eUser ) { remove( other.eTargetPoint ); @@ -78,7 +79,7 @@ void hostage_physics( void ) { input_impulse = 0; input_buttons = 0; input_angles = self.angles; - + // Are we meant to follow someone and AREN'T dead? if ( ( self.eUser != world ) && ( self.health > 0 ) ) { // Which direction we have to face @@ -157,6 +158,8 @@ void hostage_physics( void ) { // Calculate physstuff runstandardplayerphysics( self ); + //self.frame1time += frametime; + //skel_build( self.skeletonindex, self, self.modelindex, 1, 0, 0 ); } /* @@ -174,8 +177,11 @@ void hostage_entity( void ) { self.movetype = MOVETYPE_WALK; setmodel( self, self.model ); setsize( self, VEC_HULL_MIN + '0 0 36', VEC_HULL_MAX + '0 0 36' ); - self.customphysics = hostage_physics; + //self.basebone = -1; // Debug: Network that shit + //self.skeletonindex = skel_create( self.modelindex ); + self.customphysics = hostage_physics; + self.eUser = world; self.eTargetPoint = world; self.iUsable = TRUE; diff --git a/Source/Server/Footsteps.c b/Source/Server/Footsteps.c index e1d979df..8bc32c4d 100644 --- a/Source/Server/Footsteps.c +++ b/Source/Server/Footsteps.c @@ -44,7 +44,7 @@ void Footsteps_Update( void ) { dDelay = clamp( 0.1, 1 / ( fForce / 90 ), 1 ); traceline( self.origin + self.view_ofs, self.origin + '0 0 -48', FALSE, self ); - sound( self, CHAN_BODY, sprintf( "player/pl_step%d.wav", random( 1, 5 ) ), 0.5, ATTN_IDLE ); + sound( self, CHAN_BODY, sprintf( "player/pl_step%d.wav", floor( ( random() * 4 ) + 1 ) ), 0.5, ATTN_IDLE ); self.fSteptime = time + dDelay; } diff --git a/Source/Server/Player.c b/Source/Server/Player.c index c072602f..7fa7ecff 100644 --- a/Source/Server/Player.c +++ b/Source/Server/Player.c @@ -198,3 +198,25 @@ void Player_UseUp( void ) { self.fProgressBar = 0; } } + +void PlayerPreThink( void ) { + Input_Handle(); + OpenCSGunBase_ShotMultiplierUpdate(); + + if ( !( self.flags & FL_ONGROUND ) ){ + self.fFallVelocity = -self.velocity_z; + } +} + +void PlayerPostThink( void ) { + Animation_PlayerUpdate(); + + if ( ( self.flags & FL_ONGROUND ) && ( self.health > 0 ) && ( self.fFallVelocity > 100 )) { + if ( self.fFallVelocity > 580 ) { + self.fFallVelocity -= 580; + float fFallDamage = self.fFallVelocity * ( 200 / ( 1024 - 580 ) ); + Damage_Apply( self, world, fFallDamage, self.origin ); + } + self.fFallVelocity = 0; + } +} diff --git a/Source/Server/TraceAttack.c b/Source/Server/TraceAttack.c index 098921a9..8921f446 100644 --- a/Source/Server/TraceAttack.c +++ b/Source/Server/TraceAttack.c @@ -28,7 +28,7 @@ void TraceAttack_FireBullets( int iShots ) { while ( iShots > 0) { vDir = aim( self, 100000 ) + Math_CRandom()*self.fAccuracy*v_right + Math_CRandom()*self.fAccuracy*v_up; - traceline( vSrc, vSrc + ( vDir * 2048 ), FALSE, self); + traceline( vSrc, vSrc + ( vDir * 2048 ), MOVE_HITMODEL, self); if (trace_fraction != 1.0) { if ( trace_ent.takedamage == DAMAGE_YES ) { Damage_Apply( trace_ent, self, wptTable[ self.weapon ].iDamage, trace_endpos ); diff --git a/Source/Server/progs.src b/Source/Server/progs.src index f5bd8472..908d8a63 100644 --- a/Source/Server/progs.src +++ b/Source/Server/progs.src @@ -36,6 +36,7 @@ Money.c ../Shared/WeaponUSP45.c ../Shared/WeaponXM1014.c ../Shared/WeaponBase.c +../Shared/BaseMelee.c ../Shared/Weapons.c ../Shared/Effects.c ../Shared/Equipment.c diff --git a/Source/Shared/BaseMelee.c b/Source/Shared/BaseMelee.c new file mode 100644 index 00000000..89639349 --- /dev/null +++ b/Source/Shared/BaseMelee.c @@ -0,0 +1,55 @@ +/* +Copyright (C) 2015, 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. +*/ + +#ifdef SSQC +void BaseMelee_Draw( void ) { + self.iCurrentMag = 0; + self.iCurrentCaliber = 0; + + Client_SendEvent( self, EV_WEAPON_DRAW ); +} + +void BaseMelee_Attack( void ) { + vector vSource; + vector vOrigin; + + makevectors( self.v_angle ); + vSource = ( self.origin + self.view_ofs ); + traceline( vSource, vSource + ( v_forward * 64 ), FALSE, self ); + + if ( trace_fraction == 1.0 ) + return; + + vOrigin = trace_endpos - v_forward * 2; + + if ( trace_ent.takedamage ) { + Damage_Apply( trace_ent, self, wptTable[ self.weapon ].iDamage, trace_endpos ); + return; + } +} + +void BaseMelee_Delayed( float fDelay ) { + static void BaseMelee_Delayed_Trigger( void ) { + BaseMelee_Attack(); + } + + self.think = BaseMelee_Delayed_Trigger; + self.nextthink = time + fDelay; +} +#endif diff --git a/Source/Shared/WeaponBase.c b/Source/Shared/WeaponBase.c index 27da550a..b4b983bf 100644 --- a/Source/Shared/WeaponBase.c +++ b/Source/Shared/WeaponBase.c @@ -18,11 +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. */ -// Because padding... -weaponinfo_t wptDEFAULT = { 0, 0, 0, 0, 240, 0, 0, 0, 0, 0.0, 0.0, 0, 0.0, 0.0, iAmmo_9MM, iAmmo_9MM, 0.0, 0.0, 0.0, 0, 0 }; - weaponinfo_t wptTable[ CS_WEAPON_COUNT ] = { - wptDEFAULT, + { 0, 0, 0, 0, 240, 0, 0, 0, 0, 0.0, 0.0, 0, 0.0, 0.0, iAmmo_9MM, iAmmo_9MM, 0.0, 0.0, 0.0, 0, 0 }, wptKNIFE, wptUSP45, wptGLOCK18, diff --git a/Source/Shared/WeaponKnife.c b/Source/Shared/WeaponKnife.c index a00d6797..80e24140 100644 --- a/Source/Shared/WeaponKnife.c +++ b/Source/Shared/WeaponKnife.c @@ -32,7 +32,7 @@ weaponinfo_t wptKNIFE = { 64, // Bullet Range 0.75, // Range Modifier TYPE_SEMI, // Firing Type - 0.15, // Attack-Delay + 0.3, // Attack-Delay 1.0, // Reload-Delay iAmmo_9MM, // Caliber Pointer iMag_GLOCK18, // Clip Pointer @@ -58,9 +58,7 @@ enum { void WeaponKNIFE_Draw( void ) { #ifdef SSQC - Client_SendEvent( self, EV_WEAPON_DRAW ); - self.iCurrentMag = 0; - self.iCurrentCaliber = 0; + BaseMelee_Draw(); #else View_PlayAnimation( ANIM_KNIFE_DRAW ); #endif @@ -68,6 +66,7 @@ void WeaponKNIFE_Draw( void ) { void WeaponKNIFE_PrimaryFire( void ) { #ifdef SSQC + BaseMelee_Attack(); Client_SendEvent( self, EV_WEAPON_PRIMARYATTACK ); self.fAttackFinished = time + wptKNIFE.fAttackFinished; #else @@ -81,6 +80,7 @@ void WeaponKNIFE_PrimaryFire( void ) { void WeaponKNIFE_Secondary( void ) { #ifdef SSQC + BaseMelee_Attack(); Client_SendEvent( self, EV_WEAPON_SECONDARYATTACK ); self.fAttackFinished = time + wptKNIFE.fAttackFinished; #else