From 1acbe6d49a1827f6609d5a0891d5a8d4b63328c9 Mon Sep 17 00:00:00 2001 From: LegendaryGuard Date: Tue, 23 Mar 2021 00:24:16 +0100 Subject: [PATCH] Enhanced Detective skill weapon feature, a bit of fix, and ammo differences per each role --- gamemodes-server.cfg | 2 +- qcsrc/common/gamemodes/gamemode/ttt/sv_ttt.qc | 164 ++++++++++-------- qcsrc/common/gamemodes/gamemode/ttt/sv_ttt.qh | 3 +- 3 files changed, 94 insertions(+), 75 deletions(-) diff --git a/gamemodes-server.cfg b/gamemodes-server.cfg index 2e9f0e02d..6e058ec4e 100644 --- a/gamemodes-server.cfg +++ b/gamemodes-server.cfg @@ -572,7 +572,7 @@ set g_duel_not_dm_maps 0 "when this is set, DM maps will NOT be listed in duel" // ========== set g_ttt 0 "Trouble in Terrorist Town: A group of space terrorists have traitors among them. Traitors must kill terrorists, while the terrorists have to try to find and kill the traitors" set g_ttt_not_lms_maps 0 "when this is set, LMS maps will NOT be listed in ttt" -set g_ttt_traitor_count 0.25 "number of players who will become traitors, 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_ttt_traitor_count 0.25 "number of players who will become traitors, 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_ttt_punish_teamkill 0 "kill the player when they kill an ally" set g_ttt_reward_innocent 1 "give a point to all innocent players if the round timelimit is reached, in addition to the points given for kills" set g_ttt_warmup 10 "how long the players will have time to run around the map before the round starts" diff --git a/qcsrc/common/gamemodes/gamemode/ttt/sv_ttt.qc b/qcsrc/common/gamemodes/gamemode/ttt/sv_ttt.qc index 945efe506..b68dcf90a 100644 --- a/qcsrc/common/gamemodes/gamemode/ttt/sv_ttt.qc +++ b/qcsrc/common/gamemodes/gamemode/ttt/sv_ttt.qc @@ -3,7 +3,7 @@ //set g_ttt_detective_count 0.125 "number of players who will become detectives, 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_ttt_detective_count = 0.125; //I don't think that it won't be used... float autocvar_g_ttt_innocent_count = 0.625; -float autocvar_g_ttt_traitor_count = 0.25; +//float autocvar_g_ttt_traitor_count = 0.25; float autocvar_g_ttt_round_timelimit = 180; float autocvar_g_ttt_warmup = 10; bool autocvar_g_ttt_punish_teamkill = false; @@ -17,6 +17,7 @@ bool autocvar_g_ttt_karma_damageactive = true; //LegendGuard sets Karma damage s // 27-02-2021 //Ideas: skills/items per each player-type: (these skills/items should be used once) // Innocents: Shield and Strength; Traitors: Shield and Strength; Detectives: skill to detect any player to see what player-type is +// Add for the corpse a role of who killed 22-03-2021 // Detective is a created team, this team is added inside Innocents team @@ -217,7 +218,6 @@ void ttt_RoundStart() allowed_to_spawn = boolean(warmup_stage); int playercount = 0; - // Fix number of detectives to 1 FOREACH_CLIENT(true, { if(IS_PLAYER(it) && !IS_DEAD(it)) @@ -232,17 +232,18 @@ void ttt_RoundStart() int innocent_count = bound(1, ((autocvar_g_ttt_innocent_count >= 1) ? autocvar_g_ttt_innocent_count : floor(playercount * autocvar_g_ttt_innocent_count)), playercount - 1); // 20%, but ensure at least 1 and less than total int total_innocents = 0; - int traitor_count = bound(1, ((autocvar_g_ttt_traitor_count >= 1) ? autocvar_g_ttt_traitor_count : floor(playercount * autocvar_g_ttt_traitor_count)), playercount - 1); // 20%, but ensure at least 1 and less than total + //int traitor_count = bound(1, ((autocvar_g_ttt_traitor_count >= 1) ? autocvar_g_ttt_traitor_count : floor(playercount * autocvar_g_ttt_traitor_count)), playercount - 1); // 20%, but ensure at least 1 and less than total int total_traitors = 0; //int detective_count = bound(1, ((autocvar_g_ttt_detective_count >= 1) ? autocvar_g_ttt_detective_count : floor(playercount * autocvar_g_ttt_detective_count)), playercount - 1); // 20%, but ensure at least 1 and less than total int total_detectives = 0; + //innocents TOTAL FOREACH_CLIENT_RANDOM(IS_PLAYER(it) && !IS_DEAD(it), { if(total_innocents >= innocent_count) break; + //LegendGuard fixes the round start again 22-03-2021 total_innocents++; - //LegendGuard fixes the round start 26-02-2021 if (total_innocents <= 1) { if (total_traitors <= 1) @@ -251,7 +252,7 @@ void ttt_RoundStart() it.ttt_status = TTT_STATUS_TRAITOR; } } - else if (total_innocents == 3) // test this? && total_traitors >= 1) + else if (total_innocents == 3) { if (total_detectives >= 1) break; @@ -261,7 +262,7 @@ void ttt_RoundStart() it.ttt_status = TTT_STATUS_DETECTIVE; } } - else if (total_innocents >= 5) + else if (total_innocents == 5) { if (total_detectives >= 2) break; @@ -271,41 +272,24 @@ void ttt_RoundStart() it.ttt_status = TTT_STATUS_DETECTIVE; } } - else - it.ttt_status = TTT_STATUS_INNOCENT; - }); - - - //traitors TOTAL - FOREACH_CLIENT_RANDOM(IS_PLAYER(it) && !IS_DEAD(it), - { - if(total_traitors >= traitor_count) - break; - if(total_traitors >= 3) + else if (total_innocents >= 7) { - total_traitors++; - it.ttt_status = TTT_STATUS_TRAITOR; - } - total_traitors++; - it.ttt_status = TTT_STATUS_TRAITOR; - }); - - //detectives TOTAL //Hey, is necessary? I don't think so... - /*FOREACH_CLIENT_RANDOM(IS_PLAYER(it) && !IS_DEAD(it), - { - if(total_detectives >= detective_count) - break; - total_detectives++; - //ROUND FIX - if (total_detectives <= 1) - { - if (total_traitors <= 1) - it.ttt_status = TTT_STATUS_INNOCENT; + if (total_detectives >= 3) + break; + else if (total_traitors == 3) + { + total_traitors++; + it.ttt_status = TTT_STATUS_TRAITOR; + } + else + { + total_detectives++; + it.ttt_status = TTT_STATUS_DETECTIVE; + } } else - it.ttt_status = TTT_STATUS_DETECTIVE; - });*/ - + it.ttt_status = TTT_STATUS_TRAITOR; + }); FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it), { @@ -322,12 +306,20 @@ void ttt_RoundStart() if(it.ttt_status == TTT_STATUS_INNOCENT) { + SetResource(it, RES_SHELLS, 50); + SetResource(it, RES_BULLETS, 70); + SetResource(it, RES_ROCKETS, 30); + SetResource(it, RES_CELLS, 60); Send_Notification(NOTIF_ONE_ONLY, it, MSG_CENTER, CENTER_TTT_INNOCENT); Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_TTT_INNOCENT); //PrintToChatAll(sprintf("^1DEBUG^7: %s is ^2Innocent^7!", it.netname)); } else if(it.ttt_status == TTT_STATUS_TRAITOR) { + SetResource(it, RES_SHELLS, 20); + SetResource(it, RES_BULLETS, 60); + SetResource(it, RES_ROCKETS, 20); + SetResource(it, RES_CELLS, 40); Send_Notification(NOTIF_ONE_ONLY, it, MSG_CENTER, CENTER_TTT_TRAITOR); Send_Notification(NOTIF_ONE_ONLY, it, MSG_INFO, INFO_TTT_TRAITOR); //PrintToChatAll(sprintf("^1DEBUG^7: %s is ^1Traitor^7!", it.netname)); @@ -413,6 +405,7 @@ MUTATOR_HOOKFUNCTION(ttt, ClientObituary) // in ttt, announcing a frag would tell everyone who the traitor 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); @@ -429,6 +422,7 @@ MUTATOR_HOOKFUNCTION(ttt, ClientObituary) //PrintToChatAll(sprintf("frag_attacker.karmapoints: ^1%f", frag_attacker.karmapoints)); GiveFrags(frag_attacker, frag_target, ((autocvar_g_ttt_punish_teamkill) ? -1 : -2), frag_deathtype, wep_ent.weaponentity_fld); karma_Control(frag_attacker); + frag_target.whokilled = frag_attacker.netname; //BASIC MATH THEORY: example: 1000 * 0.3 * (0.1 + 0.4) * 0.25 // karma points reduce when player attacked to other player } @@ -444,7 +438,11 @@ MUTATOR_HOOKFUNCTION(ttt, ClientObituary) //PrintToChatAll(sprintf("frag_attacker.karmapoints: ^1%f", frag_attacker.karmapoints)); GiveFrags(frag_attacker, frag_target, ((autocvar_g_ttt_punish_teamkill) ? -1 : -2), frag_deathtype, wep_ent.weaponentity_fld); karma_Control(frag_attacker); + frag_target.whokilled = frag_attacker.netname; } + else + frag_target.whokilled = frag_attacker.netname; + } if (frag_attacker.ttt_status == TTT_STATUS_INNOCENT) @@ -458,7 +456,19 @@ MUTATOR_HOOKFUNCTION(ttt, ClientObituary) frag_attacker.karmapoints = frag_attacker.karmapoints + decreasekarma; GiveFrags(frag_attacker, frag_target, ((autocvar_g_ttt_punish_teamkill) ? -1 : -2), frag_deathtype, wep_ent.weaponentity_fld); karma_Control(frag_attacker); + frag_target.whokilled = frag_attacker.netname; } + else + frag_target.whokilled = frag_attacker.netname; + + } + + if (frag_attacker.ttt_status == TTT_STATUS_TRAITOR) + { + if (frag_target.ttt_status == TTT_STATUS_INNOCENT) + frag_target.whokilled = frag_attacker.netname; + else + frag_target.whokilled = frag_attacker.netname; } //if ttt_status is 1, means innocent, 2 means traitor, 3 means detective, TODO: the bots: frag_attacker(1) shouldn't attack to frag_target(3) //PrintToChatAll(sprintf("^1DEBUG^7: frag_attacker.ttt_status is ^3%s^7",ftos(frag_attacker.ttt_status))); @@ -474,24 +484,29 @@ MUTATOR_HOOKFUNCTION(ttt, 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); - //entity weaponent = M_ARGV(7, entity); - // entity i(entity, MUTATOR_ARGV_7_entity) - //attacker.(weaponentity); if (autocvar_g_ttt_karma_damageactive != false) { - if(target == attacker) // damage done to yourself + if (IS_PLAYER(attacker)) { - damage /= autocvar_g_weaponforcefactor / (attacker.karmapoints / autocvar_g_ttt_max_karma_points); - force /= autocvar_g_weaponforcefactor / (attacker.karmapoints / autocvar_g_ttt_max_karma_points); - } - else - { - damage /= autocvar_g_weapondamagefactor / (attacker.karmapoints / autocvar_g_ttt_max_karma_points); - force /= autocvar_g_weaponforcefactor / (attacker.karmapoints / autocvar_g_ttt_max_karma_points); + if(target == attacker) // damage done to yourself + { + damage /= autocvar_g_weapondamagefactor / (attacker.karmapoints / autocvar_g_ttt_max_karma_points); + force /= autocvar_g_weaponforcefactor / (attacker.karmapoints / autocvar_g_ttt_max_karma_points); + } + else if (target != attacker) + { + damage /= autocvar_g_weapondamagefactor / (attacker.karmapoints / autocvar_g_ttt_max_karma_points); + force /= autocvar_g_weaponforcefactor / (attacker.karmapoints / autocvar_g_ttt_max_karma_points); + } + else + { + damage *= autocvar_g_weapondamagefactor; + force *= autocvar_g_weaponforcefactor; + } } } @@ -500,24 +515,30 @@ MUTATOR_HOOKFUNCTION(ttt, Damage_Calculate) { if(IS_DEAD(target)) { - //TODO: Try using shockwave gun as radar gun to check the corpses 22-03-2021 - damage = 0; - force = '0 0 0'; - if (target.ttt_status == TTT_STATUS_INNOCENT) - { - //try to add centerprint message for chat privately if possible - centerprint(attacker, "^5Role^3: ^2Innocent"); - centerprint(attacker, strcat("^6Name^3:^7 ", target.netname)); - } - else if (target.ttt_status == TTT_STATUS_TRAITOR) - { - centerprint(attacker, "^5Role^3: ^1Traitor"); - centerprint(attacker, strcat("^6Name^3:^7 ", target.netname)); - } - else if (target.ttt_status == TTT_STATUS_DETECTIVE) + //Shockwave weapon as radar gun to check the corpses 22-03-2021 + if(DEATH_ISWEAPON(deathtype, WEP_SHOCKWAVE)) { - centerprint(attacker, "^5Role^3: ^4Detective"); - centerprint(attacker, strcat("^6Name^3:^7 ", target.netname)); + damage = 0; + force = '0 0 0'; + if (target.ttt_status == TTT_STATUS_INNOCENT) + { + //try to add centerprint message for chat privately if possible + centerprint(attacker, strcat("^1Killed by^3:^7 ", target.whokilled)); + centerprint(attacker, "^5Role^3: ^2Innocent"); + centerprint(attacker, strcat("^6Name^3:^7 ", target.netname)); + } + else if (target.ttt_status == TTT_STATUS_TRAITOR) + { + centerprint(attacker, strcat("^1Killed by^3:^7 ", target.whokilled)); + centerprint(attacker, "^5Role^3: ^1Traitor"); + centerprint(attacker, strcat("^6Name^3:^7 ", target.netname)); + } + else if (target.ttt_status == TTT_STATUS_DETECTIVE) + { + centerprint(attacker, strcat("^1Killed by^3:^7 ", target.whokilled)); + centerprint(attacker, "^5Role^3: ^4Detective"); + centerprint(attacker, strcat("^6Name^3:^7 ", target.netname)); + } } } } @@ -550,8 +571,8 @@ MUTATOR_HOOKFUNCTION(ttt, PlayerPreThink) { player.event_damage = func_null; //player.health = 0; - player.solid = SOLID_CORPSE; - set_movetype(player, MOVETYPE_STEP); + player.solid = SOLID_CORPSE; //test hooks with SOLID_SLIDEBOX + set_movetype(player, MOVETYPE_STEP); //test with MOVETYPE_TOSS or MOVETYPE_BOUNCE (maybe not good) } } @@ -671,10 +692,7 @@ MUTATOR_HOOKFUNCTION(ttt, PlayerDies) } //if(frag_attacker.ttt_status == frag_target.ttt_status) - // killed an ally! punishment is death - if(autocvar_g_ttt_punish_teamkill && frag_attacker != frag_target && IS_PLAYER(frag_attacker) && IS_PLAYER(frag_target) && frag_attacker.ttt_status == frag_target.ttt_status && !ITEM_DAMAGE_NEEDKILL(frag_deathtype)) - if(!warmup_stage && round_handler_IsActive() && round_handler_IsRoundStarted()) // don't autokill if the round hasn't - Damage(frag_attacker, frag_attacker, frag_attacker, 100000, DEATH_MIRRORDAMAGE.m_id, DMG_NOWEP, frag_attacker.origin, '0 0 0'); + // killed an ally! punishment is sentenced if(frag_attacker.ttt_status == TTT_STATUS_DETECTIVE) { if (frag_target.ttt_status == TTT_STATUS_INNOCENT) diff --git a/qcsrc/common/gamemodes/gamemode/ttt/sv_ttt.qh b/qcsrc/common/gamemodes/gamemode/ttt/sv_ttt.qh index a9207b35a..0722b8d9c 100644 --- a/qcsrc/common/gamemodes/gamemode/ttt/sv_ttt.qh +++ b/qcsrc/common/gamemodes/gamemode/ttt/sv_ttt.qh @@ -15,4 +15,5 @@ REGISTER_MUTATOR(ttt, false) } .int ttt_validkills; // store the player's valid kills to be given at the end of the match (avoid exposing their score until then) -.float karmapoints; //LegendGuard adds karma points to store player status 22-02-2021 \ No newline at end of file +.float karmapoints; //LegendGuard adds karma points to store player status 22-02-2021 +.string whokilled; //LegendGuard sets a variable to know who killed who 22-03-2021 \ No newline at end of file -- 2.39.2