From 12b583098c0ff4fe69eb844460c189eb636876f2 Mon Sep 17 00:00:00 2001 From: drjaska Date: Thu, 25 Nov 2021 00:53:28 +0200 Subject: [PATCH] added waypoints, total player count instead of alive, fixes, I forgot other small things --- qcsrc/common/gamemodes/gamemode/mh/TODO.txt | 6 +- qcsrc/common/gamemodes/gamemode/mh/mh.qh | 7 +- qcsrc/common/gamemodes/gamemode/mh/sv_mh.qc | 79 ++++++++++++++++----- qcsrc/common/gamemodes/gamemode/mh/sv_mh.qh | 2 +- qcsrc/server/teamplay.qc | 24 +++++++ qcsrc/server/teamplay.qh | 14 ++++ 6 files changed, 109 insertions(+), 23 deletions(-) diff --git a/qcsrc/common/gamemodes/gamemode/mh/TODO.txt b/qcsrc/common/gamemodes/gamemode/mh/TODO.txt index de096c1d9..75e4f3d68 100644 --- a/qcsrc/common/gamemodes/gamemode/mh/TODO.txt +++ b/qcsrc/common/gamemodes/gamemode/mh/TODO.txt @@ -1,12 +1,10 @@ add g_mh_startitem cvars to the balance files -add waypoints on runners +fix waypoint visibility, currently they are always visible to everyone. Fix them to not be visible for self or for spectators of that player. rename teams as far as possible -count dead players to be in a team - -more dynamic +more dynamicity for the code :) on-screen notification for getting tagged diff --git a/qcsrc/common/gamemodes/gamemode/mh/mh.qh b/qcsrc/common/gamemodes/gamemode/mh/mh.qh index ac37a1628..090c410cc 100644 --- a/qcsrc/common/gamemodes/gamemode/mh/mh.qh +++ b/qcsrc/common/gamemodes/gamemode/mh/mh.qh @@ -2,6 +2,9 @@ #include + +bool autocvar_g_mh_not_dm_maps; + #ifdef CSQC void HUD_Mod_MH(vector pos, vector mySize); void HUD_Mod_MH_Export(int fh); @@ -9,7 +12,7 @@ void HUD_Mod_MH_Export(int fh); CLASS(Manhunt, Gametype) INIT(Manhunt) { - this.gametype_init(this, _("Manhunt"),"mh","g_mh",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PRIORITY,"","timelimit=30 pointlimit=10 teams=2 leadlimit=0",_("Avoid getting tagged yourself and once tagged go catch as many untagged players as possible")); + this.gametype_init(this, _("Tag Manhunt"),"mh","g_mh",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PRIORITY,"","timelimit=30 pointlimit=10 teams=2 leadlimit=0",_("Avoid getting tagged yourself and once tagged go catch as many untagged players as possible")); } METHOD(Manhunt, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter)) { @@ -19,7 +22,7 @@ CLASS(Manhunt, Gametype) } METHOD(Manhunt, m_isForcedSupported, bool(Gametype this)) { - if(!cvar("g_mh_not_dm_maps")) + if(!autocvar_g_mh_not_dm_maps) { // if this is unset, all DM maps support MMM too if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags)) diff --git a/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qc b/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qc index 7df3a0b7f..0e3462cd2 100644 --- a/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qc +++ b/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qc @@ -116,7 +116,7 @@ MUTATOR_HOOKFUNCTION(mh, GiveFragsForKill, CBC_ORDER_FIRST) // HideTeamNagger y y // PlayerSpawn y y // PutClientInServer y y -// MH_count_alive_players y y +// MH_count_players y y // MH_GetWinnerTeam y y // nades_Clear y y // MH_CheckWinner y y @@ -128,7 +128,7 @@ MUTATOR_HOOKFUNCTION(mh, GiveFragsForKill, CBC_ORDER_FIRST) // general order which they are called in / when they are called: // todo: update after cleanup is finished and when new functions are added -// Start by initiating round_handler, when there is >= 1 player alive on both teams MH_CheckTeams(which is done by calling MH_count_alive_players and +// Start by initiating round_handler, when there is >= 1 player alive on both teams MH_CheckTeams(which is done by calling MH_count_players and // it also updates the count for alive players for Team_ functions) let's round handler start a new round // Between rounds reset_map_ hooks get triggered and on new round start MH_RoundStart is called @@ -206,8 +206,12 @@ MUTATOR_HOOKFUNCTION(mh, ClientDisconnect) { entity player = M_ARGV(0, entity); - if (IS_PLAYER(player)) + if (IS_PLAYER(player)){ mh_LastPlayerForTeam_Notify(player); + if (player.waypointsprite_attachedforcarrier) + WaypointSprite_Kill(player.waypointsprite_attachedforcarrier); + + } return true; } @@ -221,7 +225,7 @@ MUTATOR_HOOKFUNCTION(mh, HideTeamNagger) } // Function: -// MH_count_alive_players +// MH_count_players // Purpose in CA: // refresh count of how many players are alive in each team to Team_ functions // Needed in MH? Purpose?: @@ -232,18 +236,22 @@ MUTATOR_HOOKFUNCTION(mh, HideTeamNagger) // MH_CheckWinner , MH_CheckTeams // Calls: // multiple Team_ functions which are imported -void MH_count_alive_players() +void MH_count_players() { total_players = 0; for (int i = 1; i <= 2; ++i){ Team_SetNumberOfAlivePlayers(Team_GetTeamFromIndex(i), 0); + Team_SetNumberOfTotalPlayers(Team_GetTeamFromIndex(i), 0); } FOREACH_CLIENT(IS_PLAYER(it) && Entity_HasValidTeam(it),{ + entity team_ = Entity_GetTeam(it); + int num_total = Team_GetNumberOfTotalPlayers(team_); + ++num_total; + Team_SetNumberOfTotalPlayers(team_, num_total); ++total_players; if (IS_DEAD(it)){ continue; } - entity team_ = Entity_GetTeam(it); int num_alive = Team_GetNumberOfAlivePlayers(team_); ++num_alive; Team_SetNumberOfAlivePlayers(team_, num_alive); @@ -274,13 +282,13 @@ void MH_count_alive_players() // Team_ int MH_GetWinnerTeam() { - //both teams have alive players - if ((Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(1)) >= 1) && (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(2)) >= 1)){ + //both teams have players + if ((Team_GetNumberOfTotalPlayers(Team_GetTeamFromIndex(1)) >= 1) && (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(2)) >= 1)){ return Team_IndexToTeam(2); } //only hunters were alive - if ((Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(1)) >= 1) && (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(2)) == 0)){ + if ((Team_GetNumberOfTotalPlayers(Team_GetTeamFromIndex(1)) >= 1) && (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(2)) == 0)){ return Team_IndexToTeam(1); } @@ -298,11 +306,11 @@ int MH_GetWinnerTeam() // Called by: // round_handler // Calls: -// round_handler_Init , MH_count_alive_players , MH_GetWinnerTeam , nades_Clear +// round_handler_Init , MH_count_players , MH_GetWinnerTeam , nades_Clear float MH_CheckWinner() { int did_the_round_end = 0; - MH_count_alive_players(); + MH_count_players(); int winner_team = MH_GetWinnerTeam(); if(winner_team == 14) FOREACH_CLIENT(IS_PLAYER(it) && it.team == 14, @@ -353,13 +361,13 @@ float MH_CheckWinner() // Called by: // round_handler_Spawn // Calls: -// MH_count_alive_players , Team_ functions which are imported +// MH_count_players , Team_ functions which are imported bool MH_CheckTeams() { static int prev_missing_teams_mask; allowed_to_spawn_untagged = true; - MH_count_alive_players(); - if (Team_GetNumberOfAliveTeams() == NumTeams(mh_teams)){ + MH_count_players(); + if (Team_GetNumberOfTotalTeams() == NumTeams(mh_teams)){ if(prev_missing_teams_mask > 0) Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_MISSING_TEAMS); prev_missing_teams_mask = -1; @@ -374,7 +382,7 @@ bool MH_CheckTeams() int missing_teams_mask = 0; for (int i = 1; i <= 2; ++i){ if ((mh_teams & Team_IndexToBit(i)) && - (Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(i)) == 0)){ + (Team_GetNumberOfTotalPlayers(Team_GetTeamFromIndex(i)) == 0)){ missing_teams_mask |= Team_IndexToBit(i); } } @@ -400,6 +408,18 @@ bool MH_CheckTeams() void MH_RoundStart() { allowed_to_spawn_untagged = boolean(warmup_stage); + if(autocvar_g_mh_player_waypoints == 0){ + return; + } else if(autocvar_g_mh_player_waypoints == 1 || autocvar_g_mh_player_waypoints == 2){ + FOREACH_CLIENT(IS_PLAYER(it) && it.team == Team_IndexToTeam(2), + { + WaypointSprite_AttachCarrier(WP_Null, it, RADARICON_FLAGCARRIER); + WaypointSprite_UpdateRule(it.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT); + vector pl_color = colormapPaletteColor(it.clientcolors & 0x0F, false); + WaypointSprite_UpdateTeamRadar(it.waypointsprite_attachedforcarrier, RADARICON_FLAGCARRIER, pl_color); + WaypointSprite_Ping(it.waypointsprite_attachedforcarrier); + }); + } } // Function: @@ -455,6 +475,9 @@ MUTATOR_HOOKFUNCTION(mh, PlayerDies) { entity frag_target = M_ARGV(2, entity); + if (frag_target.waypointsprite_attachedforcarrier) + WaypointSprite_Kill(frag_target.waypointsprite_attachedforcarrier); + mh_LastPlayerForTeam_Notify(frag_target); if (!allowed_to_spawn_untagged) { @@ -467,6 +490,18 @@ MUTATOR_HOOKFUNCTION(mh, PlayerDies) return true; } +// runs on waypoints which are attached to players, updates once per frame +bool mh_waypointsprite_visible_for_player(entity this, entity player, entity view) +{ + //if(IS_PLAYER(view) || this == view || IS_SPEC(player)) //fix me + // return false; // we don't want spectators to see the attached waypoint on the top of their screen + + if(autocvar_g_mh_player_waypoints == 0) + return false; + + return true; +} + // Function: // PlayerSpawn // Purpose in CA: @@ -483,7 +518,7 @@ MUTATOR_HOOKFUNCTION(mh, PlayerSpawn) { entity player = M_ARGV(0, entity); player.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP; - MH_count_alive_players(); + MH_count_players(); if(player.team == Team_IndexToTeam(2) && !allowed_to_spawn_untagged && Team_GetNumberOfAlivePlayers(Team_GetTeamFromIndex(2)) > 1 && round_handler_IsActive() && round_handler_IsRoundStarted()){ player.deadflag = 1; // avoid a crash when a spectator joins runners mid-round and gets sent to hunters MoveToTeam(player, 1, 6); //index of 1 static is wrong way but it's working somehow with bubblegum and prayers @@ -495,6 +530,18 @@ MUTATOR_HOOKFUNCTION(mh, PlayerSpawn) player.velocity = player.taggedplayervelocity; player.angles = player.taggedplayerviewangles; } + //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)) + { + WaypointSprite_AttachCarrier(WP_Null, player, RADARICON_FLAGCARRIER); + //player.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = mh_waypointsprite_visible_for_player; + WaypointSprite_UpdateRule(player.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT); + vector pl_color = colormapPaletteColor(player.clientcolors & 0x0F, false); + WaypointSprite_UpdateTeamRadar(player.waypointsprite_attachedforcarrier, RADARICON_FLAGCARRIER, pl_color); + WaypointSprite_Ping(player.waypointsprite_attachedforcarrier); + }; + } } //reset kill streaks and respawn players on round reset diff --git a/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qh b/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qh index d9b11be88..c12d05121 100644 --- a/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qh +++ b/qcsrc/common/gamemodes/gamemode/mh/sv_mh.qh @@ -20,7 +20,7 @@ int round_counter_for_teamchanging = 1; int autocvar_g_mh_how_many_rounds_before_shuffle; bool autocvar_g_mh_enable_tagging_on_touch; -//float autocvar_g_mh_player_waypoints; +float autocvar_g_mh_player_waypoints; const int ST_MH_ROUNDS = 1; diff --git a/qcsrc/server/teamplay.qc b/qcsrc/server/teamplay.qc index c26a0b165..348045ba1 100644 --- a/qcsrc/server/teamplay.qc +++ b/qcsrc/server/teamplay.qc @@ -35,6 +35,7 @@ const int TEAM_NOT_ALLOWED = -1; .int m_num_players; ///< Number of players (both humans and bots) in a team. .int m_num_bots; ///< Number of bots in a team. .int m_num_players_alive; ///< Number of alive players in a team. +.int m_num_players_total; ///< Number of total players in a team. .int m_num_control_points; ///< Number of control points owned by a team. string autocvar_g_forced_team_red; @@ -92,6 +93,16 @@ void Team_SetNumberOfAlivePlayers(entity team_ent, int number) team_ent.m_num_players_alive = number; } +int Team_GetNumberOfTotalPlayers(entity team_ent) +{ + return team_ent.m_num_players_total; +} + +void Team_SetNumberOfTotalPlayers(entity team_ent, int number) +{ + team_ent.m_num_players_total = number; +} + int Team_GetNumberOfAliveTeams() { int result = 0; @@ -105,6 +116,19 @@ int Team_GetNumberOfAliveTeams() return result; } +int Team_GetNumberOfTotalTeams() +{ + int result = 0; + for (int i = 0; i < NUM_TEAMS; ++i) + { + if (g_team_entities[i].m_num_players_total > 0) + { + ++result; + } + } + return result; +} + int Team_GetNumberOfControlPoints(entity team_ent) { return team_ent.m_num_control_points; diff --git a/qcsrc/server/teamplay.qh b/qcsrc/server/teamplay.qh index 06787c6ff..43e06dabd 100644 --- a/qcsrc/server/teamplay.qh +++ b/qcsrc/server/teamplay.qh @@ -46,15 +46,29 @@ void Team_SetTeamScore(entity team_ent, float score); /// \return Number of alive players in a team. int Team_GetNumberOfAlivePlayers(entity team_ent); +/// \brief Returns the number of total players in a team. +/// \param[in] team_ent Team entity. +/// \return Number of total players in a team. +int Team_GetNumberOfTotalPlayers(entity team_ent); + /// \brief Sets the number of alive players in a team. /// \param[in,out] team_ent Team entity. /// \param[in] number Number of players to set. void Team_SetNumberOfAlivePlayers(entity team_ent, int number); +/// \brief Sets the number of total players in a team. +/// \param[in,out] team_ent Team entity. +/// \param[in] number Number of players to set. +void Team_SetNumberOfTotalPlayers(entity team_ent, int number); + /// \brief Returns the number of alive teams. /// \return Number of alive teams. int Team_GetNumberOfAliveTeams(); +/// \brief Returns the number of total teams. +/// \return Number of total teams. +int Team_GetNumberOfTotalTeams(); + /// \brief Returns the number of control points owned by a team. /// \param[in] team_ent Team entity. /// \return Number of control points owned by a team. -- 2.39.2