//----------------------------------------------------------------------------- // // $Id$ // //----------------------------------------------------------------------------- // // $Log$ // Revision 1.76 2007/02/03 15:02:21 jbravo // Renamed RQ3 to Reaction, Dropped loading of various baseq3 media, disabled the follow command, fixed grenades killing teammates and some cleanups // // Revision 1.75 2005/02/15 16:33:38 makro // Tons of updates (entity tree attachment system, UI vectors) // // Revision 1.74 2003/09/07 19:51:39 makro // no message // // Revision 1.73 2003/07/30 16:05:46 makro // no message // // Revision 1.72 2003/04/07 02:18:49 jbravo // Removed more unlagged stuff that was messing up impact marks and fixed a // booboo in the UI ssg xhair previews. // // Revision 1.71 2003/03/09 21:30:38 jbravo // Adding unlagged. Still needs work. // // Revision 1.70 2002/11/09 14:13:32 makro // Added tdmMode info to the loading screen // // Revision 1.69 2002/10/30 20:04:33 jbravo // Adding helmet // // Revision 1.68 2002/08/25 07:09:00 niceass // added "life" setting to func_pressure // // Revision 1.67 2002/07/22 06:31:11 niceass // cleaned up the powerup code // // Revision 1.66 2002/07/07 18:36:13 jbravo // Added an AntiIdle system. Can play insane sounds for idle players, drop them // from teams or kick them. Upped version to Beta 2.1 // // Revision 1.65 2002/06/16 20:06:13 jbravo // Reindented all the source files with "indent -kr -ut -i8 -l120 -lc120 -sob -bad -bap" // // Revision 1.64 2002/06/16 19:12:52 jbravo // Removed the MISSIONPACK ifdefs and missionpack only code. // // Revision 1.63 2002/06/05 23:53:05 jbravo // Color fixes for player names // // Revision 1.62 2002/06/05 09:42:30 niceass // removed old death messages // // Revision 1.61 2002/05/30 18:22:20 jbravo // Misc fixes // // Revision 1.60 2002/05/28 01:46:58 jbravo // Added stomach gibbing // // Revision 1.59 2002/05/28 01:17:01 jbravo // More gib fixes. g_RQ3_gib added // // Revision 1.58 2002/05/27 17:47:19 jbravo // Fixes and cleanups // // Revision 1.57 2002/05/26 05:15:36 niceass // pressure // // Revision 1.56 2002/05/12 22:13:43 makro // Impact sounds // // Revision 1.55 2002/05/11 19:13:42 makro // Sand surfaceparm // // Revision 1.54 2002/05/09 20:58:30 jbravo // New Obit system and a warning cleanup in zcam // // Revision 1.53 2002/05/02 23:04:59 makro // Loading screen. Jump kicks // // Revision 1.52 2002/04/29 06:14:57 niceass // pressure // // Revision 1.51 2002/04/23 06:08:58 niceass // pressure stuff // // Revision 1.50 2002/04/20 15:05:08 makro // More footstep sounds, a few other things // // Revision 1.49 2002/04/06 21:43:58 makro // New surfaceparm system // // Revision 1.48 2002/04/03 03:13:48 blaze // NEW BREAKABLE CODE - will break all old breakables(wont appear in maps) // // Revision 1.47 2002/03/31 03:31:24 jbravo // Compiler warning cleanups // // Revision 1.46 2002/03/23 05:17:42 jbravo // Major cleanup of game -> cgame communication with LCA vars. // // Revision 1.45 2002/03/21 15:02:05 jbravo // More teamname cleanups and fix for fraglines. // // Revision 1.44 2002/03/18 13:32:53 jbravo // Fixed the fraglines for sniper head kills and twekaed bandaging a bit for // testing // // Revision 1.43 2002/03/18 12:25:10 jbravo // Live players dont get fraglines, except their own. Cleanups and some // hacks to get bots to stop using knives only. // // Revision 1.42 2002/03/17 01:44:39 jbravo // Fixed the "xxx died" fraglines, did some code cleanups andalmost fixed // DM. Only DM problem I can see is that bots are invisible. // // Revision 1.41 2002/03/17 00:40:23 jbravo // Adding variable team names. g_RQ3_team1name and g_RQ3_team2name. Fixed // Slicers fraglimit check. // // Revision 1.40 2002/03/14 23:54:12 jbravo // Added a variable system from AQ. Works the same except it uses $ for % // // Revision 1.39 2002/03/03 22:02:15 jbravo // Further attempts to stop "you fragged XXX" messages for spectators // // Revision 1.38 2002/03/02 20:16:58 jbravo // Stopping you fragged XXX messages for spectators in followmode. // // Revision 1.37 2002/02/11 00:30:02 niceass // LCA fix // // Revision 1.36 2002/02/10 16:26:55 jbravo // Attempting to intergrate zcam better into rq3 and a fix for lights.wav // // Revision 1.35 2002/01/24 14:20:53 jbravo // Adding func_explosive and a few new surfaceparms // // Revision 1.34 2002/01/14 01:19:23 niceass // No more default 800 gravity on items - NiceAss // // Revision 1.33 2002/01/11 20:20:57 jbravo // Adding TP to main branch // // Revision 1.32 2002/01/11 19:48:29 jbravo // Formatted the source in non DOS format. // // Revision 1.31 2001/12/31 16:28:41 jbravo // I made a Booboo with the Log tag. // // //----------------------------------------------------------------------------- // Copyright (C) 1999-2000 Id Software, Inc. // // cg_event.c -- handle entity events at snapshot or playerstate transitions #include "cg_local.h" // JBravo: warning fix void CG_BreakBreakable(centity_t * cent, int eParam, int number); void CG_LaunchGib(vec3_t origin, vec3_t velocity, qhandle_t hModel); //========================================================================== /* =================== CG_PlaceString Also called by scoreboard drawing =================== */ const char *CG_PlaceString(int rank) { static char str[64]; char *s, *t; if (rank & RANK_TIED_FLAG) { rank &= ~RANK_TIED_FLAG; t = "Tied for "; } else { t = ""; } if (rank == 1) { s = S_COLOR_BLUE "1st" S_COLOR_WHITE; // draw in blue } else if (rank == 2) { s = S_COLOR_RED "2nd" S_COLOR_WHITE; // draw in red } else if (rank == 3) { s = S_COLOR_YELLOW "3rd" S_COLOR_WHITE; // draw in yellow } else if (rank == 11) { s = "11th"; } else if (rank == 12) { s = "12th"; } else if (rank == 13) { s = "13th"; } else if (rank % 10 == 1) { s = va("%ist", rank); } else if (rank % 10 == 2) { s = va("%ind", rank); } else if (rank % 10 == 3) { s = va("%ird", rank); } else { s = va("%ith", rank); } Com_sprintf(str, sizeof(str), "%s%s", t, s); return str; } /* =============== CG_UseItem =============== */ static void CG_UseItem(centity_t * cent) { //clientInfo_t *ci; int itemNum; gitem_t *item; entityState_t *es; es = ¢->currentState; itemNum = (es->event & ~EV_EVENT_BITS) - EV_USE_ITEM0; if (itemNum < 0 || itemNum > HI_NUM_HOLDABLE) { itemNum = 0; } // print a message if the local player if (es->number == cg.snap->ps.clientNum) { if (!itemNum) { CG_CenterPrint("No item to use", SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH); } else { item = BG_FindItemForHoldable(itemNum); CG_CenterPrint(va("Use %s", item->pickup_name), SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH); } } switch (itemNum) { default: case HI_NONE: //trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.useNothingSound); break; // JBravo: getting rid of NON RQ3 items. /* case HI_TELEPORTER: break; case HI_MEDKIT: clientNum = cent->currentState.clientNum; if (clientNum >= 0 && clientNum < MAX_CLIENTS) { ci = &cgs.clientinfo[clientNum]; ci->medkitUsageTime = cg.time; } trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.medkitSound); break; */ } } /* ================ CG_ItemPickup A new item was picked up this frame ================ */ static void CG_ItemPickup(int itemNum) { cg.itemPickup = itemNum; cg.itemPickupTime = cg.time; cg.itemPickupBlendTime = cg.time; // see if it should be the grabbed weapon if (bg_itemlist[itemNum].giType == IT_WEAPON) { // select it immediately //Blaze: Changed WP_MACHINEGUN to WP_PISTOL // if ( cg_autoswitch.integer && bg_itemlist[itemNum].giTag != WP_PISTOL ) { // cg.weaponSelectTime = cg.time; // cg.weaponSelect = bg_itemlist[itemNum].giTag; // } } } /* ================ CG_PainEvent Also called by playerstate transition ================ */ void CG_PainEvent(centity_t * cent, int health) { char *snd; // don't do more than two pain sounds a second if (cg.time - cent->pe.painTime < 500) { return; } if (health < 25) { snd = "*pain25_1.wav"; } else if (health < 50) { snd = "*pain50_1.wav"; } else if (health < 75) { snd = "*pain75_1.wav"; } else { snd = "*pain100_1.wav"; } trap_S_StartSound(NULL, cent->currentState.number, CHAN_VOICE, CG_CustomSound(cent->currentState.number, snd)); // save pain time for programitic twitch animation cent->pe.painTime = cg.time; cent->pe.painDirection ^= 1; } /* ============= CG_DMRewardEvent Used to display the frag rewards for getting many frags in a row during a DM game. ============= */ static void CG_DMRewardEvent(entityState_t * ent) { int mod; int attacker; char *message; const char *attackerInfo; char attackerName[32]; // clientInfo_t *ci; attacker = ent->otherEntityNum2; mod = ent->eventParm; if (attacker < 0 || attacker >= MAX_CLIENTS) { attacker = ENTITYNUM_WORLD; attackerInfo = NULL; } else { attackerInfo = CG_ConfigString(CS_PLAYERS + attacker); } Q_strncpyz(attackerName, Info_ValueForKey(attackerInfo, "n"), sizeof(attackerName) - 2); strcat(attackerName, S_COLOR_WHITE); if ((mod > 3) && (mod < 8)) message = "2"; else if (mod < 16) message = "4"; else if (mod < 32) message = "8"; else message = "16"; if (message) { CG_AddMessage(va("%s has %d kills in a row and receives %s frags for the kill!\n", attackerName, mod, message)); return; } } // JBravo: for sniper headshots #define GIB_VELOCITY 250 #define GIB_JUMP 250 void CG_GibPlayerHeadshot(vec3_t playerOrigin) { vec3_t origin, velocity; if (!cg_blood.integer) { return; } VectorCopy(playerOrigin, origin); origin[2] += 25; velocity[0] = crandom() * GIB_VELOCITY; velocity[1] = crandom() * GIB_VELOCITY; velocity[2] = GIB_JUMP + crandom() * GIB_VELOCITY; if (rand() & 1) { CG_LaunchGib(origin, velocity, cgs.media.gibSkull); } else { CG_LaunchGib(origin, velocity, cgs.media.gibBrain); } } void CG_GibPlayerStomachshot(vec3_t playerOrigin) { vec3_t origin, velocity; if (!cg_blood.integer) { return; } VectorCopy(playerOrigin, origin); origin[2] += 25; velocity[0] = crandom() * GIB_VELOCITY; velocity[1] = crandom() * GIB_VELOCITY; velocity[2] = GIB_JUMP + crandom() * GIB_VELOCITY; if (rand() & 1) { CG_LaunchGib(origin, velocity, cgs.media.gibAbdomen); } else { CG_LaunchGib(origin, velocity, cgs.media.gibIntestine); } } /* ============== CG_JumpKick Added by Elder Handles messages for client jumpkicks plus sound event ============== */ static void CG_JumpKick(entityState_t * ent) { int target; int attacker; clientInfo_t *ci; char sex[4]; // null-terminated so one-bigger than pronoun target = ent->otherEntityNum; attacker = ent->otherEntityNum2; if (target < 0 || target >= MAX_CLIENTS) { CG_Error("CG_JumpKick: target out of range"); } else if (attacker < 0 || target >= MAX_CLIENTS) { CG_Error("CG_JumpKick: attacker out of range"); } if (ent->weapon && attacker == cg.clientNum) { // this client was the kicker ci = &cgs.clientinfo[target]; // get gender-appropriate pronoun if (ci->gender == GENDER_FEMALE) Q_strncpyz(sex, "her", sizeof(sex)); else if (ci->gender == GENDER_MALE) Q_strncpyz(sex, "his", sizeof(sex)); else Q_strncpyz(sex, "its", sizeof(sex)); CG_AddMessage(va("You kicked %s^7's %s from %s hands!\n", ci->name, cg_weapons[ent->weapon].item->pickup_name, sex)); } else if (ent->weapon && target == cg.clientNum) { // this client was the kicked ci = &cgs.clientinfo[attacker]; CG_AddMessage(va("%s^7 kicked your weapon from your hands!\n", ci->name)); } // everyone hears this trap_S_StartSound(NULL, ent->number, CHAN_AUTO, cgs.media.kickSound); } /* ============== CG_EntityEvent An entity has an event value also called by CG_CheckPlayerstateEvents ============== */ #define DEBUGNAME(x) if(cg_debugEvents.integer){CG_Printf(x"\n");} void CG_EntityEvent(centity_t * cent, vec3_t position) { entityState_t *es; int event; vec3_t dir; //, viewDir; const char *s; int clientNum; //Makro - added int soundType; clientInfo_t *ci; es = ¢->currentState; event = es->event & ~EV_EVENT_BITS; if (cg_debugEvents.integer) { CG_Printf("ent:%3i event:%3i ", es->number, event); } if (!event) { DEBUGNAME("ZEROEVENT"); return; } clientNum = es->clientNum; if (clientNum < 0 || clientNum >= MAX_CLIENTS) { clientNum = 0; } ci = &cgs.clientinfo[clientNum]; // CG_CalcViewDir2(es->origin2, position, viewDir); switch (event) { case EV_INSANESOUND: DEBUGNAME("EV_INSANESOUND"); trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.insanesounds[rand() & 7]); break; // // movement generated events // case EV_FOOTSTEP: DEBUGNAME("EV_FOOTSTEP"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[ci->footsteps][rand() & 3]); } break; case EV_FOOTSTEP_METAL: DEBUGNAME("EV_FOOTSTEP_METAL"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_METAL][rand() & 3]); } break; case EV_FOOTSTEP_GRASS: DEBUGNAME("EV_FOOTSTEP_GRASS"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_GRASS][rand() & 3]); } break; case EV_FOOTSTEP_GRAVEL: DEBUGNAME("EV_FOOTSTEP_GRAVEL"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_GRAVEL][rand() & 3]); } break; case EV_FOOTSTEP_WOOD: DEBUGNAME("EV_FOOTSTEP_WOOD"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_WOOD][rand() & 3]); } break; case EV_FOOTSTEP_CARPET: DEBUGNAME("EV_FOOTSTEP_CARPET"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_CARPET][rand() & 3]); } break; // JBravo: begin new sounds case EV_FOOTSTEP_SNOW: DEBUGNAME("EV_FOOTSTEP_SNOW"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_SNOW][rand() & 3]); } break; case EV_FOOTSTEP_MUD: DEBUGNAME("EV_FOOTSTEP_MUD"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_MUD][rand() & 3]); } break; case EV_FOOTSTEP_WOOD2: DEBUGNAME("EV_FOOTSTEP_WOOD2"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_WOOD2][rand() & 3]); } break; case EV_FOOTSTEP_HARDMETAL: DEBUGNAME("EV_FOOTSTEP_HARDMETAL"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_HARDMETAL][rand() & 3]); } break; // JBravo: end new sounds // Makro - more sounds case EV_FOOTSTEP_LEAVES: DEBUGNAME("EV_FOOTSTEP_LEAVES"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_LEAVES][rand() & 3]); } break; case EV_FOOTSTEP_CEMENT: DEBUGNAME("EV_FOOTSTEP_CEMENT"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_CEMENT][rand() & 3]); } break; case EV_FOOTSTEP_MARBLE: DEBUGNAME("EV_FOOTSTEP_MARBLE"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_MARBLE][rand() & 3]); } break; case EV_FOOTSTEP_SNOW2: DEBUGNAME("EV_FOOTSTEP_SNOW2"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_SNOW2][rand() & 3]); } break; case EV_FOOTSTEP_HARDSTEPS: DEBUGNAME("EV_FOOTSTEP_HARDSTEPS"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_HARDSTEPS][rand() & 3]); } break; case EV_FOOTSTEP_SAND: DEBUGNAME("EV_FOOTSTEP_SAND"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_SAND][rand() & 3]); } break; // Makro - end new sounds case EV_FOOTSTEP_METAL2: DEBUGNAME("EV_FOOTSTEP_METAL2"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_METAL2][rand() & 3]); } break; case EV_FOOTSPLASH: DEBUGNAME("EV_FOOTSPLASH"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_SPLASH][rand() & 3]); } break; case EV_FOOTWADE: DEBUGNAME("EV_FOOTWADE"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_SPLASH][rand() & 3]); } break; case EV_SWIM: DEBUGNAME("EV_SWIM"); if (cg_footsteps.integer) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.footsteps[FOOTSTEP_SPLASH][rand() & 3]); } break; case EV_FALL_SHORT: DEBUGNAME("EV_FALL_SHORT"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.landSound); if (clientNum == cg.predictedPlayerState.clientNum) { // smooth landing z changes cg.landChange = -8; cg.landTime = cg.time; } break; case EV_FALL_SHORT_NOSOUND: DEBUGNAME("EV_FALL_SHORT_NOSOUND"); if (clientNum == cg.predictedPlayerState.clientNum) { // smooth landing z changes cg.landChange = -8; cg.landTime = cg.time; } break; case EV_FALL_MEDIUM: DEBUGNAME("EV_FALL_MEDIUM"); // use normal pain sound trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*pain100_1.wav")); if (clientNum == cg.predictedPlayerState.clientNum) { // smooth landing z changes cg.landChange = -16; cg.landTime = cg.time; } break; case EV_FALL_MEDIUM_NOSOUND: DEBUGNAME("EV_FALL_MEDIUM_NOSOUND"); if (clientNum == cg.predictedPlayerState.clientNum) { // smooth landing z changes cg.landChange = -16; cg.landTime = cg.time; } break; case EV_FALL_FAR: DEBUGNAME("EV_FALL_FAR"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, CG_CustomSound(es->number, "*fall1.wav")); cent->pe.painTime = cg.time; // don't play a pain sound right after this if (clientNum == cg.predictedPlayerState.clientNum) { // smooth landing z changes cg.landChange = -24; cg.landTime = cg.time; } break; case EV_FALL_FAR_NOSOUND: DEBUGNAME("EV_FALL_FAR_NOSOUND"); if (clientNum == cg.predictedPlayerState.clientNum) { // smooth landing z changes cg.landChange = -24; cg.landTime = cg.time; } break; case EV_STEP_4: case EV_STEP_8: case EV_STEP_12: case EV_STEP_16: // smooth out step up transitions DEBUGNAME("EV_STEP"); { float oldStep; int delta; int step; if (clientNum != cg.predictedPlayerState.clientNum) { break; } // if we are interpolating, we don't need to smooth steps if (cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) || cg_nopredict.integer || cg_synchronousClients.integer) { break; } // check for stepping up before a previous step is completed delta = cg.time - cg.stepTime; if (delta < STEP_TIME) { oldStep = cg.stepChange * (STEP_TIME - delta) / STEP_TIME; } else { oldStep = 0; } // add this amount step = 4 * (event - EV_STEP_4 + 1); cg.stepChange = oldStep + step; if (cg.stepChange > MAX_STEP_CHANGE) { cg.stepChange = MAX_STEP_CHANGE; } cg.stepTime = cg.time; break; } case EV_JUMP_PAD: DEBUGNAME("EV_JUMP_PAD"); // CG_Printf( "EV_JUMP_PAD w/effect #%i\n", es->eventParm ); { vec3_t up = { 0, 0, 1 }; CG_SmokePuff(cent->lerpOrigin, up, 32, 1, 1, 1, 0.33f, 1000, cg.time, 0, LEF_PUFF_DONT_SCALE, cgs.media.smokePuffShader); } // boing sound at origin, jump sound on player // NiceAss: Allow for custom jump sounds. I have no clue what I am doing. if (es->eventParm) trap_S_StartSound(cent->lerpOrigin, -1, CHAN_VOICE, cgs.gameSounds[es->eventParm]); //cgs.media.jumpPadSound ); //Blaze: Get rid of jump noises // trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); break; case EV_JUMP: DEBUGNAME("EV_JUMP"); //Blaze: Get rid of jump noises // trap_S_StartSound (NULL, es->number, CHAN_VOICE, CG_CustomSound( es->number, "*jump1.wav" ) ); break; case EV_TAUNT: DEBUGNAME("EV_TAUNT"); trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, "*taunt.wav")); break; case EV_WATER_TOUCH: DEBUGNAME("EV_WATER_TOUCH"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.watrInSound); break; case EV_WATER_LEAVE: DEBUGNAME("EV_WATER_LEAVE"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.watrOutSound); break; case EV_WATER_UNDER: DEBUGNAME("EV_WATER_UNDER"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.watrUnSound); break; case EV_WATER_CLEAR: DEBUGNAME("EV_WATER_CLEAR"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, CG_CustomSound(es->number, "*gasp.wav")); break; case EV_ITEM_PICKUP: DEBUGNAME("EV_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if (index < 1 || index >= bg_numItems) { break; } item = &bg_itemlist[index]; // powerups and team items will have a separate global sound, this one // will be played at prediction time if (item->giType == IT_POWERUP || item->giType == IT_TEAM) { trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.n_healthSound); } else if (item->giType == IT_PERSISTANT_POWERUP) { } else if (item->giType == IT_HOLDABLE) { // Elder: we want sounds for unique item pickup trap_S_StartSound(NULL, es->number, CHAN_AUTO, trap_S_RegisterSound(item->pickup_sound, qfalse)); } else { // Elder: no item pick-up sound //trap_S_StartSound (NULL, es->number, CHAN_AUTO, trap_S_RegisterSound( item->pickup_sound, qfalse ) ); } // show icon and name on status bar if (es->number == cg.snap->ps.clientNum) { CG_ItemPickup(index); } } break; case EV_GLOBAL_ITEM_PICKUP: DEBUGNAME("EV_GLOBAL_ITEM_PICKUP"); { gitem_t *item; int index; index = es->eventParm; // player predicted if (index < 1 || index >= bg_numItems) { break; } item = &bg_itemlist[index]; // powerup pickups are global if (item->pickup_sound) { trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, trap_S_RegisterSound(item->pickup_sound, qfalse)); } // show icon and name on status bar if (es->number == cg.snap->ps.clientNum) { CG_ItemPickup(index); } } break; // // weapon events // case EV_NOAMMO: DEBUGNAME("EV_NOAMMO"); //Elder: Only play on non-grenade/knife //Todo: use "out of ammo sound" for specific gun? switch (cent->currentState.weapon) { case WP_GRENADE: case WP_KNIFE: break; default: trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.noAmmoSound); break; } if (es->number == cg.snap->ps.clientNum) { CG_OutOfAmmoChange(); } break; case EV_CHANGE_WEAPON: DEBUGNAME("EV_CHANGE_WEAPON"); //Elder: TODO: change to appropriate weapon "in" sound //trap_S_StartSound (NULL, es->number, CHAN_AUTO, cgs.media.selectSound ); break; case EV_FIRE_WEAPON: DEBUGNAME("EV_FIRE_WEAPON"); //Elder: modified CG_FireWeapon(cent, es->eventParm); break; case EV_RELOAD_WEAPON0: DEBUGNAME("EV_RELOAD_WEAPON0"); CG_ReloadWeapon(cent, 0); break; case EV_RELOAD_WEAPON1: DEBUGNAME("EV_RELOAD_WEAPON1"); CG_ReloadWeapon(cent, 1); break; case EV_RELOAD_WEAPON2: DEBUGNAME("EV_RELOAD_WEAPON2"); CG_ReloadWeapon(cent, 2); break; case EV_USE_ITEM0: DEBUGNAME("EV_USE_ITEM0"); CG_UseItem(cent); break; case EV_USE_ITEM1: DEBUGNAME("EV_USE_ITEM1"); CG_UseItem(cent); break; case EV_USE_ITEM2: DEBUGNAME("EV_USE_ITEM2"); CG_UseItem(cent); break; case EV_USE_ITEM3: DEBUGNAME("EV_USE_ITEM3"); CG_UseItem(cent); break; case EV_USE_ITEM4: DEBUGNAME("EV_USE_ITEM4"); CG_UseItem(cent); break; case EV_USE_ITEM5: DEBUGNAME("EV_USE_ITEM5"); CG_UseItem(cent); break; case EV_USE_ITEM6: DEBUGNAME("EV_USE_ITEM6"); CG_UseItem(cent); break; case EV_USE_ITEM7: DEBUGNAME("EV_USE_ITEM7"); CG_UseItem(cent); break; case EV_USE_ITEM8: DEBUGNAME("EV_USE_ITEM8"); CG_UseItem(cent); break; case EV_USE_ITEM9: DEBUGNAME("EV_USE_ITEM9"); CG_UseItem(cent); break; case EV_USE_ITEM10: DEBUGNAME("EV_USE_ITEM10"); CG_UseItem(cent); break; case EV_USE_ITEM11: DEBUGNAME("EV_USE_ITEM11"); CG_UseItem(cent); break; case EV_USE_ITEM12: DEBUGNAME("EV_USE_ITEM12"); CG_UseItem(cent); break; case EV_USE_ITEM13: DEBUGNAME("EV_USE_ITEM13"); CG_UseItem(cent); break; case EV_USE_ITEM14: DEBUGNAME("EV_USE_ITEM14"); CG_UseItem(cent); break; //================================================================= // // other events // case EV_PLAYER_TELEPORT_IN: DEBUGNAME("EV_PLAYER_TELEPORT_IN"); //trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.teleInSound); //CG_SpawnEffect(position); break; case EV_PLAYER_TELEPORT_OUT: DEBUGNAME("EV_PLAYER_TELEPORT_OUT"); //trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.teleOutSound); //CG_SpawnEffect(position); break; case EV_ITEM_POP: DEBUGNAME("EV_ITEM_POP"); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.respawnSound); break; case EV_ITEM_RESPAWN: DEBUGNAME("EV_ITEM_RESPAWN"); cent->miscTime = cg.time; // scale up from this trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.respawnSound); break; case EV_GRENADE_BOUNCE: DEBUGNAME("EV_GRENADE_BOUNCE"); if (rand() & 1) { trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.hgrenb1aSound); } else { trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.hgrenb2aSound); } break; case EV_SCOREPLUM: DEBUGNAME("EV_SCOREPLUM"); CG_ScorePlum(cent->currentState.otherEntityNum, cent->lerpOrigin, cent->currentState.time); break; // // missile impacts // case EV_MISSILE_HIT: DEBUGNAME("EV_MISSILE_HIT"); ByteToDir(es->eventParm, dir); CG_MissileHitPlayer(es->weapon, position, dir, es->otherEntityNum); break; case EV_MISSILE_MISS: DEBUGNAME("EV_MISSILE_MISS"); ByteToDir(es->eventParm, dir); // JBravo: removing arg 5 after NA's changes on the next 4 CG_MissileHitWall calls. CG_MissileHitWall(es->weapon, 0, position, dir, IMPACTSOUND_DEFAULT, 0); break; case EV_MISSILE_MISS_METAL: DEBUGNAME("EV_MISSILE_MISS_METAL"); ByteToDir(es->eventParm, dir); CG_MissileHitWall(es->weapon, 0, position, dir, IMPACTSOUND_METAL, 0); break; case EV_KNIFE_MISS: DEBUGNAME("EV_KNIFE_MISS"); if (es->powerups == MAT_GRASS) soundType = IMPACTSOUND_GRASS; else if (IsSnowMat(es->powerups)) soundType = IMPACTSOUND_SNOW; else soundType = IMPACTSOUND_METAL; ByteToDir(es->eventParm, dir); CG_MissileHitWall(es->weapon, 0, position, dir, soundType, RQ3_WPMOD_KNIFESLASH); break; case EV_RAILTRAIL: DEBUGNAME("EV_RAILTRAIL"); //Blaze: No Railgun //cent->currentState.weapon = WP_RAILGUN; // if the end was on a nomark surface, don't make an explosion //CG_RailTrail( ci, es->origin2, es->pos.trBase ); if (es->eventParm != 255) { ByteToDir(es->eventParm, dir); CG_MissileHitWall(es->weapon, es->clientNum, position, dir, IMPACTSOUND_DEFAULT, 0); } break; case EV_BULLET_HIT_WALL: DEBUGNAME("EV_BULLET_HIT_WALL"); ByteToDir(es->eventParm, dir); CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_DEFAULT); break; case EV_BULLET_HIT_METAL: DEBUGNAME("EV_BULLET_HIT_METAL"); ByteToDir(es->eventParm, dir); CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_METAL); break; case EV_BULLET_HIT_GLASS: DEBUGNAME("EV_BULLET_HIT_GLASS"); ByteToDir(es->eventParm, dir); CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_GLASS); break; //Makro - added case EV_BULLET_HIT_WOOD: DEBUGNAME("EV_BULLET_HIT_WOOD"); ByteToDir(es->eventParm, dir); CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_WOOD); break; //Makro - added case EV_BULLET_HIT_BRICK: DEBUGNAME("EV_BULLET_HIT_BRICK"); ByteToDir(es->eventParm, dir); CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_BRICK); break; //Makro - added case EV_BULLET_HIT_CERAMIC: DEBUGNAME("EV_BULLET_HIT_CERAMIC"); ByteToDir(es->eventParm, dir); CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_CERAMIC); break; //Makro - added case EV_BULLET_HIT_SNOW: DEBUGNAME("EV_BULLET_HIT_SNOW"); ByteToDir(es->eventParm, dir); CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_SNOW); break; //Makro - added case EV_BULLET_HIT_GRASS: DEBUGNAME("EV_BULLET_HIT_GRASS"); ByteToDir(es->eventParm, dir); CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qfalse, ENTITYNUM_WORLD, IMPACTSOUND_GRASS); break; case EV_BULLET_HIT_KEVLAR: DEBUGNAME("EV_BULLET_HIT_KEVLAR"); ByteToDir(es->eventParm, dir); VectorScale(dir, -1, dir); trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.kevlarHitSound); if (cg_RQ3_impactEffects.integer) { vec3_t velocity; vec3_t origin; int sparkCount; int i; sparkCount = 20 + rand() % 15; VectorCopy(es->pos.trBase, origin); origin[2] += 12; // Generate the particles for (i = 0; i < sparkCount; i++) { VectorScale(dir, 150 + rand() % 30, velocity); //random upwards sparks if (rand() % 5 < 1) velocity[2] += 120 + rand() % 30; velocity[0] += rand() % 80 - 40; velocity[1] += rand() % 80 - 40; CG_ParticleSparks(origin, velocity, 150 + rand() % 120, 2, 2, -4, 1); } } break; case EV_BULLET_HIT_FLESH: DEBUGNAME("EV_BULLET_HIT_FLESH"); //ByteToDir( es->eventParm, dir ); //Elder: added additional param CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qtrue, es->otherEntityNum2, IMPACTSOUND_FLESH); break; case EV_SSG3000_HIT_FLESH: DEBUGNAME("EV_SSG3000_HIT_FLESH"); ByteToDir(es->eventParm, dir); //Elder: added additional param CG_Bullet(es->pos.trBase, es->otherEntityNum, dir, qtrue, es->otherEntityNum2, IMPACTSOUND_FLESH); VectorAdd(es->pos.trBase, dir, dir); CG_BleedSpray(es->pos.trBase, dir, es->otherEntityNum2, 10); break; case EV_JUMPKICK: DEBUGNAME("EV_JUMPKICK"); ByteToDir(es->eventParm, dir); // obviously not the pistol but oh well CG_MissileHitPlayer(WP_PISTOL, position, dir, es->otherEntityNum); CG_JumpKick(es); break; case EV_EJECTBLOOD: DEBUGNAME("EV_EJECTBLOOD"); // Straight up dir[0] = 0; dir[1] = 0; dir[2] = 20; // Eject blood splats CG_EjectBloodSplat(es->pos.trBase, dir, 1, 1500); //CG_BleedParticleSpray( es->pos.trBase, dir, es->otherEntityNum, 25, 1500 ); break; case EV_SHOTGUN: DEBUGNAME("EV_SHOTGUN"); CG_ShotgunFire(es, qtrue); break; case EV_HANDCANNON: DEBUGNAME("EV_SHOTGUN"); CG_ShotgunFire(es, qfalse); break; case EV_GENERAL_SOUND: DEBUGNAME("EV_GENERAL_SOUND"); if (cgs.gameSounds[es->eventParm]) { trap_S_StartSound(NULL, es->number, CHAN_VOICE, cgs.gameSounds[es->eventParm]); } else { s = CG_ConfigString(CS_SOUNDS + es->eventParm); trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, s)); } break; case EV_GLOBAL_SOUND: // play from the player's head so it never diminishes DEBUGNAME("EV_GLOBAL_SOUND"); if (cgs.gameSounds[es->eventParm]) { trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.gameSounds[es->eventParm]); } else { s = CG_ConfigString(CS_SOUNDS + es->eventParm); trap_S_StartSound(NULL, cg.snap->ps.clientNum, CHAN_AUTO, CG_CustomSound(es->number, s)); } break; case EV_RQ3_SOUND: DEBUGNAME("EV_RQ3_SOUND"); switch (es->eventParm) { // Elder: handled in EV_JUMPKICK now // But this is for non-client hits like glass case RQ3_SOUND_KICK: trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.kickSound); break; //Elder: handled in EV_HEADSHOT now /* case RQ3_SOUND_HEADSHOT: //CG_Printf("EV_RQ3_SOUND: Headshot\n"); //Elder: extra blood - synched with sound //CG_Bleed( position, es->number ); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.headshotSound); break; */ case RQ3_SOUND_LCA: //Global sound //trap_S_StartSound( NULL, cg.snap->ps.clientNum, CHAN_AUTO, cgs.media.lcaSound); break; case RQ3_SOUND_KEVLARHIT: //TODO: make sparks from hit position trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.kevlarHitSound); break; case RQ3_SOUND_KNIFEHIT: //When a player gets slashed trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.knifeHitSound); break; case RQ3_SOUND_KNIFEDEATH: trap_S_StartSound(NULL, es->number, CHAN_AUTO, cgs.media.knifeDeathSound); break; case RQ3_SOUND_COUNTDOWN: trap_S_StartLocalSound(cgs.media.lca10_0Sound, CHAN_ANNOUNCER); break; default: break; } break; case EV_DMREWARD: DEBUGNAME("EV_DMREWARD"); CG_DMRewardEvent(es); break; case EV_GLOBAL_TEAM_SOUND: // play from the player's head so it never diminishes { DEBUGNAME("EV_GLOBAL_TEAM_SOUND"); switch (es->eventParm) { case GTS_RED_CAPTURE: // CTF: red team captured the blue flag, 1FCTF: red team captured the neutral flag if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) CG_AddBufferedSound(cgs.media.captureYourTeamSound); else CG_AddBufferedSound(cgs.media.captureOpponentSound); break; case GTS_BLUE_CAPTURE: // CTF: blue team captured the red flag, 1FCTF: blue team captured the neutral flag if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) CG_AddBufferedSound(cgs.media.captureYourTeamSound); else CG_AddBufferedSound(cgs.media.captureOpponentSound); break; case GTS_RED_RETURN: // CTF: blue flag returned, 1FCTF: never used if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) CG_AddBufferedSound(cgs.media.returnYourTeamSound); else CG_AddBufferedSound(cgs.media.returnOpponentSound); // CG_AddBufferedSound(cgs.media.blueFlagReturnedSound); break; case GTS_BLUE_RETURN: // CTF red flag returned, 1FCTF: neutral flag returned if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) CG_AddBufferedSound(cgs.media.returnYourTeamSound); else CG_AddBufferedSound(cgs.media.returnOpponentSound); // CG_AddBufferedSound(cgs.media.redFlagReturnedSound); break; case GTS_RED_TAKEN: // CTF: red team took blue flag, 1FCTF: blue team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (cg.snap->ps.powerups[PW_BLUEFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) { } else { if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { CG_AddBufferedSound(cgs.media.enemyTookYourFlagSound); } else if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { CG_AddBufferedSound(cgs.media.yourTeamTookEnemyFlagSound); } } break; case GTS_BLUE_TAKEN: // CTF: blue team took the red flag, 1FCTF red team took the neutral flag // if this player picked up the flag then a sound is played in CG_CheckLocalSounds if (cg.snap->ps.powerups[PW_REDFLAG] || cg.snap->ps.powerups[PW_NEUTRALFLAG]) { } else { if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { CG_AddBufferedSound(cgs.media.enemyTookYourFlagSound); } else if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { CG_AddBufferedSound(cgs.media.yourTeamTookEnemyFlagSound); } } break; case GTS_REDOBELISK_ATTACKED: // Overload: red obelisk is being attacked if (cgs.clientinfo[cg.clientNum].team == TEAM_RED) { CG_AddBufferedSound(cgs.media.yourBaseIsUnderAttackSound); } break; case GTS_BLUEOBELISK_ATTACKED: // Overload: blue obelisk is being attacked if (cgs.clientinfo[cg.clientNum].team == TEAM_BLUE) { CG_AddBufferedSound(cgs.media.yourBaseIsUnderAttackSound); } break; case GTS_REDTEAM_SCORED: CG_AddBufferedSound(cgs.media.redScoredSound); break; case GTS_BLUETEAM_SCORED: CG_AddBufferedSound(cgs.media.blueScoredSound); break; case GTS_REDTEAM_TOOK_LEAD: if (cg_RQ3_anouncer.integer == 1) CG_AddBufferedSound(cgs.media.redLeadsSound); break; case GTS_BLUETEAM_TOOK_LEAD: if (cg_RQ3_anouncer.integer == 1) CG_AddBufferedSound(cgs.media.blueLeadsSound); break; case GTS_TEAMS_ARE_TIED: if (cg_RQ3_anouncer.integer == 1) CG_AddBufferedSound(cgs.media.teamsTiedSound); break; default: break; } break; } case EV_HEADSHOT: //Elder: headshot spray + sound DEBUGNAME("EV_HEADSHOT"); //trap_S_StartSound( es->pos.trBase, es->number, CHAN_AUTO, cgs.media.headshotSound); trap_S_StartSound(cent->lerpOrigin, es->number, CHAN_AUTO, cgs.media.headshotSound); ByteToDir(es->eventParm, dir); VectorAdd(es->pos.trBase, dir, dir); CG_BleedSpray(es->pos.trBase, dir, es->otherEntityNum, 6); break; case EV_PAIN: // local player sounds are triggered in CG_CheckLocalSounds, // so ignore events on the player DEBUGNAME("EV_PAIN"); /* if ( es->eventParm == -99999 ) { CG_Printf("EV_PAIN: Headshot\n"); trap_S_StartSound( NULL, es->number, CHAN_AUTO, cgs.media.headshotSound); } */ if (cent->currentState.number != cg.snap->ps.clientNum) { CG_PainEvent(cent, es->eventParm); } break; case EV_DEATH1: case EV_DEATH2: case EV_DEATH3: DEBUGNAME("EV_DEATHx"); trap_S_StartSound(NULL, es->number, CHAN_VOICE, CG_CustomSound(es->number, va("*death%i.wav", event - EV_DEATH1 + 1))); if (cent->currentState.number == cg.snap->ps.clientNum) cg.timeOfDeath = cg.time; break; case EV_OBITUARY: DEBUGNAME("EV_OBITUARY"); // JBravo: not used // CG_Obituary( es ); break; //Elder: location events case EV_OBITUARY_HEAD: DEBUGNAME("EV_OBITUARY_HEAD"); // JBravo: the following mod's dont have locations and are not handled in the location Orbits /* if (es->eventParm == MOD_HANDCANNON || es->eventParm == MOD_M3 || es->eventParm == MOD_KICK || es->eventParm == MOD_GRENADE || es->eventParm == MOD_GRENADE_SPLASH) { CG_Obituary( es ); } else { CG_Obituary_Head( es ); } */ break; case EV_OBITUARY_CHEST: DEBUGNAME("EV_OBITUARY_CHEST"); // JBravo: the following mod's dont have locations and are not handled in the location Orbits /* if (es->eventParm == MOD_HANDCANNON || es->eventParm == MOD_M3 || es->eventParm == MOD_KICK || es->eventParm == MOD_GRENADE || es->eventParm == MOD_GRENADE_SPLASH) { CG_Obituary( es ); } else { CG_Obituary_Chest( es ); } */ break; case EV_OBITUARY_STOMACH: DEBUGNAME("EV_OBITUARY_STOMACH"); // JBravo: the following mod's dont have locations and are not handled in the location Orbits /* if (es->eventParm == MOD_HANDCANNON || es->eventParm == MOD_M3 || es->eventParm == MOD_KICK || es->eventParm == MOD_GRENADE || es->eventParm == MOD_GRENADE_SPLASH) { CG_Obituary( es ); } else { CG_Obituary_Stomach( es ); } */ break; case EV_OBITUARY_LEGS: DEBUGNAME("EV_OBITUARY_LEGS"); // JBravo: the following mod's dont have locations and are not handled in the location Orbits /* if (es->eventParm == MOD_HANDCANNON || es->eventParm == MOD_M3 || es->eventParm == MOD_KICK || es->eventParm == MOD_GRENADE || es->eventParm == MOD_GRENADE_SPLASH) { CG_Obituary( es ); } else { CG_Obituary_Legs( es ); } */ break; // // powerup events // case EV_GIB_PLAYER: DEBUGNAME("EV_GIB_PLAYER"); // don't play gib sound when using the kamikaze because it interferes // with the kamikaze sound, downside is that the gib sound will also // not be played when someone is gibbed while just carrying the kamikaze // JBravo: EF_KAMIKAZE is no more // if ( !(es->eFlags & EF_KAMIKAZE) ) { trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.gibSound); // } CG_GibPlayer(cent->lerpOrigin); break; case EV_GIB_PLAYER_HEADSHOT: DEBUGNAME("EV_GIB_PLAYER_HEADSHOT"); trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.gibSound); cent->pe.noHead = qtrue; CG_GibPlayerHeadshot(cent->lerpOrigin); break; case EV_GIB_PLAYER_STOMACH: DEBUGNAME("EV_GIB_PLAYER_STOMACH"); trap_S_StartSound(NULL, es->number, CHAN_BODY, cgs.media.gibSound); CG_GibPlayerStomachshot(cent->lerpOrigin); break; case EV_BREAK_GLASS1: DEBUGNAME("EV_BREAK_GLASS1"); // Change cgs.media.gibSound to whatever sound you want it to use // I think the gib sound sounds pretty good //Elder: gonna move this into the function some day CG_BreakGlass(cent->lerpOrigin, es->eventParm, es->number, 0, 0); break; case EV_BREAK_GLASS2: DEBUGNAME("EV_BREAK_GLASS2"); CG_BreakGlass(cent->lerpOrigin, es->eventParm, es->number, 1, 0); break; case EV_BREAK_GLASS3: DEBUGNAME("EV_BREAK_GLASS3"); CG_BreakGlass(cent->lerpOrigin, es->eventParm, es->number, 2, 0); break; case EV_CHIP_GLASS: DEBUGNAME("EV_CHIP_GLASS"); CG_BreakGlass(cent->lerpOrigin, es->eventParm, es->number, 1, 1); break; case EV_PRESSURE: DEBUGNAME("EV_PRESSURE"); ByteToDir(es->eventParm, dir); //Makro - changed from constantLight to generic1 CG_Pressure(position, dir, es->frame, es->powerups, es->generic1); break; case EV_STOPLOOPINGSOUND: DEBUGNAME("EV_STOPLOOPINGSOUND"); trap_S_StopLoopingSound(es->number); es->loopSound = 0; break; case EV_DEBUG_LINE: DEBUGNAME("EV_DEBUG_LINE"); CG_Beam(cent); break; // Blaze: an exploding breakable case EV_EXPLODE_BREAKABLE: DEBUGNAME("EV_EXPLODE_BREAKABLE"); //trap_S_StartSound( NULL, es->number, CHAN_BODY, cgs.media.gibSound ); CG_BreakBreakable(cent, es->eventParm, es->number); break; default: DEBUGNAME("UNKNOWN"); CG_Error("Unknown event: %i", event); break; } } /* ============== CG_CheckEvents ============== */ void CG_CheckEvents(centity_t * cent) { // check for event-only entities if (cent->currentState.eType > ET_EVENTS) { if (cent->previousEvent) { return; // already fired } // if this is a player event set the entity number of the client entity number if (cent->currentState.eFlags & EF_PLAYER_EVENT) { cent->currentState.number = cent->currentState.otherEntityNum; } cent->previousEvent = 1; cent->currentState.event = cent->currentState.eType - ET_EVENTS; } else { // check for events riding with another entity if (cent->currentState.event == cent->previousEvent) { return; } cent->previousEvent = cent->currentState.event; if ((cent->currentState.event & ~EV_EVENT_BITS) == 0) { return; } } // calculate the position at exactly the frame time //CG_EvaluateTrajectory(¢->currentState.pos, cg.snap->serverTime, cent->lerpOrigin); CG_EvaluateTrajectoryEx(cent, cg.snap->serverTime, cent->lerpOrigin, NULL); CG_SetEntitySoundPosition(cent); CG_EntityEvent(cent, cent->lerpOrigin); }