From: LegendaryGuard Date: Fri, 16 Apr 2021 20:21:10 +0000 (+0200) Subject: Merge 'LegendaryGuard/ttt' to 'Legendary/bai_mod' X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=74c3d77622fa29de33fa1319f9885b359589781d;p=xonotic%2Fxonotic-data.pk3dir.git Merge 'LegendaryGuard/ttt' to 'Legendary/bai_mod' --- 74c3d77622fa29de33fa1319f9885b359589781d diff --cc gamemodes-server.cfg index 11d49b9e9,f19b435f0..7577822c6 --- a/gamemodes-server.cfg +++ b/gamemodes-server.cfg @@@ -555,4 -564,25 +564,25 @@@ set g_invasion_type 0 "type of invasio set g_duel 0 "Duel: frag the opponent more in a one versus one arena battle" //set g_duel_warmup 180 "Have a short warmup period before beginning the actual duel" set g_duel_with_powerups 0 "Enable powerups to spawn in the duel gamemode" - set g_duel_not_dm_maps 0 "when this is set, DM maps will NOT be listed in duel" + set g_duel_not_dm_maps 0 "when this is set, DM maps will NOT be listed in duel" + + //LegendGuard adds mmm cvars for MMM 20-02-2021 + // ========== + // murder in megaerebus manor + // ========== + set g_mmm 0 "Murder in Megaerebus Manor: A group of space civilians have murderers among them. Murderers must kill civilians, while the civilians have to try to find and kill the murderers" + set g_mmm_not_lms_maps 0 "when this is set, LMS maps will NOT be listed in mmm" + set g_mmm_civilian_count 0.625 "number of players who will become civilians, set between 0 and 0.9 to use a multiplier of the current players, or 1 and above to specify an exact number of players" + //set g_mmm_murderer_count 0.25 "number of players who will become murderers, set between 0 and 0.9 to use a multiplier of the current players, or 1 and above to specify an exact number of players" + set g_mmm_punish_teamkill 0 "enable option to kill the player when they kill an ally" + set g_mmm_reward_civilian 1 "give a point to all civilian players if the round timelimit is reached, in addition to the points given for kills" + set g_mmm_warmup 10 "how long the players will have time to run around the map before the round starts" + set g_mmm_round_timelimit 180 "round time limit in seconds" + set g_mmm_max_karma_points 1000 "limit of maximum number of karma points will have in the server" + set g_mmm_min_karma_points 400 "limit where number of karma points can be reached when are being decreased" + set g_mmm_karma_bankick_tool 0 "tool for strict rules when karma is low: '0' forces player to spec, '1' kicks player, '2' bans player" + set g_mmm_karma_bantime 1800 "number of seconds to ban someone with very low karma" + set g_mmm_karma_damageactive 1 "enable karma damage rule. If a player's karma is low, they will not do as much damage as a player who has high or full karma" + set g_mmm_karma_damagepunishmentdeal 20 "punishment damage points when player kills an ally" + set g_mmm_karma_severity 0.25 "how severe karma is to decrease karma points to the players [0.1 - 1.0]" -set g_mmm_reward_sleuth 1 "give a point to all sleuth players if investigated corpses" ++set g_mmm_reward_sleuth 1 "give a point to all sleuth players if investigated corpses" diff --cc notifications.cfg index 8c5b28bd5,3028b11b9..0ef257f54 --- a/notifications.cfg +++ b/notifications.cfg @@@ -539,7 -543,13 +543,14 @@@ seta notification_CENTER_TEAMCHANGE_SPE seta notification_CENTER_TEAMCHANGE_SUICIDE "1" "0 = off, 1 = centerprint" seta notification_CENTER_TIMEOUT_BEGINNING "1" "0 = off, 1 = centerprint" seta notification_CENTER_TIMEOUT_ENDING "1" "0 = off, 1 = centerprint" + + //LegendGuard adds mmm notification for MMM 20-02-2021 + seta notification_CENTER_MMM_MURDERER "1" "0 = off, 1 = centerprint" + seta notification_CENTER_MMM_MURDERER_WIN "1" "0 = off, 1 = centerprint" + seta notification_CENTER_MMM_CIVILIAN "1" "0 = off, 1 = centerprint" + seta notification_CENTER_MMM_CIVILIAN_WIN "1" "0 = off, 1 = centerprint" + seta notification_CENTER_MMM_SLEUTH "1" "0 = off, 1 = centerprint" + seta notification_CENTER_VEHICLE_ENTER "1" "0 = off, 1 = centerprint" seta notification_CENTER_VEHICLE_ENTER_GUNNER "1" "0 = off, 1 = centerprint" seta notification_CENTER_VEHICLE_ENTER_STEAL "1" "0 = off, 1 = centerprint" diff --cc qcsrc/common/ent_cs.qc index fbce8a70e,211724485..ac4aa8bf3 --- a/qcsrc/common/ent_cs.qc +++ b/qcsrc/common/ent_cs.qc @@@ -161,30 -157,20 +161,36 @@@ ENTCS_PROP(SOLID, true, sv_solid, solid { WriteByte(chan, ent.sv_solid); }, { ent.sv_solid = ReadByte(); }) +// z411 weapon +ENTCS_PROP(ACTIVEWEPID, false, activewepid, activewepid, ENTCS_SET_NORMAL, + { WriteByte(chan, ent.activewepid); }, + { ent.activewepid = ReadByte(); }) + + //LegendGuard adds ENTCS_PROP for MMM 20-02-2021 + // gamemode specific player mmm status (independent of score and frags) + ENTCS_PROP(MMM_STATUS, true, mmm_status, mmm_status, ENTCS_SET_NORMAL, + { WriteShort(chan, ent.mmm_status); }, + { ent.mmm_status = ReadShort(); }) + #ifdef SVQC - int ENTCS_PUBLICMASK = 0; + int ENTCS_PUBLICMASK = 0, ENTCS_PRIVATEMASK = 0; STATIC_INIT(ENTCS_PUBLICMASK) { - FOREACH(EntCSProps, it.m_public, + FOREACH(EntCSProps, true, { - ENTCS_PUBLICMASK |= BIT(it.m_id); + if (it.m_public) + ENTCS_PUBLICMASK |= BIT(it.m_id); + else + ENTCS_PRIVATEMASK |= BIT(it.m_id); + }); + } + + void entcs_update_players(entity player) + { + FOREACH_CLIENT(it != player && IS_PLAYER(it), + { + CS(it).entcs.SendFlags |= ENTCS_PRIVATEMASK; }); } diff --cc qcsrc/common/gamemodes/gamemode/mmm/sv_mmm.qc index 000000000,19a3f94f2..74c5b9f5d mode 000000,100644..100644 --- a/qcsrc/common/gamemodes/gamemode/mmm/sv_mmm.qc +++ b/qcsrc/common/gamemodes/gamemode/mmm/sv_mmm.qc @@@ -1,0 -1,957 +1,953 @@@ + #include "sv_mmm.qh" + + //set g_mmm_sleuth_count 0.125 "number of players who will become sleuths, set between 0 and 0.9 to use a multiplier of the current players, or 1 and above to specify an exact number of players" + //float autocvar_g_mmm_sleuth_count = 0.125; //I don't think that it won't be used... + float autocvar_g_mmm_civilian_count = 0.625; + //float autocvar_g_mmm_murderer_count = 0.25; + float autocvar_g_mmm_round_timelimit = 180; + float autocvar_g_mmm_warmup = 10; + bool autocvar_g_mmm_punish_teamkill = false; + bool autocvar_g_mmm_reward_civilian = true; + bool autocvar_g_mmm_reward_sleuth = true; //sleuth reward if investigated corpses + float autocvar_g_mmm_max_karma_points = 1000; //LegendGuard sets Karma points 21-02-2021 + float autocvar_g_mmm_min_karma_points = 400; + int autocvar_g_mmm_karma_bankick_tool = 0; //LegendGuard sets a ban tool for server admins 11-03-2021 + float autocvar_g_mmm_karma_bantime = 1800; //karma ban seconds + bool autocvar_g_mmm_karma_damageactive = true; //LegendGuard sets Karma damage setting if active 20-03-2021 + float autocvar_g_mmm_karma_severity = 0.25; + float autocvar_g_mmm_karma_damagepunishmentdeal = 20; //LegendGuard sets Karma punishment damage setting if player kills an ally 28-03-2021 + // Sleuth is a created team, this team is added inside Civilians team + + void mmm_FakeTimeLimit(entity e, float t) + { + if(!IS_REAL_CLIENT(e)) + return; + #if 0 + msg_entity = e; + WriteByte(MSG_ONE, 3); // svc_updatestat + WriteByte(MSG_ONE, 236); // STAT_TIMELIMIT + if(t < 0) + WriteCoord(MSG_ONE, autocvar_timelimit); + else + WriteCoord(MSG_ONE, (t + 1) / 60); + #else + STAT(MMM_ROUNDTIMER, e) = t; + #endif + } + + void nades_Clear(entity player); + + void karma_Control(entity it) + { + float masksize = autocvar_g_ban_default_masksize; + float bantime = autocvar_g_mmm_karma_bantime; + if(it.karmapoints >= autocvar_g_mmm_max_karma_points) + { + //Resets karmapoints to maintain the maximum + //PrintToChatAll("^3REWARD ^1MAXIMUM RESET"); + GameRules_scoring_add(it, MMM_KARMA, autocvar_g_mmm_max_karma_points - it.karmapoints); + it.karmapoints = autocvar_g_mmm_max_karma_points; + } + else if(it.karmapoints <= autocvar_g_mmm_min_karma_points) + { + switch (autocvar_g_mmm_karma_bankick_tool) + { + //force to spec + case 0: PutObserverInServer(it); return; + //kick + case 1: dropclient(it); return; + //ban and kick + case 2: Ban_KickBanClient(it, bantime, masksize, "Too low karma"); return; + //force to spec + default: PutObserverInServer(it); return; + } + } + } + + void karmaLoseDifference(entity attacker, entity target) + { + if (autocvar_g_mmm_karma_severity <= 0.09) + autocvar_g_mmm_karma_severity = 0.1; + else if (autocvar_g_mmm_karma_severity > 1) + autocvar_g_mmm_karma_severity = 1; + + //BASIC MATH THEORY: example: 1000 * 0.3 * (0.1 + 0.4) * 0.25 // karma points reduce when player attacked to other player + if (target.karmapoints < attacker.karmapoints) + { + float decreasekarma = - ( target.karmapoints * random() * ( 0.1 + random() ) * autocvar_g_mmm_karma_severity ); + GameRules_scoring_add(attacker, MMM_KARMA, decreasekarma); + attacker.karmapoints = attacker.karmapoints + decreasekarma; + } + else if (target.karmapoints > attacker.karmapoints) + { + float decreasekarma = - ( target.karmapoints * random() * ( 0.1 + random() ) * autocvar_g_mmm_karma_severity ); + GameRules_scoring_add(attacker, MMM_KARMA, decreasekarma); + attacker.karmapoints = attacker.karmapoints + decreasekarma; + } + else + { + float decreasekarma = - ( target.karmapoints * random() * ( 0.1 + random() ) * autocvar_g_mmm_karma_severity ); + GameRules_scoring_add(attacker, MMM_KARMA, decreasekarma); + attacker.karmapoints = attacker.karmapoints + decreasekarma; + } + } + + void karmaWinDifference(entity it) + { + GameRules_scoring_add(it, SCORE, 1); // reward civilians who make it to the end of the round time limit + float increasekarma = ( autocvar_g_mmm_min_karma_points * random() * ( 0.1 + random() ) * 0.12 ); + GameRules_scoring_add(it, MMM_KARMA, increasekarma); + it.karmapoints = it.karmapoints + increasekarma; + karma_Control(it); + } + + void mmm_UpdateScores(bool timed_out) + { + // give players their hard-earned kills now that the round is over + FOREACH_CLIENT(true, + { + it.totalfrags += it.mmm_validkills; + if(it.mmm_validkills) + { + GameRules_scoring_add(it, SCORE, it.mmm_validkills); + } + it.mmm_validkills = 0; + // player survived the round + if(IS_PLAYER(it) && !IS_DEAD(it)) // LegendGuard adds something for Karma 21-02-2021 + { + if((autocvar_g_mmm_reward_civilian && timed_out && it.mmm_status == MMM_STATUS_CIVILIAN) + || (autocvar_g_mmm_reward_civilian && !timed_out && it.mmm_status == MMM_STATUS_CIVILIAN)) + { + karmaWinDifference(it); + //PrintToChatAll(sprintf("^2REWARD ^7it.karmapoints: ^1%f", it.karmapoints)); + } + + //Sleuth reward after investigated a corpse + if((autocvar_g_mmm_reward_sleuth && timed_out && it.mmm_status == MMM_STATUS_SLEUTH) + || (autocvar_g_mmm_reward_sleuth && !timed_out && it.mmm_status == MMM_STATUS_SLEUTH)) + { + if (it.investigated == true) + { + karmaWinDifference(it); + it.investigated = false; + } + } + + if(it.mmm_status == MMM_STATUS_MURDERER) + { + karmaWinDifference(it); + //PrintToChatAll(sprintf("^1MURDERER ^7it.karmapoints: ^1%f", it.karmapoints)); + } + } + }); + } + + float mmm_CheckWinner() + { + if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0) + { + // if the match times out, civilians win too! + Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MMM_CIVILIAN_WIN); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_MMM_CIVILIAN_WIN); + FOREACH_CLIENT(true, + { + if(IS_PLAYER(it)) + nades_Clear(it); + mmm_FakeTimeLimit(it, -1); + karma_Control(it); + }); + + mmm_UpdateScores(true); + + allowed_to_spawn = false; + game_stopped = true; + round_handler_Init(5, autocvar_g_mmm_warmup, autocvar_g_mmm_round_timelimit); + return 1; + } + + int civilian_count = 0, murderer_count = 0, sleuth_count = 0; + FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it), + { + if(it.mmm_status == MMM_STATUS_CIVILIAN) + civilian_count++; + else if(it.mmm_status == MMM_STATUS_MURDERER) + murderer_count++; + else if(it.mmm_status == MMM_STATUS_SLEUTH) //LegendGuard adds sleuth_count 20-02-2021 + sleuth_count++; + }); + if(civilian_count > 0 && murderer_count > 0) + { + return 0; + } + + if(murderer_count > 0) // murderers win + { + Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MMM_MURDERER_WIN); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_MMM_MURDERER_WIN); + } + else if(civilian_count > 0) // civilians win + { + Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MMM_CIVILIAN_WIN); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_MMM_CIVILIAN_WIN); + } + else if (sleuth_count > 0 && civilian_count > 0) // sleuths are same as civilians win + { + Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MMM_CIVILIAN_WIN); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_MMM_CIVILIAN_WIN); + } + else + { + Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ROUND_TIED); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_TIED); + } + + mmm_UpdateScores(false); + + allowed_to_spawn = false; + game_stopped = true; + round_handler_Init(5, autocvar_g_mmm_warmup, autocvar_g_mmm_round_timelimit); + + FOREACH_CLIENT(true, + { + if(IS_PLAYER(it)) + { + it.respawn_flags = RESPAWN_SILENT; //CSQC print output respawn lib.qh error fix + nades_Clear(it); + } + mmm_FakeTimeLimit(it, -1); + karma_Control(it); + }); + + return 1; + } + + void mmm_RoundStart() + { + allowed_to_spawn = boolean(warmup_stage); + int playercount = 0; + + FOREACH_CLIENT(true, + { + if(IS_PLAYER(it) && !IS_DEAD(it)) + { + ++playercount; + it.mmm_status = MMM_STATUS_CIVILIAN; + } + else + it.mmm_status = 0; // this is mostly a safety check; if a client manages to somehow maintain a mmm status, clear it before the round starts! + it.mmm_validkills = 0; + }); + + int civilian_count = bound(1, ((autocvar_g_mmm_civilian_count >= 1) ? autocvar_g_mmm_civilian_count : floor(playercount * autocvar_g_mmm_civilian_count)), playercount - 1); // 20%, but ensure at least 1 and less than total + int total_civilians = 0; + //int murderer_count = bound(1, ((autocvar_g_mmm_murderer_count >= 1) ? autocvar_g_mmm_murderer_count : floor(playercount * autocvar_g_mmm_murderer_count)), playercount - 1); // 20%, but ensure at least 1 and less than total + int total_murderers = 0; + //int sleuth_count = bound(1, ((autocvar_g_mmm_sleuth_count >= 1) ? autocvar_g_mmm_sleuth_count : floor(playercount * autocvar_g_mmm_sleuth_count)), playercount - 1); // 20%, but ensure at least 1 and less than total + int total_sleuths = 0; + + //civilians TOTAL + FOREACH_CLIENT_RANDOM(IS_PLAYER(it) && !IS_DEAD(it), + { + if(total_civilians >= civilian_count) + break; + //LegendGuard fixes the round start again 22-03-2021 + total_civilians++; + if (total_civilians <= 1) + { + if (total_murderers <= 1) + { + total_murderers++; + it.mmm_status = MMM_STATUS_MURDERER; + } + } + else if (total_civilians == 2) + { + if (total_sleuths >= 1) + break; + else + { + total_sleuths++; + it.mmm_status = MMM_STATUS_SLEUTH; + } + } + else if (total_civilians == 5) + { + if (total_murderers <= 2) + break; + else + { + total_murderers++; + it.mmm_status = MMM_STATUS_MURDERER; + } + } + else if (total_civilians == 6) + { + if (total_sleuths >= 2) + break; + else + { + total_sleuths++; + it.mmm_status = MMM_STATUS_SLEUTH; + } + } + else if (total_civilians == 7) + { + if (total_sleuths >= 3) + break; + else if (total_murderers == 3) + { + total_murderers++; + it.mmm_status = MMM_STATUS_MURDERER; + } + else + { + total_sleuths++; + it.mmm_status = MMM_STATUS_SLEUTH; + } + } + else if (total_civilians >= 8) + { + if (total_sleuths >= 4) + break; + else if (total_murderers == 4) + { + total_murderers++; + it.mmm_status = MMM_STATUS_MURDERER; + } + else + { + total_sleuths++; + it.mmm_status = MMM_STATUS_SLEUTH; + } + } + else + { + total_murderers++; + it.mmm_status = MMM_STATUS_MURDERER; + } + }); + + FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it), + { + float totalmeankarma = ((autocvar_g_mmm_max_karma_points + autocvar_g_mmm_min_karma_points + it.karmapoints) / 3); + karma_Control(it); + it.activekillerrole = false; + + if(it.mmm_status == MMM_STATUS_CIVILIAN) + { + if (it.karmapoints <= totalmeankarma) + { + centerprint(it, strcat(BOLD_OPERATOR, "^1KARMA WARNING!\n^3Here, have the Rifle!")); + GiveWeapon(it, WEP_RIFLE.m_id, OP_PLUS, 1); + } + //Gives Mine Layer weapon to the player + GiveWeapon(it, WEP_MINE_LAYER.m_id, OP_PLUS, 1); + Send_Notification(NOTIF_ONE_ONLY, it, MSG_CENTER, CENTER_MMM_CIVILIAN); + Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_MMM_CIVILIAN); + //PrintToChatAll(sprintf("^1DEBUG^7: %s is ^2Civilian^7!", it.netname)); + } + else if(it.mmm_status == MMM_STATUS_MURDERER) + { + if (it.karmapoints <= totalmeankarma) + { + centerprint(it, strcat(BOLD_OPERATOR, "^1KARMA WARNING!\n^3Here, have the Rifle!")); + GiveWeapon(it, WEP_RIFLE.m_id, OP_PLUS, 1); + } + //Gives Mine Layer weapon to the player + GiveWeapon(it, WEP_MINE_LAYER.m_id, OP_PLUS, 1); + Send_Notification(NOTIF_ONE_ONLY, it, MSG_CENTER, CENTER_MMM_MURDERER); + Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_MMM_MURDERER); + //PrintToChatAll(sprintf("^1DEBUG^7: %s is ^1Murderer^7!", it.netname)); + } + else if(it.mmm_status == MMM_STATUS_SLEUTH) + { + if (it.karmapoints <= totalmeankarma) + { + centerprint(it, strcat(BOLD_OPERATOR, "^1KARMA WARNING!\n^3Here, have the Rifle!")); + GiveWeapon(it, WEP_RIFLE.m_id, OP_PLUS, 1); + } + //Gives Shockwave and Mine Layer weapon to the player + GiveWeapon(it, WEP_SHOCKWAVE.m_id, OP_PLUS, 1); + GiveWeapon(it, WEP_MINE_LAYER.m_id, OP_PLUS, 1); + Send_Notification(NOTIF_ONE_ONLY, it, MSG_CENTER, CENTER_MMM_SLEUTH); + Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_MMM_SLEUTH); + Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_MMM_WHOISSLEUTH, it.netname); + } + mmm_FakeTimeLimit(it, round_handler_GetEndTime()); + }); + } + + bool mmm_CheckPlayers() + { + static int prev_missing_players; + allowed_to_spawn = true; + int playercount = 0; + + FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it), + { + //PrintToChatAll(sprintf("it.karmapoints ^5begin: ^3%f",it.karmapoints)); + //Karma points start + if (it.karmastarted != true) + { + GameRules_scoring_add(it, MMM_KARMA, autocvar_g_mmm_max_karma_points - it.karmapoints); + it.karmapoints = autocvar_g_mmm_max_karma_points; + it.karmastarted = true; + } + karma_Control(it); + ++playercount; + //PrintToChatAll(sprintf("it.karmapoints ^6end: ^3%f",it.karmapoints)); + }); + + if (playercount >= 2) + { + if(prev_missing_players > 0) + Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_MISSING_PLAYERS); + prev_missing_players = -1; + return true; + } + + if(playercount == 0) + { + if(prev_missing_players > 0) + Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_MISSING_PLAYERS); + prev_missing_players = -1; + return false; + } + + // if we get here, only 1 player is missing + if(prev_missing_players != 1) + { + Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_MISSING_PLAYERS, 1); + prev_missing_players = 1; + } + return false; + } + + bool mmm_isEliminated(entity e) + { + if(e.caplayer == 1 && (IS_DEAD(e) || e.frags == FRAGS_PLAYER_OUT_OF_GAME)) + return true; + if(e.caplayer == 0.5) + return true; + return false; + } + + void mmm_Initialize() // run at the start of a match, initiates game mode + { + GameRules_scoring(0, SFL_SORT_PRIO_PRIMARY, 0, { + field(SP_MMM_KARMA, "karma", SFL_SORT_PRIO_SECONDARY); //LegendGuard adds Karma points in the scoreboard 22-02-2021 + }); + + allowed_to_spawn = true; + round_handler_Spawn(mmm_CheckPlayers, mmm_CheckWinner, mmm_RoundStart); + round_handler_Init(5, autocvar_g_mmm_warmup, autocvar_g_mmm_round_timelimit); + EliminatedPlayers_Init(mmm_isEliminated); + } + + void checkWeaponDeathtype(entity target, float deathtype) + { + switch (deathtype) + { + case WEP_ARC.m_id: case 276: case 788: target.killedwithweapon = "Impacted by the Arc's electric shock"; return; + case WEP_BLASTER.m_id: case 513: target.killedwithweapon = "Blasted by the Blaster"; return; + case WEP_CRYLINK.m_id: case 263: case 519: target.killedwithweapon = "Shot by the Crylink"; return; + case WEP_DEVASTATOR.m_id: case 522: case 1546: target.killedwithweapon = "Bombarded by the Devastator"; return; + case WEP_ELECTRO.m_id: case 262: case 518: case 1542: target.killedwithweapon = "Electrocuted by the Electro"; return; + case WEP_FIREBALL.m_id: case 273: case 529: case 1297: target.killedwithweapon = "Burned by the Fireball"; return; + case WEP_HAGAR.m_id: case 265: target.killedwithweapon = "Gunned by the Hagar"; return; + case WEP_HLAC.m_id: case 270: case 526: target.killedwithweapon = "Cut down with the HLAC"; return; + case WEP_HOOK.m_id: case 1805: target.killedwithweapon = "Caught in Hook gravity bomb"; return; + case WEP_MACHINEGUN.m_id: target.activekillerrole = true; target.killedwithweapon = "Riddled full of holes by the Machine Gun"; return; + case WEP_MINE_LAYER.m_id: case 517: case 1541: target.killedwithweapon = "Exploited by the Mine Layer"; return; + case WEP_MORTAR.m_id: case 516: case 1284: target.killedwithweapon = "Blew up with the Mortar"; return; + case WEP_OVERKILL_NEX.m_id: target.killedwithweapon = "Sniped by the Overkill Nex"; return; + case WEP_RIFLE.m_id: case 272: target.activekillerrole = true; target.killedwithweapon = "Sniped by the Rifle"; return; + case WEP_SEEKER.m_id: case 274: case 786: target.killedwithweapon = "Blasted by the Seeker"; return; + case WEP_SHOCKWAVE.m_id: target.killedwithweapon = "Gunned down by the Shockwave"; return; + case 275: target.killedwithweapon = "Knocked by the Shockwave"; return; + case WEP_SHOTGUN.m_id: target.activekillerrole = true; target.killedwithweapon = "Shot by Shotgun"; return; + case 258: target.killedwithweapon = "Knocked by the Shotgun"; return; + case WEP_TUBA.m_id: target.killedwithweapon = "Ear pain by the @!#%'n Tuba"; return; + case WEP_VAPORIZER.m_id: case 257: case 769: target.killedwithweapon = "Sniped by the Vaporizer"; return; + case WEP_VORTEX.m_id: target.killedwithweapon = "Sniped by the Vortex"; return; + case DEATH_FALL.m_id: target.killedwithweapon = "Fall"; return; + case DEATH_FIRE.m_id: target.killedwithweapon = "Burned with the fire"; return; + case DEATH_LAVA.m_id: target.killedwithweapon = "Burned in lava"; return; + case DEATH_MIRRORDAMAGE.m_id: target.killedwithweapon = "Suicide"; return; + case DEATH_SLIME.m_id: target.killedwithweapon = "Melted in slime"; return; + case DEATH_TELEFRAG.m_id: target.killedwithweapon = "Telefragged"; return; + case DEATH_NADE.m_id: target.killedwithweapon = "Blown up by the nade"; return; + case DEATH_NADE_NAPALM.m_id: target.killedwithweapon = "Burned by the Napalm nade"; return; + case DEATH_NADE_ICE.m_id: target.killedwithweapon = "Frozen by the Ice nade"; return; + case DEATH_NADE_HEAL.m_id: target.killedwithweapon = "Sucked by the Heal nade"; return; + default: target.killedwithweapon = "Unknown"; return; + } + } + + void ReduceKarmaPointsandFrags(entity frag_attacker, entity frag_target, float frag_deathtype, entity wep_ent) + { + karmaLoseDifference(frag_attacker, frag_target); + GiveFrags(frag_attacker, frag_target, ((autocvar_g_mmm_punish_teamkill) ? -1 : -2), frag_deathtype, wep_ent.weaponentity_fld); + frag_target.whokilled = frag_attacker.netname; + } + + // ============== + // Hook Functions + // ============== + + MUTATOR_HOOKFUNCTION(mmm, ClientObituary) + { + // LegendGuard's IDEA: To adjust the grade of severity of karma, + // we could add if sentence per weapons and adjust each weapon attack + // its own grade. Instead doing random decrease grade 22-02-2021 + + // in mmm, announcing a frag would tell everyone who the murderer is + entity frag_attacker = M_ARGV(1, entity); + entity frag_target = M_ARGV(2, entity); + + if(IS_PLAYER(frag_attacker) && frag_attacker != frag_target) + { + float frag_deathtype = M_ARGV(3, float); + entity wep_ent = M_ARGV(4, entity); + + //PrintToChatAll(strcat("deathtype var: ", ftos(frag_deathtype))); + checkWeaponDeathtype(frag_target, frag_deathtype); + // "team" kill, a point is awarded to the player by default so we must take it away plus an extra one + // unless the player is going to be punished for suicide, in which case just remove one + if(frag_attacker.mmm_status == frag_target.mmm_status) + { + //PrintToChatAll("^1DEBUG^7: A ^2PLAYER^7 has fragged a ^2PLAYER OF HIS OWN TEAM^7, TOO BAD!"); + ReduceKarmaPointsandFrags(frag_attacker, frag_target, frag_deathtype, wep_ent); + switch (frag_attacker.mmm_status) + { + case MMM_STATUS_CIVILIAN: frag_target.killerrole = "\n^3Killer role: ^2Civilian"; return; + case MMM_STATUS_MURDERER: frag_target.killerrole = "\n^3Killer role: ^1Murderer"; return; + case MMM_STATUS_SLEUTH: frag_target.killerrole = "\n^3Killer role: ^4Sleuth"; return; + default: return; + } + //PrintToChatAll(sprintf("frag_attacker.karmapoints: ^1%f", frag_attacker.karmapoints)); + } + + if(frag_attacker.mmm_status == MMM_STATUS_SLEUTH) + { + if (frag_target.mmm_status == MMM_STATUS_CIVILIAN || frag_target.mmm_status == MMM_STATUS_SLEUTH) + { + //PrintToChatAll("^1DEBUG^7: A ^4Sleuth^7 fragged an ^2Civilian^7/^4Sleuth^7, TOO BAD!"); + ReduceKarmaPointsandFrags(frag_attacker, frag_target, frag_deathtype, wep_ent); + frag_target.killerrole = "\n^3Killer role: ^4Sleuth"; + //PrintToChatAll(sprintf("frag_attacker.karmapoints: ^1%f", frag_attacker.karmapoints)); + } + else + { + frag_target.whokilled = frag_attacker.netname; + frag_target.killerrole = "\n^3Killer role: ^4Sleuth"; + } + } + + if (frag_attacker.mmm_status == MMM_STATUS_CIVILIAN) + { + if (frag_target.mmm_status == MMM_STATUS_SLEUTH) + { + //PrintToChatAll("^1DEBUG^7: An ^2Civilian^7 fragged a ^4Sleuth^7, TOO BAD!"); + ReduceKarmaPointsandFrags(frag_attacker, frag_target, frag_deathtype, wep_ent); + frag_target.killerrole = "\n^3Killer role: ^2Civilian"; + } + else + { + frag_target.whokilled = frag_attacker.netname; + frag_target.killerrole = "\n^3Killer role: ^2Civilian"; + } + } + + if (frag_attacker.mmm_status == MMM_STATUS_MURDERER) + { + if (frag_target.mmm_status == MMM_STATUS_CIVILIAN) + { + frag_target.whokilled = frag_attacker.netname; + frag_target.killerrole = "\n^3Killer role: ^1Murderer"; + } + else + { + frag_target.whokilled = frag_attacker.netname; + frag_target.killerrole = "\n^3Killer role: ^1Murderer"; + } + } + //if mmm_status is 1, means civilian, 2 means murderer, 3 means sleuth + //PrintToChatAll(sprintf("^1DEBUG^7: frag_attacker.mmm_status is ^3%s^7",ftos(frag_attacker.mmm_status))); + //PrintToChatAll(sprintf("^1DEBUG^7: frag_target.mmm_status is ^3%s^7",ftos(frag_target.mmm_status))); + } + else + { + float frag_deathtype = M_ARGV(3, float); + checkWeaponDeathtype(frag_target, frag_deathtype); + } + + M_ARGV(5, bool) = true; // anonymous attacker + } + + //karma weapon damage, halve the damage attack when player has low karma 20-03-2021 + MUTATOR_HOOKFUNCTION(mmm, Damage_Calculate) + { + entity attacker = M_ARGV(1, entity); + entity target = M_ARGV(2, entity); + float deathtype = M_ARGV(3, float); + float damage = M_ARGV(4, float); + vector force = M_ARGV(6, vector); + string corpsemessagestrcat = ""; + + if (autocvar_g_mmm_karma_damageactive != false) + { + if (IS_PLAYER(attacker)) + { + if(target == attacker) // damage done to yourself + { + damage /= autocvar_g_weapondamagefactor / (attacker.karmapoints / autocvar_g_mmm_max_karma_points); + force /= autocvar_g_weaponforcefactor / (attacker.karmapoints / autocvar_g_mmm_max_karma_points); + } + else if (target != attacker) + { + damage /= autocvar_g_weapondamagefactor / (attacker.karmapoints / autocvar_g_mmm_max_karma_points); + force /= autocvar_g_weaponforcefactor / (attacker.karmapoints / autocvar_g_mmm_max_karma_points); + } + else + { + damage *= autocvar_g_weapondamagefactor; + force *= autocvar_g_weaponforcefactor; + } + } + } + + //CORPSE DETECTION SKILL 21-03-2021 + if(IS_DEAD(target)) + { + //Shockwave weapon as radar gun to check the corpses 22-03-2021 + if(DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE)) + { + if (target.killedwithweapon == "") + target.killedwithweapon = "UNKNOWN CAUSE"; + + if (target.activekillerrole != true) + { + target.killerrole = ""; + target.activekillerrole = false; + } + + string killedbyphrase = strcat("\n^3Killed by:^7 ", target.whokilled, target.killerrole); + string wepkilledphrase = strcat("\n^3Cause:^7 ", target.killedwithweapon); + if (target.whokilled == "") + { + killedbyphrase = ""; + if (target.killedwithweapon == "") + wepkilledphrase = "\n^3Cause:^7 UNKNOWN CAUSE"; + } + + damage = 0; + force = '0 0 0'; + if (target.mmm_status == MMM_STATUS_CIVILIAN) + { + //try to add centerprint message for chat privately if possible + corpsemessagestrcat = strcat("^5DEAD PLAYER DETAILS^7: \n^3Name:^7 ", target.netname, "\n^3Role: ^2Civilian", killedbyphrase, wepkilledphrase); + //centerprint(attacker, strcat(BOLD_OPERATOR, corpsemessagestrcat)); + Send_Notification(NOTIF_ONE_ONLY, attacker, MSG_CENTER, CENTER_MMM_CORPSEDETECTION, corpsemessagestrcat); + Send_Notification(NOTIF_ONE_ONLY, attacker, MSG_INFO, INFO_MMM_CORPSEDETECTION, corpsemessagestrcat); + } + else if (target.mmm_status == MMM_STATUS_MURDERER) + { + corpsemessagestrcat = strcat("^5DEAD PLAYER DETAILS^7: \n^3Name:^7 ", target.netname, "\n^3Role: ^1Murderer", killedbyphrase, wepkilledphrase); + //centerprint(attacker, strcat(BOLD_OPERATOR, corpsemessagestrcat)); + Send_Notification(NOTIF_ONE_ONLY, attacker, MSG_CENTER, CENTER_MMM_CORPSEDETECTION, corpsemessagestrcat); + Send_Notification(NOTIF_ONE_ONLY, attacker, MSG_INFO, INFO_MMM_CORPSEDETECTION, corpsemessagestrcat); + } + else if (target.mmm_status == MMM_STATUS_SLEUTH) + { + corpsemessagestrcat = strcat("^5DEAD PLAYER DETAILS^7: \n^3Name:^7 ", target.netname, "\n^3Role: ^4Sleuth", killedbyphrase, wepkilledphrase); + //centerprint(attacker, strcat(BOLD_OPERATOR, corpsemessagestrcat)); + Send_Notification(NOTIF_ONE_ONLY, attacker, MSG_CENTER, CENTER_MMM_CORPSEDETECTION, corpsemessagestrcat); + Send_Notification(NOTIF_ONE_ONLY, attacker, MSG_INFO, INFO_MMM_CORPSEDETECTION, corpsemessagestrcat); + } + attacker.investigated = true; + } + } + + M_ARGV(4, float) = damage; + M_ARGV(6, vector) = force; + } + + MUTATOR_HOOKFUNCTION(mmm, PlayerPreThink) + { + entity player = M_ARGV(0, entity); + + if(IS_PLAYER(player) || player.caplayer) + { + // update the scoreboard colour display to out the real killer at the end of the round + // running this every frame to avoid cheats + int plcolor = MMM_COLOR_CIVILIAN; + if(player.mmm_status == MMM_STATUS_CIVILIAN && game_stopped) //Civilian status by default + plcolor = MMM_COLOR_CIVILIAN; + if(player.mmm_status == MMM_STATUS_MURDERER && game_stopped) + plcolor = MMM_COLOR_MURDERER; + //LegendGuard adds for Sleuth 21-02-2021 + if(player.mmm_status == MMM_STATUS_SLEUTH)// && game_stopped) + plcolor = MMM_COLOR_SLEUTH; + setcolor(player, plcolor); + } + + //CORPSE FEATURE 10-03-2021 + if (IS_DEAD(player)) + { + player.event_damage = func_null; + //player.health = 0; + player.solid = SOLID_CORPSE; + set_movetype(player, MOVETYPE_STEP); //test with MOVETYPE_TOSS or MOVETYPE_WALK (it's like sliding object) or MOVETYPE_BOUNCE (maybe not good) + } + } + + MUTATOR_HOOKFUNCTION(mmm, PlayerSpawn) + { + entity player = M_ARGV(0, entity); + + player.mmm_status = 0; + player.mmm_validkills = 0; + player.caplayer = 1; + if (!warmup_stage) + eliminatedPlayers.SendFlags |= 1; + } + + MUTATOR_HOOKFUNCTION(mmm, ForbidSpawn) + { + entity player = M_ARGV(0, entity); + + // spectators / observers that weren't playing can join; they are + // immediately forced to observe in the PutClientInServer hook + // this way they are put in a team and can play in the next round + if (!allowed_to_spawn && player.caplayer) + return true; + return false; + } + + MUTATOR_HOOKFUNCTION(mmm, PutClientInServer) + { + entity player = M_ARGV(0, entity); + + if (!allowed_to_spawn && IS_PLAYER(player)) // this is true even when player is trying to join + { + TRANSMUTE(Observer, player); + if (CS(player).jointime != time && !player.caplayer) // not when connecting + { + player.caplayer = 0.5; + Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_JOIN_LATE); + } + } + } + + MUTATOR_HOOKFUNCTION(mmm, reset_map_players) + { + FOREACH_CLIENT(true, { + CS(it).killcount = 0; + it.mmm_status = 0; + mmm_FakeTimeLimit(it, -1); // restore original timelimit + if (!it.caplayer && IS_BOT_CLIENT(it)) + it.caplayer = 1; + if (it.caplayer) + { + TRANSMUTE(Player, it); + it.caplayer = 1; + it.respawn_flags = RESPAWN_SILENT; //CSQC print output respawn lib.qh error fix + PutClientInServer(it); + } + }); + bot_relinkplayerlist(); + return true; + } + + MUTATOR_HOOKFUNCTION(mmm, reset_map_global) + { + allowed_to_spawn = true; + return true; + } + + entity mmm_LastPlayerForTeam(entity this) + { + entity last_pl = NULL; + FOREACH_CLIENT(IS_PLAYER(it) && it != this, { + if (!IS_DEAD(it) && this.mmm_status == it.mmm_status) + { + if (!last_pl) + { + last_pl = it; + } + else + return NULL; + } + }); + return last_pl; + } + + void mmm_LastPlayerForTeam_Notify(entity this) + { + if (!warmup_stage && round_handler_IsActive() && round_handler_IsRoundStarted()) + { + entity pl = mmm_LastPlayerForTeam(this); + if (pl) + Send_Notification(NOTIF_ONE_ONLY, pl, MSG_CENTER, CENTER_ALONE); + } + } + + MUTATOR_HOOKFUNCTION(mmm, PlayerDies) + { + entity frag_attacker = M_ARGV(1, entity); + entity frag_target = M_ARGV(2, entity); + //float frag_deathtype = M_ARGV(3, float); + + mmm_LastPlayerForTeam_Notify(frag_target); + if (!allowed_to_spawn) + { + frag_target.respawn_flags = RESPAWN_DENY; + // prevent unwanted sudden rejoin as spectator and movement of spectator camera + frag_target.respawn_time = time + 2; + } + frag_target.respawn_flags |= RESPAWN_DENY; + frag_target.event_damage = func_null; + frag_target.health = 0; + + if (!warmup_stage) - { + eliminatedPlayers.SendFlags |= 1; - if (IS_BOT_CLIENT(frag_target)) - bot_clear(frag_target); - } + + //if(frag_attacker.mmm_status == frag_target.mmm_status) + // killed an ally! punishment is sentenced + if(frag_attacker.mmm_status == MMM_STATUS_SLEUTH) + { + if (frag_target.mmm_status == MMM_STATUS_CIVILIAN) + { + //PrintToChatAll("^1DEBUG^7: ^4SLEUTH ^1DAMAGE/DEAD^7 HAS TAKEN!"); + Damage(frag_attacker, frag_attacker, frag_attacker, autocvar_g_mmm_karma_damagepunishmentdeal, DEATH_MIRRORDAMAGE.m_id, DMG_NOWEP, frag_attacker.origin, '0 0 0'); + } + } + if (frag_attacker.mmm_status == MMM_STATUS_CIVILIAN) + { + if (frag_target.mmm_status == MMM_STATUS_SLEUTH) + { + //PrintToChatAll("^1DEBUG^7: ^2CIVILIAN ^1DAMAGE/DEAD^7 HAS TAKEN!"); + Damage(frag_attacker, frag_attacker, frag_attacker, autocvar_g_mmm_karma_damagepunishmentdeal, DEATH_MIRRORDAMAGE.m_id, DMG_NOWEP, frag_attacker.origin, '0 0 0'); + } + } + if (frag_attacker.mmm_status == MMM_STATUS_MURDERER) + { + if (frag_target.mmm_status == MMM_STATUS_MURDERER) + { + //PrintToChatAll("^1DEBUG^7: ^1MURDERER ^1DAMAGE/DEAD^7 HAS TAKEN!"); + Damage(frag_attacker, frag_attacker, frag_attacker, autocvar_g_mmm_karma_damagepunishmentdeal, DEATH_MIRRORDAMAGE.m_id, DMG_NOWEP, frag_attacker.origin, '0 0 0'); + } + } + return true; + } + + MUTATOR_HOOKFUNCTION(mmm, ClientDisconnect) + { + entity player = M_ARGV(0, entity); + + if (IS_PLAYER(player) && !IS_DEAD(player)) + mmm_LastPlayerForTeam_Notify(player); + return true; + } + + MUTATOR_HOOKFUNCTION(mmm, MakePlayerObserver) + { + entity player = M_ARGV(0, entity); + + if (IS_PLAYER(player) && !IS_DEAD(player)) + mmm_LastPlayerForTeam_Notify(player); + if (player.killindicator_teamchange == -2) // player wants to spectate + player.caplayer = 0; + if (player.caplayer) + player.frags = FRAGS_PLAYER_OUT_OF_GAME; + if (!warmup_stage) + eliminatedPlayers.SendFlags |= 1; + if (!player.caplayer) + { + player.mmm_validkills = 0; + player.mmm_status = 0; + mmm_FakeTimeLimit(player, -1); // restore original timelimit + return false; // allow team reset + } + return true; // prevent team reset + } + + MUTATOR_HOOKFUNCTION(mmm, Scores_CountFragsRemaining) + { + // announce remaining frags? + return true; + } + + MUTATOR_HOOKFUNCTION(mmm, GiveFragsForKill, CBC_ORDER_FIRST) + { + entity frag_attacker = M_ARGV(0, entity); + if(!warmup_stage && round_handler_IsActive() && round_handler_IsRoundStarted()) + frag_attacker.mmm_validkills += M_ARGV(2, float); + M_ARGV(2, float) = 0; // score will be given to the winner when the round ends + return true; + } + + MUTATOR_HOOKFUNCTION(mmm, AddPlayerScore) + { + // add scorefield for scoreboard here + entity scorefield = M_ARGV(0, entity); + if(scorefield == SP_KILLS || scorefield == SP_DEATHS || scorefield == SP_SUICIDES || scorefield == SP_DMG || scorefield == SP_DMGTAKEN) + M_ARGV(1, float) = 0; // don't report that the player has killed or been killed, that would out them as a murderer! + } + + MUTATOR_HOOKFUNCTION(mmm, CalculateRespawnTime) + { + // no respawn calculations needed, player is forced to spectate anyway + return true; + } + + MUTATOR_HOOKFUNCTION(mmm, Bot_FixCount, CBC_ORDER_EXCLUSIVE) + { + FOREACH_CLIENT(IS_REAL_CLIENT(it), { + if (IS_PLAYER(it) || it.caplayer == 1) + ++M_ARGV(0, int); + ++M_ARGV(1, int); + }); + return true; + } + + MUTATOR_HOOKFUNCTION(mmm, ClientCommand_Spectate) + { + entity player = M_ARGV(0, entity); + + if (player.caplayer) + { + // they're going to spec, we can do other checks + if (autocvar_sv_spectate && (IS_SPEC(player) || IS_OBSERVER(player))) + Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_LEAVE); + return MUT_SPECCMD_FORCE; + } + + return MUT_SPECCMD_CONTINUE; + } + + MUTATOR_HOOKFUNCTION(mmm, GetPlayerStatus) + { + entity player = M_ARGV(0, entity); + + return player.caplayer == 1; + } + + MUTATOR_HOOKFUNCTION(mmm, BotShouldAttack) + { + entity bot = M_ARGV(0, entity); + entity targ = M_ARGV(1, entity); + + if(targ.mmm_status == bot.mmm_status) + { + return true; + } + + // LegendGuard fixed the problem of Sleuths and Civilians attacking each other 26-03-2021 + if(bot.mmm_status == MMM_STATUS_SLEUTH) + { + if(targ.mmm_status == MMM_STATUS_CIVILIAN) + return true; + } + } diff --cc qcsrc/common/notifications/all.inc index 94965fc2d,32273000d..a9ef5cd4c --- a/qcsrc/common/notifications/all.inc +++ b/qcsrc/common/notifications/all.inc @@@ -847,7 -783,15 +860,16 @@@ string multiteam_info_sprintf(string in MSG_CENTER_NOTIF(TIMEOUT_BEGINNING, N_ENABLE, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout begins in ^COUNT"), "") MSG_CENTER_NOTIF(TIMEOUT_ENDING, N_ENABLE, 0, 1, "", CPID_TIMEIN, "1 f1", _("^F4Timeout ends in ^COUNT"), "") + MSG_CENTER_NOTIF(TIMEOUT_ONGOING, N_ENABLE, 0, 0, "", CPID_TIMEIN, "1 f1", _("^F4Match paused"), "") + //LegendGuard adds MSG_CENTER_NOTIF for MMM 20-02-2021 + MSG_CENTER_NOTIF(MMM_MURDERER, N_ENABLE, 0, 0, "", CPID_MMM, "5 0", strcat(BOLD_OPERATOR, _("^BGYou are ^K1Murderer^BG! Kill all the civilians without raising suspicion!")), "") + MSG_CENTER_NOTIF(MMM_MURDERER_WIN, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^K1Murderers^BG win the round"), "") + + MSG_CENTER_NOTIF(MMM_CIVILIAN, N_ENABLE, 0, 0, "", CPID_MMM, "5 0", strcat(BOLD_OPERATOR, _("^BGYou are ^F1Civilian^BG! Try to find out who are murderers and survive until time is up!")), "") + MSG_CENTER_NOTIF(MMM_CIVILIAN_WIN, N_ENABLE, 0, 0, "", CPID_ROUND, "0 0", _("^F1Civilians^BG win the round"), "") + + MSG_CENTER_NOTIF(MMM_SLEUTH, N_ENABLE, 0, 0, "", CPID_MMM, "5 0", strcat(BOLD_OPERATOR, _("^BGYou are ^4Sleuth^BG! Find out who are murderers and protect the civilians!")), "") + MSG_CENTER_NOTIF(MMM_CORPSEDETECTION, N_ENABLE, 1, 0, "s1", CPID_MMM, "4 0", strcat(BOLD_OPERATOR, _("^BG%s")), "") MSG_CENTER_NOTIF(JOIN_PREVENT_MINIGAME, N_ENABLE, 0, 0, "", CPID_Null, "0 0", _("^K1Cannot join given minigame session!"), "" ) diff --cc qcsrc/common/scores.qh index 63e49ae5f,8e1d8e61c..3b00c4da6 --- a/qcsrc/common/scores.qh +++ b/qcsrc/common/scores.qh @@@ -90,27 -86,7 +90,28 @@@ REGISTER_SP(NEXBALL_FAULTS) REGISTER_SP(ONS_TAKES); REGISTER_SP(ONS_CAPS); +REGISTER_SP(MEDAL_AIRSHOT); +REGISTER_SP(MEDAL_DAMAGE); +REGISTER_SP(MEDAL_ELECTROBITCH); +REGISTER_SP(MEDAL_EXCELLENT); +REGISTER_SP(MEDAL_FIRSTBLOOD); +REGISTER_SP(MEDAL_HEADSHOT); +REGISTER_SP(MEDAL_HUMILIATION); +REGISTER_SP(MEDAL_IMPRESSIVE); +REGISTER_SP(MEDAL_YODA); +REGISTER_SP(MEDAL_TELEFRAG); + +REGISTER_SP(MEDAL_ACCURACY); +REGISTER_SP(MEDAL_ASSIST); +REGISTER_SP(MEDAL_CAPTURE); +REGISTER_SP(MEDAL_DEFENSE); +REGISTER_SP(MEDAL_PERFECT); + +REGISTER_SP(MEDAL_KILLSTREAK_03); +REGISTER_SP(MEDAL_KILLSTREAK_05); +REGISTER_SP(MEDAL_KILLSTREAK_10); +REGISTER_SP(MEDAL_KILLSTREAK_15); + REGISTER_SP(MMM_KARMA); //LegendGuard adds REGISTER_SP for MMM Karma points 21-02-2021 #endif