From: drjaska Date: Sun, 28 Nov 2021 04:44:04 +0000 (+0200) Subject: added weapon support, fixed waypoints, refined runner score stuff and more X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=00d6c86c1791c83fe0692cbbf75be78a45b1e676;p=xonotic%2Fxonotic-data.pk3dir.git added weapon support, fixed waypoints, refined runner score stuff and more --- diff --git a/gamemodes-server.cfg b/gamemodes-server.cfg index 4165e17eb..6a6cf234a 100644 --- a/gamemodes-server.cfg +++ b/gamemodes-server.cfg @@ -577,9 +577,11 @@ set g_mh_not_dm_maps 0 "when this is set, DM maps will NOT be listed in MH" set g_mh_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any" set g_mh_point_limit -1 "MH point limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)" set g_mh_warmup 10 //10 "time players get to run around before the round starts" -set g_mh_round_timelimit 60 //180 "round time limit in seconds" +set g_mh_round_timelimit 120 //180 "round time limit in seconds" set g_mh_how_many_rounds_before_shuffle 1 "how many rounds are played before teams are shuffled automatically" set g_mh_enable_tagging_on_touch 1 "are runners killed when touching hunters?" set g_mh_player_waypoints 1 "0: no waypoints, 1: waypoints on runners, 2: waypoints on everyone" set g_mh_weaponarena " " "starting weapons - takes the same options as g_weaponarena" -set g_mh_unlimited_ammunition 0 "do players consume ammunition when firing" +set g_mh_weapons_damage 0 "0: no damage, 1: only self-damage for runners, 2: only damage opposing team, 3: only allow hunters to damage runners, 4: self-damage and opposing team damage" +set g_mh_weapons_force 1 "0: no force, 1: only self-force, 2: self-force and opposing team force" +set g_mh_limited_ammunition 0 "do players consume ammunition when firing" diff --git a/qcsrc/common/gamemodes/gamemode/mh/TODO.txt b/qcsrc/common/gamemodes/gamemode/mh/TODO.txt index 4dfa6f3c1..cae75cc33 100644 --- a/qcsrc/common/gamemodes/gamemode/mh/TODO.txt +++ b/qcsrc/common/gamemodes/gamemode/mh/TODO.txt @@ -1,17 +1,20 @@ add g_mh_startitem cvars to the balance files -weapon support ++1 waypoint mode, waypoints for runners on round start always and waypoints for hunters when there are 3 or more hunters -fix waypoints on hunters +rename teams as far as possible -score bonus for last survivor +on-screen notification for getting tagged -fix waypoint visibility, currently they are always visible to everyone. Fix them to not be visible for self or for spectators of that player. +on-screen indication for your role -rename teams as far as possible +gamemode icon more dynamicity for the code :) -on-screen notification for getting tagged +add more TODO: notes + -add more TODO: notes \ No newline at end of file + +fix waypoint visibility, currently they are always visible to everyone. Fix them to not be visible for self or for spectators of that player. +can you even see your own null waypoint? \ No newline at end of file diff --git a/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qc b/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qc index 0e3462cd2..a55c7bfde 100644 --- a/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qc +++ b/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qc @@ -49,6 +49,77 @@ MUTATOR_HOOKFUNCTION(mh, PlayerPreThink) } } +MUTATOR_HOOKFUNCTION(mh, Damage_Calculate) +{ + entity frag_attacker = M_ARGV(1, entity); + entity frag_target = M_ARGV(2, entity); + float frag_deathtype = M_ARGV(3, float); + float frag_damage = M_ARGV(4, float); + vector frag_force = M_ARGV(6, vector); + + if(frag_deathtype==DEATH_CAMP.m_id)return; + + if(IS_PLAYER(frag_target) && !IS_DEAD(frag_target)){ //check that the target is a player and not dead, allows anyone to knock around corpses for funsies + + if(frag_deathtype == DEATH_FALL.m_id)frag_damage = 0; //no fall damage or splat damage + + switch(autocvar_g_mh_weapons_damage) + { + // no damage + default: + case 0: { + frag_damage = 0; + break; + } + // only self-damage for runners + case 1: { + if(frag_target != frag_attacker)frag_damage = 0; + break; + } + // only damage opposing team + case 2: { + if(SAME_TEAM(frag_target, frag_attacker))frag_damage = 0; + break; + } + // only allow hunters to damage runners + case 3: { + //print(sprintf("%f", frag_attacker.team)); + //print("\n"); + //print(sprintf("%f", frag_target.team)); + //print("\n"); + if(!((frag_attacker.team==5) && (frag_target.team==14)))frag_damage = 0; + break; + } + // self-damage and opposing team damage + case 4: { + if(frag_target != frag_attacker && SAME_TEAM(frag_target, frag_attacker))frag_damage = 0; + break; + } + } + switch(autocvar_g_mh_weapons_force){ + // no force + case 0: { + frag_force = '0 0 0'; + break; + } + // only self-force + default: + case 1: { + if(frag_target != frag_attacker)frag_force = '0 0 0'; + break; + } + // self-force and opposing team force + case 2: { + if(frag_target != frag_attacker && SAME_TEAM(frag_target, frag_attacker))frag_force = '0 0 0'; + break; + } + } + } + + M_ARGV(4, float) = frag_damage; + M_ARGV(6, vector) = frag_force; +} + MUTATOR_HOOKFUNCTION(mh, SetWeaponArena) { if (M_ARGV(0, string) == "0" || M_ARGV(0, string) == "") @@ -59,6 +130,9 @@ MUTATOR_HOOKFUNCTION(mh, SetWeaponArena) MUTATOR_HOOKFUNCTION(mh, SetStartItems) { start_items &= ~(IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS); + if(!cvar("g_use_ammunition") || autocvar_g_mh_limited_ammunition) + start_items |= IT_UNLIMITED_AMMO; + start_health = warmup_start_health = cvar("g_ca_start_health"); start_armorvalue = warmup_start_armorvalue = cvar("g_ca_start_armor"); start_ammo_shells = warmup_start_ammo_shells = cvar("g_ca_start_ammo_shells"); @@ -106,7 +180,7 @@ MUTATOR_HOOKFUNCTION(mh, GiveFragsForKill, CBC_ORDER_FIRST) // "wtf do these functions do" chart -// all functions: refactor documented: +// functions: refactor documented: // finished: :) // mh_LastPlayerForTeam y y @@ -312,9 +386,16 @@ float MH_CheckWinner() int did_the_round_end = 0; MH_count_players(); int winner_team = MH_GetWinnerTeam(); - if(winner_team == 14) + if(winner_team == 14){ + //(total amount of players divided by total amount of runners) divided by 2[because of initial team split] amount of score per second divided over X ticks per second + //(2 total players / 1 total runner) / 2 = 1 score per second + //(9 total players / 3 total runners) / 2 = 1.5 score per second (5v4 in the beginning and only 1 person has been tagged making it 6v3) + //(10 total players / 1 total runner) / 2 = 5 score per second (5v5 in which only 1 runner is alive, they gain 5 score per second as last alive) + //(10 total players / 9 total runners) / 2 = 0.55556 score per second(1 hunter and 9 runners, doesn't really award runners for stacking for that team) + float survivalscore = (((total_players/(Team_GetNumberOfTotalPlayers(Team_GetTeamFromIndex(2))))/2)/(1/cvar("sys_ticrate"))); FOREACH_CLIENT(IS_PLAYER(it) && it.team == 14, - { GameRules_scoring_add_team(it, SCORE, (0.016666667)); }); //add 1 score to each runner's score per second at 60 tickrate + { GameRules_scoring_add_team(it, SCORE, (survivalscore)); }); //add 1 score to each runner's score per second at 60 tickrate + } if(round_handler_GetEndTime() - time > 0 && winner_team == Team_IndexToTeam(2)){ did_the_round_end = 0; } else if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0 && winner_team == Team_IndexToTeam(2)){ @@ -323,7 +404,7 @@ float MH_CheckWinner() TeamScore_AddToTeam(winner_team, ST_MH_ROUNDS, +1); did_the_round_end = 1; FOREACH_CLIENT(IS_PLAYER(it) && it.team == 14, - { GameRules_scoring_add_team(it, SCORE, (30)); }); //add 30 score to each runner's score + { GameRules_scoring_add_team(it, SCORE, (autocvar_g_mh_round_timelimit)); }); //add score to each runner's score, equal to the round timelimit } else if(winner_team == Team_IndexToTeam(1)){ Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, APP_TEAM_NUM(winner_team, CENTER_ROUND_TEAM_WIN)); //replace with hunters win Send_Notification(NOTIF_ALL, NULL, MSG_INFO, APP_TEAM_NUM(winner_team, INFO_ROUND_TEAM_WIN)); //replace with hunters win @@ -334,7 +415,7 @@ float MH_CheckWinner() Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ROUND_TIED); did_the_round_end = 1; } else { - //print("Error: Ran out of appropriate team win situations\n"); + print("Error: Ran out of appropriate team win situations\n"); } if(did_the_round_end == 0)return 0; @@ -532,7 +613,7 @@ MUTATOR_HOOKFUNCTION(mh, PlayerSpawn) } //player.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = mh_waypointsprite_visible_for_player; if(autocvar_g_mh_player_waypoints == 2){ - if(player.team == Team_IndexToTeam(2)) + if(player.team == Team_IndexToTeam(1)) { WaypointSprite_AttachCarrier(WP_Null, player, RADARICON_FLAGCARRIER); //player.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = mh_waypointsprite_visible_for_player; diff --git a/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qh b/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qh index c12d05121..56d75421e 100644 --- a/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qh +++ b/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qh @@ -11,6 +11,9 @@ bool autocvar_g_mh_team_spawns; float autocvar_g_mh_warmup; float autocvar_g_mh_round_timelimit; string autocvar_g_mh_weaponarena; +int autocvar_g_mh_weapons_damage; +int autocvar_g_mh_weapons_force; +bool autocvar_g_mh_limited_ammunition; int mh_teams; bool allowed_to_spawn_untagged = 1; diff --git a/qcsrc/server/world.qc b/qcsrc/server/world.qc index f85591a9d..da2422121 100644 --- a/qcsrc/server/world.qc +++ b/qcsrc/server/world.qc @@ -457,6 +457,17 @@ void cvar_changes_init() BADCVAR("g_lms_lives_override"); BADCVAR("g_maplist"); BADCVAR("g_maxplayers"); + BADCVAR("g_mh_team_spawns"); + BADCVAR("g_mh_point_limit"); + BADCVAR("g_mh_warmup"); + BADCVAR("g_mh_round_timelimit"); + BADCVAR("g_mh_how_many_rounds_before_shuffle"); + BADCVAR("g_mh_enable_tagging_on_touch"); + BADCVAR("g_mh_player_waypoints"); + BADCVAR("g_mh_weaponarena"); + BADCVAR("g_mh_weapons_damage"); + BADCVAR("g_mh_weapons_force"); + BADCVAR("g_mh_limited_ammunition"); BADCVAR("g_mirrordamage"); BADCVAR("g_nexball_goallimit"); BADCVAR("g_norecoil");