From 943539a1a7741d395667f2830b31cfdfea5e0816 Mon Sep 17 00:00:00 2001 From: Petr Pudlak Date: Tue, 19 Aug 2014 22:24:50 +0200 Subject: The head-shot mod: headshots on humans splash blood around .. using the particle system. Blood drops splat on impact. --- src/game/bg_misc.c | 1 + src/game/bg_public.h | 3 +++ src/game/g_active.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- src/game/g_combat.c | 12 ++++++++++-- src/game/g_local.h | 2 ++ 5 files changed, 63 insertions(+), 3 deletions(-) (limited to 'src/game') diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index 71f5507..1597194 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -4315,6 +4315,7 @@ char *eventnames[ ] = "EV_DEATH3", "EV_OBITUARY", "EV_GIB_PLAYER", // gib a previously living player + "EV_BLEED", "EV_BUILD_CONSTRUCT", "EV_BUILD_DESTROY", "EV_BUILD_DELAY", // can't build yet diff --git a/src/game/bg_public.h b/src/game/bg_public.h index 9109a35..886d29b 100644 --- a/src/game/bg_public.h +++ b/src/game/bg_public.h @@ -478,6 +478,8 @@ typedef enum #define EVENT_VALID_MSEC 300 +#define EVENT_HEADSHOT_BIT 0x80 + const char *BG_EventName( int num ); typedef enum @@ -538,6 +540,7 @@ typedef enum EV_DEATH3, EV_OBITUARY, EV_GIB_PLAYER, // gib a previously living player + EV_BLEED, EV_BUILD_CONSTRUCT, EV_BUILD_DESTROY, EV_BUILD_DELAY, // can't build yet diff --git a/src/game/g_active.c b/src/game/g_active.c index 2f7f906..3c888a6 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -76,8 +76,14 @@ void P_DamageFeedback( gentity_t *player ) // play an apropriate pain sound if( ( level.time > player->pain_debounce_time ) && !( player->flags & FL_GODMODE ) ) { + int param; player->pain_debounce_time = level.time + 700; - G_AddEvent( player, EV_PAIN, player->health > 255 ? 255 : player->health ); + param = player->health; + if( param >= EVENT_HEADSHOT_BIT ) + param = EVENT_HEADSHOT_BIT - 1; + if( client->damage_headshot ) + param |= EVENT_HEADSHOT_BIT; + G_AddEvent( player, EV_PAIN, param ); client->ps.damageEvent++; } @@ -90,10 +96,47 @@ void P_DamageFeedback( gentity_t *player ) client->damage_blood = 0; client->damage_armor = 0; client->damage_knockback = 0; + client->damage_headshot = 0; } +/* +=============== +P_WoundsBleed + +=============== +*/ +void P_WoundsBleed( gentity_t *player ) +{ + gclient_t *client; + int maxHealth; + int health; + + if( player->nextBleedTime > level.time ) + return; + + client = player->client; + health = player->health; + maxHealth = client->ps.stats[ STAT_MAX_HEALTH ]; + if( maxHealth > 100 ) + maxHealth = 100; + maxHealth = maxHealth * 3 / 4; + if( ( health > maxHealth ) || ( health < 0 ) ) { + player->nextBleedTime = level.time + 2000; + return; + } + + G_AddEvent( player, EV_BLEED, ( health > 255 ) ? 255 : health ); + + if( health < 20 ) + health = 20; + player->nextBleedTime = level.time + 2000 * health / maxHealth; +} + + + + /* ============= P_WorldEffects @@ -2292,6 +2335,9 @@ void ClientEndFrame( gentity_t *ent ) // burn from lava, etc P_WorldEffects( ent ); + // bleeding wounds + P_WoundsBleed( ent ); + // apply all the damage taken this frame P_DamageFeedback( ent ); diff --git a/src/game/g_combat.c b/src/game/g_combat.c index c79594d..073c00c 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -687,8 +687,12 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int } // use own entityid if killed by non-client to prevent uint8_t overflow - G_AddEvent( self, EV_DEATH1 + i, - ( killer < MAX_CLIENTS ) ? killer : self - g_entities ); + { + int param = ( killer < MAX_CLIENTS ) ? killer : self - g_entities; + if( self->client->damage_headshot ) + param |= EVENT_HEADSHOT_BIT; + G_AddEvent( self, EV_DEATH1 + i, param ); + } // globally cycle through the different death animations i = ( i + 1 ) % 3; @@ -1069,6 +1073,10 @@ static float G_CalcDamageModifier( vec3_t point, gentity_t *targ, gentity_t *att g_numDamageRegions[ class ], hitRotation, hitRatio ); + // For headshots done by an enemy, make a client event + if( ( modifier >= 1.2f ) && !OnSameTeam( targ, attacker ) ) + targ->client->damage_headshot ++; + for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ ) { if( BG_InventoryContainsUpgrade( i, targ->client->ps.stats ) ) diff --git a/src/game/g_local.h b/src/game/g_local.h index 2683ac5..a9774a6 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -245,6 +245,7 @@ struct gentity_s int lastDamageTime; int nextRegenTime; + int nextBleedTime; qboolean ownerClear; // used for missle tracking @@ -399,6 +400,7 @@ struct gclient_s int damage_knockback; // impact damage vec3_t damage_from; // origin for vector calculation qboolean damage_fromWorld; // if true, don't use the damage_from vector + int damage_headshot; // the number of head-shots taken in a frame // int lastkilled_client;// last client that this client killed -- cgit