This tut shows you how to add
a new award that you receive for hitting and killing a person in air. Note
this is based on the 1.17 source code! This might First off go to bg_public.h and find: #define EF_MOVER_STOP 0x00000400 // will push otherwise Directly up underneath add: #define EF_AWARD_AIRKILL 0x00000800 // draw an airkill sprite That lets it know when we get the award so it can add it on top of our head. Now find: // reward sounds typedef enum { REWARD_BAD, REWARD_IMPRESSIVE, Now directly under that add: REWARD_AIRKILL, That of course defines to play the sound, now find this tidbit of code: // these were added for single player awards tracking PERS_IMPRESSIVE_COUNT, Now guess what we add? This of course: PERS_AIRKILL_COUNT, That tells how many of these awards you have that are Air Kills. Now open cg_local.h and find: qhandle_t medalImpressive; Up under it add: qhandle_t medalAirKill; That gives us a place so we can store a
reference to the sprite we use that goes over your head. sfxHandle_t impressiveSound; Below it add: sfxHandle_t airkillSound; Now open up cg_main.c and find: cgs.media.impressiveSound = trap_S_RegisterSound( "sound/feedback/impressive.wav" ); Below it add: cgs.media.airkillSound = trap_S_RegisterSound( "sound/feedback/airkill.wav" ); That says what to play when we receive the
award. cgs.media.medalImpressive = trap_R_RegisterShaderNoMip( "medal_impressive" ); Below it add: cgs.media.medalAirKill = trap_R_RegisterShaderNoMip( "medal_airkill" ); Now we gotta go and open up cg_players.c and tell it to draw the award abover our head when we receive it. Find: if ( cent->currentState.eFlags & EF_AWARD_IMPRESSIVE ) { CG_PlayerFloatSprite( cent, cgs.media.medalImpressive ); return; } Up under it add: if ( cent->currentState.eFlags & EF_AWARD_AIRKILL ) { CG_PlayerFloatSprite( cent, cgs.media.medalAirKill ); return; } Now open up cg_playerstate.c and find: case REWARD_IMPRESSIVE: trap_S_StartLocalSound( cgs.media.impressiveSound, CHAN_ANNOUNCER ); cg.rewardTime = cg.time; cg.rewardShader = cgs.media.medalImpressive; cg.rewardCount = ps->persistant[PERS_IMPRESSIVE_COUNT]; break; Now lets add below that: case REWARD_AIRKILL: trap_S_StartLocalSound( cgs.media.airkillSound, CHAN_ANNOUNCER ); cg.rewardTime = cg.time; cg.rewardShader = cgs.media.medalAirKill; cg.rewardCount = ps->persistant[PERS_AIRKILL_COUNT]; break; That starts up the predfined sound, tells
it what shader to use as the image over our head, and then sets the
rewardCount to how many of these we hav received( not sure of its purpose
). // clear the rewards if time And replace that and the function below it with: // clear the rewards if time if ( level.time > client->rewardTime ) { client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_AIRKILL | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET ); } That just takes away the award when
ready. Com_sprintf( msg, sizeof(msg), "postgame And replace the function with: Com_sprintf( msg, sizeof(msg), "postgame %i %i %i %i %i %i %i %i %i", level.numNonSpectatorClients, playerClientNum, accuracy, player->client->ps.persistant[PERS_IMPRESSIVE_COUNT], player->client->ps.persistant[PERS_AIRKILL_COUNT], player->client->ps.persistant[PERS_EXCELLENT_COUNT], player->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT], player->client->ps.persistant[PERS_SCORE], perfect ); Now open up g_combat.c and find this bit of code: if (attacker && attacker->client) { if ( attacker == self || OnSameTeam (self, attacker ) ) { AddScore( attacker, -1 ); } else { And replace that and the large chunk of code following it with: if (attacker && attacker->client) { if ( attacker == self || OnSameTeam (self, attacker ) ) { AddScore( attacker, -1 ); } else { AddScore( attacker, 1 ); if( meansOfDeath == MOD_GAUNTLET ) { attacker->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT]++; attacker->client->ps.persistant[PERS_REWARD] = REWARD_GAUNTLET; attacker->client->ps.persistant[PERS_REWARD_COUNT]++; // add the sprite over the player's head attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_AIRKILL | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET ); attacker->client->ps.eFlags |= EF_AWARD_GAUNTLET; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; // also play humiliation on target self->client->ps.persistant[PERS_REWARD] = REWARD_GAUNTLET; self->client->ps.persistant[PERS_REWARD_COUNT]++; } // check for airkill // FireWorks! if ( self->s.groundEntityNum == ENTITYNUM_NONE ) { attacker->client->ps.persistant[PERS_REWARD_COUNT]++; attacker->client->ps.persistant[PERS_REWARD] = REWARD_AIRKILL; attacker->client->ps.persistant[PERS_AIRKILL_COUNT]++; // add the sprite over the player's head attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_AIRKILL | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET ); attacker->client->ps.eFlags |= EF_AWARD_AIRKILL; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; } // check for two kills in a short amount of time // if this is close enough to the last kill, give a reward sound if ( level.time - attacker->client->lastKillTime < CARNAGE_REWARD_TIME ) { attacker->client->ps.persistant[PERS_REWARD_COUNT]++; attacker->client->ps.persistant[PERS_REWARD] = REWARD_EXCELLENT; attacker->client->ps.persistant[PERS_EXCELLENT_COUNT]++; // add the sprite over the player's head attacker->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_AIRKILL | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET ); attacker->client->ps.eFlags |= EF_AWARD_EXCELLENT; attacker->client->rewardTime = level.time + REWARD_SPRITE_TIME; } attacker->client->lastKillTime = level.time; } } else { AddScore( self, -1 ); } Now, the final step! Open up g_weapon.c and find: // add the sprite over the player's head And replace the next line with: ent->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_AIRKILL | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET ); There, we are done! Compile all 3 projects and enjoy! I spend my time programming and writing these tutorials, so please feel free to use this code in your mod as long as www.inolen.com and the author receive credit. | |
Design Copyright inolen 2000 |