diff --git a/assets/japro/hud/mod/DEMP2.png b/assets/japro/hud/mod/DEMP2.png new file mode 100644 index 0000000000..b9574948ea Binary files /dev/null and b/assets/japro/hud/mod/DEMP2.png differ diff --git a/assets/japro/hud/mod/DEMP2_alt.png b/assets/japro/hud/mod/DEMP2_alt.png new file mode 100644 index 0000000000..78b9ca72e9 Binary files /dev/null and b/assets/japro/hud/mod/DEMP2_alt.png differ diff --git a/assets/japro/hud/mod/bowcaster.png b/assets/japro/hud/mod/bowcaster.png new file mode 100644 index 0000000000..973314bb00 Binary files /dev/null and b/assets/japro/hud/mod/bowcaster.png differ diff --git a/assets/japro/hud/mod/concussion.png b/assets/japro/hud/mod/concussion.png new file mode 100644 index 0000000000..9002684046 Binary files /dev/null and b/assets/japro/hud/mod/concussion.png differ diff --git a/assets/japro/hud/mod/concussion_alt.png b/assets/japro/hud/mod/concussion_alt.png new file mode 100644 index 0000000000..f4518758ef Binary files /dev/null and b/assets/japro/hud/mod/concussion_alt.png differ diff --git a/assets/japro/hud/mod/crushed.png b/assets/japro/hud/mod/crushed.png new file mode 100644 index 0000000000..284bec96aa Binary files /dev/null and b/assets/japro/hud/mod/crushed.png differ diff --git a/assets/japro/hud/mod/detpack.png b/assets/japro/hud/mod/detpack.png new file mode 100644 index 0000000000..42396aef68 Binary files /dev/null and b/assets/japro/hud/mod/detpack.png differ diff --git a/assets/japro/hud/mod/disruptor.png b/assets/japro/hud/mod/disruptor.png new file mode 100644 index 0000000000..58ee7acc90 Binary files /dev/null and b/assets/japro/hud/mod/disruptor.png differ diff --git a/assets/japro/hud/mod/disruptor_alt.png b/assets/japro/hud/mod/disruptor_alt.png new file mode 100644 index 0000000000..2c52c8d524 Binary files /dev/null and b/assets/japro/hud/mod/disruptor_alt.png differ diff --git a/assets/japro/hud/mod/fall.png b/assets/japro/hud/mod/fall.png new file mode 100644 index 0000000000..966b86933b Binary files /dev/null and b/assets/japro/hud/mod/fall.png differ diff --git a/assets/japro/hud/mod/flachette.png b/assets/japro/hud/mod/flachette.png new file mode 100644 index 0000000000..f94e69e6f1 Binary files /dev/null and b/assets/japro/hud/mod/flachette.png differ diff --git a/assets/japro/hud/mod/flachette_alt.png b/assets/japro/hud/mod/flachette_alt.png new file mode 100644 index 0000000000..6b4300d244 Binary files /dev/null and b/assets/japro/hud/mod/flachette_alt.png differ diff --git a/assets/japro/hud/mod/force.png b/assets/japro/hud/mod/force.png new file mode 100644 index 0000000000..c2679ee113 Binary files /dev/null and b/assets/japro/hud/mod/force.png differ diff --git a/assets/japro/hud/mod/generic.png b/assets/japro/hud/mod/generic.png new file mode 100644 index 0000000000..943e37f57a Binary files /dev/null and b/assets/japro/hud/mod/generic.png differ diff --git a/assets/japro/hud/mod/lava.png b/assets/japro/hud/mod/lava.png new file mode 100644 index 0000000000..96f2c61fff Binary files /dev/null and b/assets/japro/hud/mod/lava.png differ diff --git a/assets/japro/hud/mod/melee.png b/assets/japro/hud/mod/melee.png new file mode 100644 index 0000000000..3490fcd27d Binary files /dev/null and b/assets/japro/hud/mod/melee.png differ diff --git a/assets/japro/hud/mod/merrsonn.png b/assets/japro/hud/mod/merrsonn.png new file mode 100644 index 0000000000..145314d3f9 Binary files /dev/null and b/assets/japro/hud/mod/merrsonn.png differ diff --git a/assets/japro/hud/mod/merrsonn_alt.png b/assets/japro/hud/mod/merrsonn_alt.png new file mode 100644 index 0000000000..e1a1659b98 Binary files /dev/null and b/assets/japro/hud/mod/merrsonn_alt.png differ diff --git a/assets/japro/hud/mod/merrsonn_splash.png b/assets/japro/hud/mod/merrsonn_splash.png new file mode 100644 index 0000000000..ce3387fe0d Binary files /dev/null and b/assets/japro/hud/mod/merrsonn_splash.png differ diff --git a/assets/japro/hud/mod/mine.png b/assets/japro/hud/mod/mine.png new file mode 100644 index 0000000000..4144e17b44 Binary files /dev/null and b/assets/japro/hud/mod/mine.png differ diff --git a/assets/japro/hud/mod/mine_alt.png b/assets/japro/hud/mod/mine_alt.png new file mode 100644 index 0000000000..889343c6ad Binary files /dev/null and b/assets/japro/hud/mod/mine_alt.png differ diff --git a/assets/japro/hud/mod/ooze.png b/assets/japro/hud/mod/ooze.png new file mode 100644 index 0000000000..5d504265c5 Binary files /dev/null and b/assets/japro/hud/mod/ooze.png differ diff --git a/assets/japro/hud/mod/pistol.png b/assets/japro/hud/mod/pistol.png new file mode 100644 index 0000000000..3d61f2a488 Binary files /dev/null and b/assets/japro/hud/mod/pistol.png differ diff --git a/assets/japro/hud/mod/pistol_alt.png b/assets/japro/hud/mod/pistol_alt.png new file mode 100644 index 0000000000..cfb8b2bfe7 Binary files /dev/null and b/assets/japro/hud/mod/pistol_alt.png differ diff --git a/assets/japro/hud/mod/portable_turret.png b/assets/japro/hud/mod/portable_turret.png new file mode 100644 index 0000000000..add50401b2 Binary files /dev/null and b/assets/japro/hud/mod/portable_turret.png differ diff --git a/assets/japro/hud/mod/repeater.png b/assets/japro/hud/mod/repeater.png new file mode 100644 index 0000000000..e1bc853177 Binary files /dev/null and b/assets/japro/hud/mod/repeater.png differ diff --git a/assets/japro/hud/mod/repeater_alt.png b/assets/japro/hud/mod/repeater_alt.png new file mode 100644 index 0000000000..462f7e9584 Binary files /dev/null and b/assets/japro/hud/mod/repeater_alt.png differ diff --git a/assets/japro/hud/mod/rifle.png b/assets/japro/hud/mod/rifle.png new file mode 100644 index 0000000000..66b3b9f733 Binary files /dev/null and b/assets/japro/hud/mod/rifle.png differ diff --git a/assets/japro/hud/mod/rifle_alt.png b/assets/japro/hud/mod/rifle_alt.png new file mode 100644 index 0000000000..feca10fd8d Binary files /dev/null and b/assets/japro/hud/mod/rifle_alt.png differ diff --git a/assets/japro/hud/mod/saber.png b/assets/japro/hud/mod/saber.png new file mode 100644 index 0000000000..bf3e7ebbad Binary files /dev/null and b/assets/japro/hud/mod/saber.png differ diff --git a/assets/japro/hud/mod/stun.png b/assets/japro/hud/mod/stun.png new file mode 100644 index 0000000000..a9c858e5ff Binary files /dev/null and b/assets/japro/hud/mod/stun.png differ diff --git a/assets/japro/hud/mod/swoop.png b/assets/japro/hud/mod/swoop.png new file mode 100644 index 0000000000..451020a5db Binary files /dev/null and b/assets/japro/hud/mod/swoop.png differ diff --git a/assets/japro/hud/mod/telefrag.png b/assets/japro/hud/mod/telefrag.png new file mode 100644 index 0000000000..c76e252a1b Binary files /dev/null and b/assets/japro/hud/mod/telefrag.png differ diff --git a/assets/japro/hud/mod/thermal.png b/assets/japro/hud/mod/thermal.png new file mode 100644 index 0000000000..323e7c4128 Binary files /dev/null and b/assets/japro/hud/mod/thermal.png differ diff --git a/assets/japro/hud/mod/thermal_alt.png b/assets/japro/hud/mod/thermal_alt.png new file mode 100644 index 0000000000..4ff5a6527e Binary files /dev/null and b/assets/japro/hud/mod/thermal_alt.png differ diff --git a/assets/japro/hud/mod/turret.png b/assets/japro/hud/mod/turret.png new file mode 100644 index 0000000000..b4aff52029 Binary files /dev/null and b/assets/japro/hud/mod/turret.png differ diff --git a/assets/japro/hud/mod/water.png b/assets/japro/hud/mod/water.png new file mode 100644 index 0000000000..576c855d5c Binary files /dev/null and b/assets/japro/hud/mod/water.png differ diff --git a/codemp/cgame/CMakeLists.txt b/codemp/cgame/CMakeLists.txt index 3993c66e66..a9e68a7e85 100644 --- a/codemp/cgame/CMakeLists.txt +++ b/codemp/cgame/CMakeLists.txt @@ -63,6 +63,7 @@ set(MPCGameCgameFiles "${MPDir}/cgame/cg_effects.c" "${MPDir}/cgame/cg_ents.c" "${MPDir}/cgame/cg_event.c" + "${MPDir}/cgame/cg_hud.c" "${MPDir}/cgame/cg_info.c" "${MPDir}/cgame/cg_light.c" "${MPDir}/cgame/cg_localents.c" @@ -91,11 +92,14 @@ set(MPCGameCgameFiles "${MPDir}/cgame/fx_force.c" "${MPDir}/cgame/fx_heavyrepeater.c" "${MPDir}/cgame/fx_rocketlauncher.c" + "${MPDir}/cgame/hud_obituary.c" + "${MPDir}/cgame/hud_shared.c" "${MPDir}/cgame/animtable.h" "${MPDir}/cgame/cg_local.h" "${MPDir}/cgame/cg_public.h" "${MPDir}/cgame/cg_xcvar.h" "${MPDir}/cgame/fx_local.h" + "${MPDir}/cgame/hud_local.h" ) source_group("cgame" FILES ${MPCGameCgameFiles}) set(MPCGameFiles ${MPCGameFiles} ${MPCGameCgameFiles}) diff --git a/codemp/cgame/cg_draw.c b/codemp/cgame/cg_draw.c index 085adceaee..e58f79041a 100644 --- a/codemp/cgame/cg_draw.c +++ b/codemp/cgame/cg_draw.c @@ -7057,7 +7057,6 @@ void CG_AddSpeed(void) #define SPEEDOMETER_MIN_RANGE 900 #define SPEED_MED 1000.f #define SPEED_FAST 1600.f -#define Vector4Copy( a, b ) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) #define VectorLerp( f, s, e, r ) ((r)[0]=(s)[0]+(f)*((e)[0]-(s)[0]),\ (r)[1]=(s)[1]+(f)*((e)[1]-(s)[1]),\ (r)[2]=(s)[2]+(f)*((e)[2]-(s)[2])) @@ -11280,6 +11279,9 @@ static void CG_Draw2D( void ) { return; } + if(cg_killfeed.integer) + CG_Draw2DNew( ); + CG_Draw2DScreenTints(); if (cg.snap->ps.rocketLockIndex != ENTITYNUM_NONE && (cg.time - cg.snap->ps.rocketLockTime) > 0) diff --git a/codemp/cgame/cg_event.c b/codemp/cgame/cg_event.c index 9f67c35f26..996528ac44 100644 --- a/codemp/cgame/cg_event.c +++ b/codemp/cgame/cg_event.c @@ -150,300 +150,298 @@ static void CG_Obituary( entityState_t *ent ) { Com_sprintf(targetName, sizeof(targetName), "%s%s", targetInfo->name, S_COLOR_WHITE); targetInfo->deaths++; - // check for single client messages - switch( mod ) { - case MOD_SUICIDE: - case MOD_FALLING: - case MOD_CRUSH: - case MOD_WATER: - case MOD_SLIME: - case MOD_LAVA: - case MOD_TRIGGER_HURT: - message = "DIED_GENERIC"; - break; - case MOD_TARGET_LASER: - message = "DIED_LASER"; - break; - default: - message = NULL; - break; - } - - // Attacker killed themselves. Ridicule them for it. - if (attacker == target) { - gender = targetInfo->gender; - switch (mod) { - case MOD_BRYAR_PISTOL: - case MOD_BRYAR_PISTOL_ALT: - case MOD_BLASTER: - case MOD_TURBLAST: - case MOD_DISRUPTOR: - case MOD_DISRUPTOR_SPLASH: - case MOD_DISRUPTOR_SNIPER: - case MOD_BOWCASTER: - case MOD_REPEATER: - case MOD_REPEATER_ALT: - case MOD_FLECHETTE: - if ( gender == GENDER_FEMALE ) - message = "SUICIDE_SHOT_FEMALE"; - else if ( gender == GENDER_NEUTER ) - message = "SUICIDE_SHOT_GENDERLESS"; - else - message = "SUICIDE_SHOT_MALE"; - break; - case MOD_REPEATER_ALT_SPLASH: - case MOD_FLECHETTE_ALT_SPLASH: - case MOD_ROCKET: - case MOD_ROCKET_SPLASH: - case MOD_ROCKET_HOMING: - case MOD_ROCKET_HOMING_SPLASH: - case MOD_THERMAL: - case MOD_THERMAL_SPLASH: - case MOD_TRIP_MINE_SPLASH: - case MOD_TIMED_MINE_SPLASH: - case MOD_DET_PACK_SPLASH: - case MOD_VEHICLE: - case MOD_CONC: - case MOD_CONC_ALT: - if ( gender == GENDER_FEMALE ) - message = "SUICIDE_EXPLOSIVES_FEMALE"; - else if ( gender == GENDER_NEUTER ) - message = "SUICIDE_EXPLOSIVES_GENDERLESS"; - else - message = "SUICIDE_EXPLOSIVES_MALE"; - break; - case MOD_DEMP2: - if ( gender == GENDER_FEMALE ) - message = "SUICIDE_ELECTROCUTED_FEMALE"; - else if ( gender == GENDER_NEUTER ) - message = "SUICIDE_ELECTROCUTED_GENDERLESS"; - else - message = "SUICIDE_ELECTROCUTED_MALE"; - break; - case MOD_FALLING: - if ( gender == GENDER_FEMALE ) - message = "SUICIDE_FALLDEATH_FEMALE"; - else if ( gender == GENDER_NEUTER ) - message = "SUICIDE_FALLDEATH_GENDERLESS"; - else - message = "SUICIDE_FALLDEATH_MALE"; - break; - default: - if ( gender == GENDER_FEMALE ) - message = "SUICIDE_GENERICDEATH_FEMALE"; - else if ( gender == GENDER_NEUTER ) - message = "SUICIDE_GENERICDEATH_GENDERLESS"; - else - message = "SUICIDE_GENERICDEATH_MALE"; - break; - } - } - - if (target != attacker && target < MAX_CLIENTS && attacker < MAX_CLIENTS) - { - goto clientkilled; - } - - if (message) { - gender = targetInfo->gender; - - if (!message[0]) - { - if ( gender == GENDER_FEMALE ) - message = "SUICIDE_GENERICDEATH_FEMALE"; - else if ( gender == GENDER_NEUTER ) - message = "SUICIDE_GENERICDEATH_GENDERLESS"; - else - message = "SUICIDE_GENERICDEATH_MALE"; - } - message = (char *)CG_GetStringEdString("MP_INGAME", message); - - trap->Print( "%s %s\n", targetName, message); - return; - } - -clientkilled: - - // check for kill messages from the current clientNum - if ( attacker == cg.snap->ps.clientNum ) { - char s[MAX_STRING_CHARS] = {0}; - - if ( cg_killMessage.integer != 2 && cgs.gametype < GT_TEAM && cgs.gametype != GT_DUEL && cgs.gametype != GT_POWERDUEL ) { - if (cgs.gametype == GT_JEDIMASTER && - attacker < MAX_CLIENTS && - !ent->isJediMaster && - !cg.snap->ps.isJediMaster && - CG_ThereIsAMaster()) - { - char part1[512]; - char part2[512]; - trap->SE_GetStringTextString("MP_INGAME_KILLED_MESSAGE", part1, sizeof(part1)); - trap->SE_GetStringTextString("MP_INGAME_JMKILLED_NOTJM", part2, sizeof(part2)); - Com_sprintf(s, sizeof(s), "%s %s\n%s\n", part1, targetName, part2); - } - else if (cgs.gametype == GT_JEDIMASTER && - attacker < MAX_CLIENTS && - !ent->isJediMaster && - !cg.snap->ps.isJediMaster) - { //no JM, saber must be out - char part1[512]; - trap->SE_GetStringTextString("MP_INGAME_KILLED_MESSAGE", part1, sizeof(part1)); - /* - kmsg1 = "for 0 points.\nGo for the saber!"; - strcpy(part2, kmsg1); - - Com_sprintf(s, sizeof(s), "%s %s %s\n", part1, targetName, part2); - */ - Com_sprintf(s, sizeof(s), "%s %s\n", part1, targetName); - } - else if (cgs.gametype == GT_POWERDUEL) - { - Q_strncpyz(s, "", sizeof(s)); - } - else - { - char sPlaceWith[256]; - char sKilledStr[256]; - trap->SE_GetStringTextString("MP_INGAME_PLACE_WITH", sPlaceWith, sizeof(sPlaceWith)); - trap->SE_GetStringTextString("MP_INGAME_KILLED_MESSAGE", sKilledStr, sizeof(sKilledStr)); - - Com_sprintf(s, sizeof(s), "%s %s\n%s %s %i.", sKilledStr, targetName, - CG_PlaceString( cg.snap->ps.persistant[PERS_RANK] + 1 ), - sPlaceWith, - cg.snap->ps.persistant[PERS_SCORE] ); - } - } else { - char sKilledStr[256]; - trap->SE_GetStringTextString("MP_INGAME_KILLED_MESSAGE", sKilledStr, sizeof(sKilledStr)); - Com_sprintf(s, sizeof(s), "%s %s", sKilledStr, targetName ); - } - - if (cg_killMessage.integer == 1 || cg_killMessage.integer == 2)//JAPRO - Clientside - Toggle Kill award message - CG_CenterPrintMultiKill( s, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH ); - else if (cg_killMessage.integer > 2)//JAPRO - Clientside - Toggle Kill award message - CG_CenterPrintMultiKill( s, SCREEN_HEIGHT * 0.10, BIGCHAR_WIDTH ); - } - - // check for double client messages - if ( !attackerInfo || !attackerInfo->infoValid ) { - attacker = ENTITYNUM_WORLD; - Q_strncpyz( attackerName, "noname", sizeof(attackerName) ); - } else { - Com_sprintf(attackerName, sizeof(attackerName), "%s%s", attackerInfo->name, S_COLOR_WHITE); - // check for kill messages about the current clientNum - if ( target == cg.snap->ps.clientNum ) { - Q_strncpyz( cg.killerName, attackerName, sizeof( cg.killerName ) ); - } - } - - if ( attacker != ENTITYNUM_WORLD ) { - switch (mod) { - case MOD_STUN_BATON: - message = "KILLED_STUN"; - break; - case MOD_MELEE: - message = "KILLED_MELEE"; - break; - case MOD_SABER: - message = "KILLED_SABER"; - break; - case MOD_BRYAR_PISTOL: - case MOD_BRYAR_PISTOL_ALT: - message = "KILLED_BRYAR"; - break; - case MOD_BLASTER: - message = "KILLED_BLASTER"; - break; - case MOD_TURBLAST: - message = "KILLED_BLASTER"; - break; - case MOD_DISRUPTOR: - case MOD_DISRUPTOR_SPLASH: - message = "KILLED_DISRUPTOR"; - break; - case MOD_DISRUPTOR_SNIPER: - message = "KILLED_DISRUPTORSNIPE"; - break; - case MOD_BOWCASTER: - message = "KILLED_BOWCASTER"; - break; - case MOD_REPEATER: - message = "KILLED_REPEATER"; - break; - case MOD_REPEATER_ALT: - case MOD_REPEATER_ALT_SPLASH: - message = "KILLED_REPEATERALT"; - break; - case MOD_DEMP2: - case MOD_DEMP2_ALT: - message = "KILLED_DEMP2"; - break; - case MOD_FLECHETTE: - message = "KILLED_FLECHETTE"; - break; - case MOD_FLECHETTE_ALT_SPLASH: - message = "KILLED_FLECHETTE_MINE"; - break; - case MOD_ROCKET: - case MOD_ROCKET_SPLASH: - message = "KILLED_ROCKET"; - break; - case MOD_ROCKET_HOMING: - case MOD_ROCKET_HOMING_SPLASH: - message = "KILLED_ROCKET_HOMING"; - break; - case MOD_THERMAL: - case MOD_THERMAL_SPLASH: - message = "KILLED_THERMAL"; - break; - case MOD_TRIP_MINE_SPLASH: - message = "KILLED_TRIPMINE"; - break; - case MOD_TIMED_MINE_SPLASH: - message = "KILLED_TRIPMINE_TIMED"; - break; - case MOD_DET_PACK_SPLASH: - message = "KILLED_DETPACK"; - break; - case MOD_VEHICLE: - case MOD_CONC: - case MOD_CONC_ALT: - message = "KILLED_GENERIC"; - break; - case MOD_FORCE_DARK: - message = "KILLED_DARKFORCE"; - break; - case MOD_SENTRY: - message = "KILLED_SENTRY"; - break; - case MOD_TELEFRAG: - message = "KILLED_TELEFRAG"; - break; - case MOD_CRUSH: - message = "KILLED_GENERIC";//"KILLED_FORCETOSS"; - break; - case MOD_FALLING: - message = "KILLED_FORCETOSS"; - break; - case MOD_TRIGGER_HURT: - message = "KILLED_GENERIC";//"KILLED_FORCETOSS"; - break; - default: - message = "KILLED_GENERIC"; - break; - } - - if (message) { - message = (char *)CG_GetStringEdString("MP_INGAME", message); - - trap->Print( "%s %s %s\n", - targetName, message, attackerName); - return; - } - } - - // we don't know what it was - trap->Print( "%s %s\n", targetName, (char *)CG_GetStringEdString("MP_INGAME", "DIED_GENERIC") ); + if(cg_killfeed.integer){ + CG_AddObituary( attacker, target, mod ); + } + if (cg_killfeed.integer != 1){ + // check for single client messages + switch (mod) { + case MOD_SUICIDE: + case MOD_FALLING: + case MOD_CRUSH: + case MOD_WATER: + case MOD_SLIME: + case MOD_LAVA: + case MOD_TRIGGER_HURT: + message = "DIED_GENERIC"; + break; + case MOD_TARGET_LASER: + message = "DIED_LASER"; + break; + default: + message = NULL; + break; + } + + // Attacker killed themselves. Ridicule them for it. + if (attacker == target) { + gender = targetInfo->gender; + switch (mod) { + case MOD_BRYAR_PISTOL: + case MOD_BRYAR_PISTOL_ALT: + case MOD_BLASTER: + case MOD_TURBLAST: + case MOD_DISRUPTOR: + case MOD_DISRUPTOR_SPLASH: + case MOD_DISRUPTOR_SNIPER: + case MOD_BOWCASTER: + case MOD_REPEATER: + case MOD_REPEATER_ALT: + case MOD_FLECHETTE: + if (gender == GENDER_FEMALE) + message = "SUICIDE_SHOT_FEMALE"; + else if (gender == GENDER_NEUTER) + message = "SUICIDE_SHOT_GENDERLESS"; + else + message = "SUICIDE_SHOT_MALE"; + break; + case MOD_REPEATER_ALT_SPLASH: + case MOD_FLECHETTE_ALT_SPLASH: + case MOD_ROCKET: + case MOD_ROCKET_SPLASH: + case MOD_ROCKET_HOMING: + case MOD_ROCKET_HOMING_SPLASH: + case MOD_THERMAL: + case MOD_THERMAL_SPLASH: + case MOD_TRIP_MINE_SPLASH: + case MOD_TIMED_MINE_SPLASH: + case MOD_DET_PACK_SPLASH: + case MOD_VEHICLE: + case MOD_CONC: + case MOD_CONC_ALT: + if (gender == GENDER_FEMALE) + message = "SUICIDE_EXPLOSIVES_FEMALE"; + else if (gender == GENDER_NEUTER) + message = "SUICIDE_EXPLOSIVES_GENDERLESS"; + else + message = "SUICIDE_EXPLOSIVES_MALE"; + break; + case MOD_DEMP2: + if (gender == GENDER_FEMALE) + message = "SUICIDE_ELECTROCUTED_FEMALE"; + else if (gender == GENDER_NEUTER) + message = "SUICIDE_ELECTROCUTED_GENDERLESS"; + else + message = "SUICIDE_ELECTROCUTED_MALE"; + break; + case MOD_FALLING: + if (gender == GENDER_FEMALE) + message = "SUICIDE_FALLDEATH_FEMALE"; + else if (gender == GENDER_NEUTER) + message = "SUICIDE_FALLDEATH_GENDERLESS"; + else + message = "SUICIDE_FALLDEATH_MALE"; + break; + default: + if (gender == GENDER_FEMALE) + message = "SUICIDE_GENERICDEATH_FEMALE"; + else if (gender == GENDER_NEUTER) + message = "SUICIDE_GENERICDEATH_GENDERLESS"; + else + message = "SUICIDE_GENERICDEATH_MALE"; + break; + } + } + + if (target != attacker && target < MAX_CLIENTS && attacker < MAX_CLIENTS) { + goto clientkilled; + } + + if (message) { + gender = targetInfo->gender; + + if (!message[0]) { + if (gender == GENDER_FEMALE) + message = "SUICIDE_GENERICDEATH_FEMALE"; + else if (gender == GENDER_NEUTER) + message = "SUICIDE_GENERICDEATH_GENDERLESS"; + else + message = "SUICIDE_GENERICDEATH_MALE"; + } + message = (char *) CG_GetStringEdString("MP_INGAME", message); + + trap->Print("%s %s\n", targetName, message); + return; + } + + clientkilled: + + // check for kill messages from the current clientNum + if (attacker == cg.snap->ps.clientNum) { + char s[MAX_STRING_CHARS] = {0}; + + if (cg_killMessage.integer != 2 && cgs.gametype < GT_TEAM && cgs.gametype != GT_DUEL && + cgs.gametype != GT_POWERDUEL) { + if (cgs.gametype == GT_JEDIMASTER && + attacker < MAX_CLIENTS && + !ent->isJediMaster && + !cg.snap->ps.isJediMaster && + CG_ThereIsAMaster()) { + char part1[512]; + char part2[512]; + trap->SE_GetStringTextString("MP_INGAME_KILLED_MESSAGE", part1, sizeof(part1)); + trap->SE_GetStringTextString("MP_INGAME_JMKILLED_NOTJM", part2, sizeof(part2)); + Com_sprintf(s, sizeof(s), "%s %s\n%s\n", part1, targetName, part2); + } else if (cgs.gametype == GT_JEDIMASTER && + attacker < MAX_CLIENTS && + !ent->isJediMaster && + !cg.snap->ps.isJediMaster) { //no JM, saber must be out + char part1[512]; + trap->SE_GetStringTextString("MP_INGAME_KILLED_MESSAGE", part1, sizeof(part1)); + /* + kmsg1 = "for 0 points.\nGo for the saber!"; + strcpy(part2, kmsg1); + + Com_sprintf(s, sizeof(s), "%s %s %s\n", part1, targetName, part2); + */ + Com_sprintf(s, sizeof(s), "%s %s\n", part1, targetName); + } else if (cgs.gametype == GT_POWERDUEL) { + Q_strncpyz(s, "", sizeof(s)); + } else { + char sPlaceWith[256]; + char sKilledStr[256]; + trap->SE_GetStringTextString("MP_INGAME_PLACE_WITH", sPlaceWith, sizeof(sPlaceWith)); + trap->SE_GetStringTextString("MP_INGAME_KILLED_MESSAGE", sKilledStr, sizeof(sKilledStr)); + + Com_sprintf(s, sizeof(s), "%s %s\n%s %s %i.", sKilledStr, targetName, + CG_PlaceString(cg.snap->ps.persistant[PERS_RANK] + 1), + sPlaceWith, + cg.snap->ps.persistant[PERS_SCORE]); + } + } else { + char sKilledStr[256]; + trap->SE_GetStringTextString("MP_INGAME_KILLED_MESSAGE", sKilledStr, sizeof(sKilledStr)); + Com_sprintf(s, sizeof(s), "%s %s", sKilledStr, targetName); + } + + if (cg_killMessage.integer == 1 || + cg_killMessage.integer == 2)//JAPRO - Clientside - Toggle Kill award message + CG_CenterPrintMultiKill(s, SCREEN_HEIGHT * 0.30, BIGCHAR_WIDTH); + else if (cg_killMessage.integer > 2)//JAPRO - Clientside - Toggle Kill award message + CG_CenterPrintMultiKill(s, SCREEN_HEIGHT * 0.10, BIGCHAR_WIDTH); + } + + // check for double client messages + if (!attackerInfo || !attackerInfo->infoValid) { + attacker = ENTITYNUM_WORLD; + Q_strncpyz(attackerName, "noname", sizeof(attackerName)); + } else { + Com_sprintf(attackerName, sizeof(attackerName), "%s%s", attackerInfo->name, S_COLOR_WHITE); + // check for kill messages about the current clientNum + if (target == cg.snap->ps.clientNum) { + Q_strncpyz(cg.killerName, attackerName, sizeof(cg.killerName)); + } + } + + if (attacker != ENTITYNUM_WORLD) { + switch (mod) { + case MOD_STUN_BATON: + message = "KILLED_STUN"; + break; + case MOD_MELEE: + message = "KILLED_MELEE"; + break; + case MOD_SABER: + message = "KILLED_SABER"; + break; + case MOD_BRYAR_PISTOL: + case MOD_BRYAR_PISTOL_ALT: + message = "KILLED_BRYAR"; + break; + case MOD_BLASTER: + message = "KILLED_BLASTER"; + break; + case MOD_TURBLAST: + message = "KILLED_BLASTER"; + break; + case MOD_DISRUPTOR: + case MOD_DISRUPTOR_SPLASH: + message = "KILLED_DISRUPTOR"; + break; + case MOD_DISRUPTOR_SNIPER: + message = "KILLED_DISRUPTORSNIPE"; + break; + case MOD_BOWCASTER: + message = "KILLED_BOWCASTER"; + break; + case MOD_REPEATER: + message = "KILLED_REPEATER"; + break; + case MOD_REPEATER_ALT: + case MOD_REPEATER_ALT_SPLASH: + message = "KILLED_REPEATERALT"; + break; + case MOD_DEMP2: + case MOD_DEMP2_ALT: + message = "KILLED_DEMP2"; + break; + case MOD_FLECHETTE: + message = "KILLED_FLECHETTE"; + break; + case MOD_FLECHETTE_ALT_SPLASH: + message = "KILLED_FLECHETTE_MINE"; + break; + case MOD_ROCKET: + case MOD_ROCKET_SPLASH: + message = "KILLED_ROCKET"; + break; + case MOD_ROCKET_HOMING: + case MOD_ROCKET_HOMING_SPLASH: + message = "KILLED_ROCKET_HOMING"; + break; + case MOD_THERMAL: + case MOD_THERMAL_SPLASH: + message = "KILLED_THERMAL"; + break; + case MOD_TRIP_MINE_SPLASH: + message = "KILLED_TRIPMINE"; + break; + case MOD_TIMED_MINE_SPLASH: + message = "KILLED_TRIPMINE_TIMED"; + break; + case MOD_DET_PACK_SPLASH: + message = "KILLED_DETPACK"; + break; + case MOD_VEHICLE: + case MOD_CONC: + case MOD_CONC_ALT: + message = "KILLED_GENERIC"; + break; + case MOD_FORCE_DARK: + message = "KILLED_DARKFORCE"; + break; + case MOD_SENTRY: + message = "KILLED_SENTRY"; + break; + case MOD_TELEFRAG: + message = "KILLED_TELEFRAG"; + break; + case MOD_CRUSH: + message = "KILLED_GENERIC";//"KILLED_FORCETOSS"; + break; + case MOD_FALLING: + message = "KILLED_FORCETOSS"; + break; + case MOD_TRIGGER_HURT: + message = "KILLED_GENERIC";//"KILLED_FORCETOSS"; + break; + default: + message = "KILLED_GENERIC"; + break; + } + + if (message) { + message = (char *) CG_GetStringEdString("MP_INGAME", message); + + trap->Print("%s %s %s\n", + targetName, message, attackerName); + return; + } + } + + // we don't know what it was + trap->Print("%s %s\n", targetName, (char *) CG_GetStringEdString("MP_INGAME", "DIED_GENERIC")); + } } //========================================================================== diff --git a/codemp/cgame/cg_hud.c b/codemp/cgame/cg_hud.c new file mode 100644 index 0000000000..bf83cf5057 --- /dev/null +++ b/codemp/cgame/cg_hud.c @@ -0,0 +1,49 @@ +/* +=========================================================================== +Copyright (C) 1999 - 2005, Id Software, Inc. +Copyright (C) 2000 - 2013, Raven Software, Inc. +Copyright (C) 2001 - 2013, Activision, Inc. +Copyright (C) 2005 - 2015, ioquake3 contributors +Copyright (C) 2013 - 2015, OpenJK contributors +Copyright (C) 2015 - 2021, EternalJK contributors +Copyright (C) 2015 - 2023, TaystJK contributors + + +This file is part of the TaystJK source code. + +TaystJK is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License version 2 as +published by the Free Software Foundation. + +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, see . +=========================================================================== +*/ + +// +// cg_hud.c - New HUD +// + +#include "cg_local.h" +#include "hud_local.h" + +void CG_InitNewHUD( void ) { + HUD_InitMedia(); + HUD_InitObituary(); +} + +/* +================= +CG_Draw2DNew +================= +*/ + +void CG_Draw2DNew( void ) { + trap->R_SetColor( NULL ); + HUD_DrawObituary(); +} diff --git a/codemp/cgame/cg_local.h b/codemp/cgame/cg_local.h index 72dbeb66e4..d63e9dc8a0 100644 --- a/codemp/cgame/cg_local.h +++ b/codemp/cgame/cg_local.h @@ -35,6 +35,8 @@ along with this program; if not, see . // If you absolutely need something stored, it can either be kept // by the server in the server stored userinfos, or stashed in a cvar. +#define Vector4Copy( a, b ) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) + #define POWERUP_BLINKS 5 #define POWERUP_BLINK_TIME 1000 @@ -2660,6 +2662,9 @@ void CG_Respawn( void ); void CG_TransitionPlayerState( playerState_t *ps, playerState_t *ops ); void CG_CheckChangedPredictableEvents( playerState_t *ps ); +void CG_InitNewHUD( void ); +void CG_Draw2DNew( void ); +void CG_AddObituary( int killer, int victim, meansOfDeath_t mod ); // // cg_siege.c diff --git a/codemp/cgame/cg_main.c b/codemp/cgame/cg_main.c index 5fd9b58db2..cc1399c03b 100644 --- a/codemp/cgame/cg_main.c +++ b/codemp/cgame/cg_main.c @@ -3193,6 +3193,7 @@ Ghoul2 Insert End #endif CG_InitMarkPolys(); + CG_InitNewHUD(); // remove the last loading update cg.infoScreenText[0] = 0; diff --git a/codemp/cgame/cg_xcvar.h b/codemp/cgame/cg_xcvar.h index 29255da68f..c18a665c55 100644 --- a/codemp/cgame/cg_xcvar.h +++ b/codemp/cgame/cg_xcvar.h @@ -409,7 +409,13 @@ XCVAR_DEF( cg_disruptorSpiralColor, "xff2200", NULL, CVAR_ARCHIVE ) XCVAR_DEF( cg_disruptorNew, "0", NULL, CVAR_ARCHIVE ) XCVAR_DEF( cg_ambientSounds, "1", NULL, CVAR_ARCHIVE ) - +XCVAR_DEF( cg_killfeed, "0", NULL, CVAR_ARCHIVE ) +XCVAR_DEF( cg_killfeedX, "0", NULL, CVAR_ARCHIVE ) +XCVAR_DEF( cg_killfeedY, "0", NULL, CVAR_ARCHIVE ) +XCVAR_DEF( cg_killfeedAlignment, "0", NULL, CVAR_ARCHIVE ) +XCVAR_DEF( cg_killfeedIconSize, "12", NULL, CVAR_ARCHIVE ) +XCVAR_DEF( cg_killfeedTextSize, "0.8", NULL, CVAR_ARCHIVE ) +XCVAR_DEF( cg_killfeedColors, "0", NULL, CVAR_ARCHIVE ) #undef XCVAR_DEF diff --git a/codemp/cgame/hud_local.h b/codemp/cgame/hud_local.h new file mode 100644 index 0000000000..e432e02808 --- /dev/null +++ b/codemp/cgame/hud_local.h @@ -0,0 +1,68 @@ +/* +=========================================================================== +Copyright (C) 1999 - 2005, Id Software, Inc. +Copyright (C) 2000 - 2013, Raven Software, Inc. +Copyright (C) 2001 - 2013, Activision, Inc. +Copyright (C) 2005 - 2015, ioquake3 contributors +Copyright (C) 2013 - 2015, OpenJK contributors +Copyright (C) 2015 - 2021, EternalJK contributors +Copyright (C) 2015 - 2023, TaystJK contributors + + +This file is part of the TaystJK source code. + +TaystJK is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License version 2 as +published by the Free Software Foundation. + +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, see . +=========================================================================== +*/ + +#if !defined( HUD_LOCAL_H ) +#define HUD_LOCAL_H + + +#define MAX_OBITUARY 8 +#define OBITUARY_TIMEOUT 2500 +#define OBITUARY_FADEOUTTIME 2000 +#define OBITUARY_ICON_SIZE 18.0f +#define OBITUARY_TEXT_SIZE 2.0f + +#define OBITUARY_PADDING_SCALAR 0.2f + +enum KillfeedAlignment +{ + KF_RIGHT, + KF_LEFT, + KF_CENTER, +}; + +typedef struct { + int killer; + int victim; + meansOfDeath_t mod; + int time; +} obituary_t; + +typedef struct { + qhandle_t deathIcon; // for generic kill message + qhandle_t modIcon[MOD_MAX]; // means of death icons +} hudMedia_t; + +extern hudMedia_t hm; +extern vec4_t hudModColors[MOD_MAX]; +extern const char *hudModIcons[MOD_MAX]; + +// get all the required assets +void HUD_InitMedia( void ); +void HUD_InitObituary( void ); +void HUD_DrawObituary( void ); +void HUD_InitKFAlignment( void ); +#endif diff --git a/codemp/cgame/hud_obituary.c b/codemp/cgame/hud_obituary.c new file mode 100644 index 0000000000..b7173d6035 --- /dev/null +++ b/codemp/cgame/hud_obituary.c @@ -0,0 +1,228 @@ +/* +=========================================================================== +Copyright (C) 1999 - 2005, Id Software, Inc. +Copyright (C) 2000 - 2013, Raven Software, Inc. +Copyright (C) 2001 - 2013, Activision, Inc. +Copyright (C) 2005 - 2015, ioquake3 contributors +Copyright (C) 2013 - 2015, OpenJK contributors +Copyright (C) 2015 - 2021, EternalJK contributors +Copyright (C) 2015 - 2023, TaystJK contributors + + +This file is part of the TaystJK source code. + +TaystJK is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License version 2 as +published by the Free Software Foundation. + +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, see . +=========================================================================== +*/ + +#include "../qcommon/q_shared.h" +#include "cg_local.h" +#include "hud_local.h" + +static int killfeedAlignment; +static obituary_t hudObituary[MAX_OBITUARY]; +static int hudNumObituary; +static float kfXOffset, kfYOffset, kfTextSize, kfIconSize; +void HUD_InitObituary(void) { + hudNumObituary = 0; +} + +void HUD_InitKFAlignment(void) { + killfeedAlignment = cg_killfeedAlignment.integer; + kfXOffset = cg_killfeedX.value; + kfYOffset = cg_killfeedY.value; + kfIconSize = cg_killfeedIconSize.value; + kfTextSize = cg_killfeedTextSize.value; +} + +static void HUD_PurgeObituary(void) { + static obituary_t obituary[MAX_OBITUARY]; + int i, numObituary; + memcpy(obituary, hudObituary, sizeof(obituary)); + numObituary = 0; + for (i = 0; i < hudNumObituary; i++) { + if (cg.time - obituary[i].time > OBITUARY_TIMEOUT) { + continue; + } + memcpy( &hudObituary[numObituary], &obituary[i], sizeof(obituary_t)); + numObituary++; + } + hudNumObituary = numObituary; +} + +void HUD_DrawObituary(void) { + qboolean suicide = qfalse; + static float color[4] = {1.0f,1.0f,1.0f,1.0f}; + static float blueTeam[4] = {0.0f,0.0f,1.0f,0.15f}; + static float redTeam[4] = {1.0f,0.0f,0.0f,0.15f}; + static float playerColor[4] = {0.0f,1.0f,0.0f,0.15f}; + static float neutralColor[4] = {0.6f,0.6f,0.6f, 0.15f }; + float x, y, iconSize, iconHeight, iconWidth, padding, xPadding, yPadding, textScale, textHeight, killerTextHeight, victimTextHeight, boxCenterY, boxCenterX; + float wepColor[4], killerColor[4], victimColor[4]; + float killerTextWidth, victimTextWidth, totalWidth, maxHeight, victimTextStartY, killerTextStartY; + obituary_t *p; + qhandle_t deathIcon; + + HUD_PurgeObituary(); + + // Set up the killfeed + if(cg_killfeedIconSize.value) + iconSize = kfIconSize; + else + iconSize = OBITUARY_ICON_SIZE; + + if(cg_killfeedTextSize.value) + textScale = kfTextSize; + else + textScale = OBITUARY_TEXT_SIZE; + + y = 10.0f + kfYOffset; + padding = OBITUARY_PADDING_SCALAR; + iconWidth = (iconSize * cgs.widthRatioCoef); + iconHeight = iconSize; + + for (p = hudObituary; p < hudObituary + hudNumObituary; p++) { + // Set the method of death icon + if(hm.modIcon[p->mod]) + deathIcon = hm.modIcon[p->mod]; + else + deathIcon = hm.modIcon[MOD_UNKNOWN]; + // Set the icons' color + if(cg_killfeedColors.integer){ + wepColor[0] = hudModColors[p->mod][0]; + wepColor[1] = hudModColors[p->mod][1]; + wepColor[2] = hudModColors[p->mod][2]; + } else { + wepColor[0] = color[0]; + wepColor[1] = color[0]; + wepColor[2] = color[0]; + } + // Set the box colors based on game type + if (cgs.gametype >= GT_TEAM) { + // Use a neutral grey color + Vector4Copy(neutralColor, victimColor); + Vector4Copy(neutralColor, killerColor); + // Get the killer's team color + if (cgs.clientinfo[p->killer].team == TEAM_BLUE) { + Vector4Copy(blueTeam, killerColor); + } else if (cgs.clientinfo[p->killer].team == TEAM_RED) { + Vector4Copy(redTeam, killerColor); + } + // Check if it's the local player + if (p->killer == cg.snap->ps.clientNum) { + Vector4Copy(playerColor, killerColor); + } + // Get the victim's team color + if (cgs.clientinfo[p->victim].team == TEAM_BLUE) { + Vector4Copy(blueTeam, victimColor); + } else if (cgs.clientinfo[p->victim].team == TEAM_RED) { + Vector4Copy(redTeam, victimColor); + } + // Check if it's the local player + if (p->victim == cg.snap->ps.clientNum) { + Vector4Copy(playerColor, victimColor); + } + } else { + // Use a neutral grey color + Vector4Copy(neutralColor, victimColor); + Vector4Copy(neutralColor, killerColor); + // Unless it's the local player + if (p->killer == cg.snap->ps.clientNum) { + Vector4Copy(playerColor, killerColor); + } + if (p->victim == cg.snap->ps.clientNum) { + Vector4Copy(playerColor, victimColor); + } + } + // Fade the obituaries + if (cg.time - p->time > OBITUARY_FADEOUTTIME) { + color[3] = 1.0f - ((float)cg.time - (float)p->time - OBITUARY_FADEOUTTIME) / (OBITUARY_TIMEOUT - OBITUARY_FADEOUTTIME); + } else { + color[3] = 1.0f; + } + // Only fade the boxes if the new fade is less than our current opacity + killerColor[3] = fminf(0.25f * color[3], killerColor[3]); + victimColor[3] = fminf(0.25f * color[3], victimColor[3]); + wepColor[3] = color[3]; + //Get the sizes of everything + if((p->killer == p->victim) || (p->killer == ENTITYNUM_WORLD)) { //is it a suicide + suicide = qtrue; + victimTextWidth = CG_Text_Width(cgs.clientinfo[p->victim].name, textScale, FONT_MEDIUM); + victimTextHeight = (float)CG_Text_Height(cgs.clientinfo[p->victim].name, textScale, FONT_MEDIUM); + textHeight = victimTextHeight; + } else { + victimTextWidth = CG_Text_Width(cgs.clientinfo[p->victim].name, textScale, FONT_MEDIUM); + victimTextHeight = (float)CG_Text_Height(cgs.clientinfo[p->victim].name, textScale, FONT_MEDIUM); + killerTextWidth = CG_Text_Width(cgs.clientinfo[p->killer].name, textScale, FONT_MEDIUM); + killerTextHeight = (float)CG_Text_Height(cgs.clientinfo[p->killer].name, textScale, FONT_MEDIUM); + textHeight = fmaxf(killerTextHeight, victimTextHeight); + } + maxHeight = fmaxf(iconHeight, textHeight); + xPadding = (padding * maxHeight * cgs.widthRatioCoef); + yPadding = (padding * maxHeight); + boxCenterY = y + ((maxHeight + yPadding) / 2.0f); + victimTextStartY = boxCenterY - 0.75f * victimTextHeight; + boxCenterX = ((maxHeight * cgs.widthRatioCoef + xPadding) / 2.0f); + if(!suicide) { + killerTextStartY = boxCenterY - 0.75f * killerTextHeight; + totalWidth = killerTextWidth + victimTextWidth + (3.0f * xPadding) + (2.0f * boxCenterX); + } else { + totalWidth = victimTextWidth + (1.5f * xPadding) + (2.0f * boxCenterX); + } + //offset the allignment + switch (killfeedAlignment){ + case KF_RIGHT: + x = SCREEN_WIDTH - totalWidth - (10.0f + kfXOffset) * cgs.widthRatioCoef; + break; + case KF_LEFT: + x = (10.0f + kfXOffset) * cgs.widthRatioCoef; + break; + case KF_CENTER: + x = (SCREEN_WIDTH - totalWidth) * 0.5f + kfXOffset; + break; + default: + x = kfXOffset; + } + + //Draw the killfeed + if(!suicide) { + CG_FillRect(x, y, killerTextWidth + xPadding, maxHeight + yPadding, killerColor); + CG_Text_Paint(x + 0.5f * xPadding, killerTextStartY, textScale, color, cgs.clientinfo[p->killer].name, 0, 0, 0, FONT_MEDIUM); + x += killerTextWidth + xPadding; + } + trap->R_SetColor(wepColor); + CG_DrawPic(x + boxCenterX - 0.5f * iconWidth, boxCenterY - 0.5f * iconHeight, iconWidth, iconHeight, deathIcon); + trap->R_SetColor(NULL); + x += (boxCenterX * 2.0f); + CG_FillRect(x, y, victimTextWidth + xPadding, maxHeight + yPadding, victimColor); + CG_Text_Paint(x + (0.5f * xPadding), victimTextStartY, textScale, color, cgs.clientinfo[p->victim].name, 0, 0, 0, FONT_MEDIUM); + + y += boxCenterY + yPadding; + } +} + +void CG_AddObituary(int killer, int victim, meansOfDeath_t mod) { + int i; + HUD_InitKFAlignment(); + if (hudNumObituary == MAX_OBITUARY) { + for (i = 0; i < MAX_OBITUARY - 1; i++) { + memcpy(&hudObituary[i], &hudObituary[i + 1], sizeof(obituary_t)); + } + hudNumObituary--; + } + hudObituary[hudNumObituary].killer = killer; + hudObituary[hudNumObituary].victim = victim; + hudObituary[hudNumObituary].mod = mod; + hudObituary[hudNumObituary].time = cg.time; + hudNumObituary++; +} \ No newline at end of file diff --git a/codemp/cgame/hud_shared.c b/codemp/cgame/hud_shared.c new file mode 100644 index 0000000000..65a7627621 --- /dev/null +++ b/codemp/cgame/hud_shared.c @@ -0,0 +1,132 @@ +/* +=========================================================================== +Copyright (C) 1999 - 2005, Id Software, Inc. +Copyright (C) 2000 - 2013, Raven Software, Inc. +Copyright (C) 2001 - 2013, Activision, Inc. +Copyright (C) 2005 - 2015, ioquake3 contributors +Copyright (C) 2013 - 2015, OpenJK contributors +Copyright (C) 2015 - 2021, EternalJK contributors +Copyright (C) 2015 - 2023, TaystJK contributors + + +This file is part of the TaystJK source code. + +TaystJK is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License version 2 as +published by the Free Software Foundation. + +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, see . +=========================================================================== +*/ + +#include "cg_local.h" +#include "hud_local.h" + +vec4_t hudModColors[MOD_MAX] = { + { 1.0f, 1.0f, 1.0f, 1.0f }, // MOD_UNKNOWN + { 0.0f, 1.0f, 1.0f, 1.0f }, // MOD_STUN_BATON + { 1.0f, 1.0f, 0.0f, 1.0f }, // MOD_MELEE + { 0.5f, 0.0f, 1.0f, 1.0f }, // MOD_SABER + { 0.0f, 1.0f, 1.0f, 1.0f }, // MOD_BRYAR_PISTOL + { 0.0f, 1.0f, 1.0f, 1.0f }, // MOD_BRYAR_PISTOL_ALT + { 0.0f, 1.0f, 0.5f, 1.0f }, // MOD_BLASTER + { 0.0f, 1.0f, 0.5f, 1.0f }, // MOD_TURBLAST + { 0.0f, 1.0f, 0.0f, 1.0f }, // MOD_DISRUPTOR + { 0.0f, 1.0f, 0.0f, 1.0f }, // MOD_DISRUPTOR_SPLASH + { 0.0f, 1.0f, 0.0f, 1.0f }, // MOD_DISRUPTOR_SNIPER + { 0.0f, 1.0f, 0.5f, 1.0f }, // MOD_BOWCASTER + { 0.0f, 0.0f, 1.0f, 1.0f }, // MOD_REPEATER + { 0.0f, 0.0f, 1.0f, 1.0f }, // MOD_REPEATER_ALT + { 0.0f, 0.0f, 1.0f, 1.0f }, // MOD_REPEATER_ALT_SPLASH + { 0.5f, 1.0f, 0.0f, 1.0f }, // MOD_DEMP2 + { 0.5f, 1.0f, 0.0f, 1.0f }, // MOD_DEMP2_ALT + { 1.0f, 0.5f, 0.0f, 1.0f }, // MOD_FLECHETTE + { 1.0f, 0.5f, 0.0f, 1.0f }, // MOD_FLECHETTE_ALT_SPLASH + { 1.0f, 0.0f, 0.0f, 1.0f }, // MOD_ROCKET + { 1.0f, 0.0f, 0.0f, 1.0f }, // MOD_ROCKET_SPLASH + { 1.0f, 0.0f, 0.0f, 1.0f }, // MOD_ROCKET_HOMING + { 1.0f, 0.0f, 0.0f, 1.0f }, // MOD_ROCKET_HOMING_SPLASH + { 1.0f, 0.4f, 0.0f, 1.0f }, // MOD_THERMAL + { 1.0f, 0.4f, 0.0f, 1.0f }, // MOD_THERMAL_SPLASH + { 1.0f, 1.0f, 0.4f, 1.0f }, // MOD_TRIP_MINE_SPLASH + { 1.0f, 1.0f, 0.4f, 1.0f }, // MOD_TIMED_MINE_SPLASH + { 1.0f, 0.4f, 0.0f, 1.0f }, // MOD_DET_PACK_SPLASH + { 0.0f, 1.0f, 0.0f, 1.0f }, // MOD_VEHICLE + { 1.0f, 0.0f, 1.0f, 1.0f }, // MOD_CONC + { 1.0f, 0.0f, 1.0f, 1.0f }, // MOD_CONC_ALT + { 1.0f, 0.4f, 0.0f, 1.0f }, // MOD_FORCE_DARK + { 1.0f, 1.0f, 1.0f, 1.0f }, // MOD_SENTRY + { 0.0f, 0.0f, 1.0f, 1.0f }, // MOD_WATER + { 0.0f, 1.0f, 0.0f, 1.0f }, // MOD_SLIME + { 1.0f, 0.0f, 0.0f, 1.0f }, // MOD_LAVA + { 0.0f, 0.0f, 0.0f, 1.0f }, // MOD_CRUSH + { 0.4f, 0.2f, 0.3f, 1.0f }, // MOD_TELEFRAG + { 1.0f, 1.0f, 0.6f, 1.0f }, // MOD_FALLING + { 0.5f, 0.2f, 0.7f, 1.0f }, // MOD_SUICIDE + { 0.0f, 1.0f, 0.0f, 1.0f }, // MOD_TARGET_LASER + { 1.0f, 1.0f, 0.6f, 1.0f }, // MOD_TRIGGER_HURT + { 1.0f, 1.0f, 1.0f, 1.0f } // MOD_TEAM_CHANGE +}; + +const char *hudModIcons[ MOD_MAX ] = { + "hud/mod/generic", // MOD_UNKNOWN + "hud/mod/stun", // MOD_STUN_BATON + "hud/mod/melee", // MOD_MELEE + "hud/mod/saber", // MOD_SABER + "hud/mod/pistol", // MOD_BRYAR_PISTOL + "hud/mod/pistol", // MOD_BRYAR_PISTOL_ALT + "hud/mod/rifle", // MOD_BLASTER + "hud/mod/rifle_alt", // MOD_TURBLAST + "hud/mod/disruptor", // MOD_DISRUPTOR + "hud/mod/disruptor", // MOD_DISRUPTOR_SPLASH + "hud/mod/disruptor_alt", // MOD_DISRUPTOR_SNIPER + "hud/mod/bowcaster", // MOD_BOWCASTER + "hud/mod/repeater", // MOD_REPEATER + "hud/mod/repeater_alt", // MOD_REPEATER_ALT + "hud/mod/repeater_alt", // MOD_REPEATER_ALT_SPLASH + "hud/mod/demp2", // MOD_DEMP2 + "hud/mod/demp2_alt", // MOD_DEMP2_ALT + "hud/mod/flechette", // MOD_FLECHETTE + "hud/mod/flechette_alt", // MOD_FLECHETTE_ALT_SPLASH + "hud/mod/merrsonn", // MOD_ROCKET + "hud/mod/merrsonn_splash", // MOD_ROCKET_SPLASH + "hud/mod/merrsonn_alt", // MOD_ROCKET_HOMING + "hud/mod/merrsonn_alt", // MOD_ROCKET_HOMING_SPLASH + "hud/mod/thermal", // MOD_THERMAL + "hud/mod/thermal_alt", // MOD_THERMAL_SPLASH + "hud/mod/mine", // MOD_TRIP_MINE_SPLASH + "hud/mod/mine_alt", // MOD_TIMED_MINE_SPLASH + "hud/mod/detpack", // MOD_DET_PACK_SPLASH + "hud/mod/swoop", // MOD_VEHICLE + "hud/mod/concussion", // MOD_CONC + "hud/mod/concussion_alt", // MOD_CONC_ALT + "hud/mod/force", // MOD_FORCE_DARK + "hud/mod/portable_turret", // MOD_SENTRY + "hud/mod/water", // MOD_WATER + "hud/mod/ooze", // MOD_SLIME + "hud/mod/lava", // MOD_LAVA + "hud/mod/crushed", // MOD_CRUSH + "hud/mod/telefrag", // MOD_TELEFRAG + "hud/mod/fall", // MOD_FALLING + "hud/mod/generic", // MOD_SUICIDE + "hud/mod/generic", // MOD_TARGET_LASER + "hud/mod/generic", // MOD_TRIGGER_HURT + "hud/mod/generic", // MOD_TEAM_CHANGE +}; + +hudMedia_t hm; + +// get all the required assets +void HUD_InitMedia( void ) { + int i; + for ( i = 0; i < MOD_MAX; i++ ) { + hm.modIcon[i] = trap->R_RegisterShaderNoMip( hudModIcons[i] ); + } +} + diff --git a/codemp/ui/ui_xdocs.h b/codemp/ui/ui_xdocs.h index d943adccc8..e5f3895fed 100644 --- a/codemp/ui/ui_xdocs.h +++ b/codemp/ui/ui_xdocs.h @@ -444,6 +444,31 @@ XDOCS_CVAR_DEF("g_gametype", "Gametype that the server is currently on", SETTING("9", "CTY") ) +XDOCS_CVAR_DEF("cg_killfeed", "Draw a killfeed on the HUD", +SETTING("0", "Disable the HUD killfeed") NL +SETTING("1", "Draw killfeed HUD") NL +SETTING("2", "Draw killfeed HUD + console death messages") +) + +XDOCS_CVAR_DEF("cg_killfeedAlignment", "Align the killfeed", +SETTING("0", "Align items to the right") NL +SETTING("1", "Align items to the left") NL +SETTING("2", "Align items to the center") +) + +XDOCS_CVAR_DEF("cg_killfeedX", "Offset the killfeed's horizontal position from its current position","" +) + +XDOCS_CVAR_DEF("cg_killfeedY", "Offset the killfeed's vertical position from its current position","" +) + +XDOCS_CVAR_DEF("cg_killfeedIconSize", "Resize the killfeed","" +) +XDOCS_CVAR_DEF("cg_killfeedTextSize", "Resize the killfeed","" +) +XDOCS_CVAR_DEF("cg_killfeedColors", "Color the killfeed icons","" +) + //Work from above this line // ...