Descriptions were based on https://gitlab.com/xonotic/xonotic/-/wikis/home, although some gamemodes don't have a description there.
Added back .gametype_description (now called .m_description) so that the shorter gamemode descriptions can still be used.
Added .m_name to the gamemode class, copied with the initial value of .message, so that the COLORED_NAME macros can be used. Ideally .message wouldn't be necessary since it's not very descriptive, I just didn't bother going through all instances of .message being used to make sure nothing would break.
#include "assault.qh"
+
+#ifdef MENUQC
+METHOD(Assault, describe, string(Assault this))
+{
+ TC(Assault, this);
+ return sprintf(_("%s is a team-based gamemode involving an attacking and a defending team\n\n"
+ "The attacking deam destroys objects placed on the map, which opens up new doors or pathways to more objects, until a main object (the enemy power core) is reached. "
+ "The attacking team wins the round if they manage to destroy the power core before time runs out, and then teams switch roles in the next round\n\n"
+ "The defending team has to defend the objects, winning the round if they successfully prevent the attacking team from destroying the power core\n\n"
+ "A team will win the match overall once they win at least one round where they attacked and one round where they defended, meaning there can be ties\n\n"
+ "Objects have waypoints which show their health and position, and they're destroyed by shooting them with any weapon"),
+ COLORED_NAME(this));
+}
+#endif
CLASS(Assault, Gametype)
INIT(Assault)
{
- this.gametype_init(this, _("Assault"),"as","g_assault",GAMETYPE_FLAG_TEAMPLAY,"","timelimit=20");
+ this.gametype_init(this, _("Assault"),"as","g_assault",GAMETYPE_FLAG_TEAMPLAY,"","timelimit=20",_("Destroy obstacles to find and destroy the enemy power core before time runs out"));
}
METHOD(Assault, m_generate_mapinfo, void(Gametype this, string v))
{
TC(Gametype, this);
returns(menu, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
}
- METHOD(Assault, describe, string(Assault this))
- {
- TC(Assault, this);
- return _("Destroy obstacles to find and destroy the enemy power core before time runs out");
- }
ATTRIB(Assault, m_legacydefaults, string, "20 0");
ENDCLASS(Assault)
REGISTER_GAMETYPE(ASSAULT, NEW(Assault));
#include "clanarena.qh"
+
+#ifdef MENUQC
+METHOD(ClanArena, describe, string(ClanArena this))
+{
+ TC(ClanArena, this);
+ return sprintf(_("%s is a common round-based gamemode played with teams, where players spawn with all weapons available, have maximum health and armor, but only have one life per round. "
+ "There are no pickups available on the map in %s, making the gameplay fast-paced and focused on combat\n\n"
+ "Rounds start with a ten second grace period where weapons cannot be fired, so it's a good opportunity to group up with your team\n\n"
+ "The match ends once a team reaches a certain number of won rounds, or has a considerable lead over the other team\n\n"
+ "Since players only have one life per round, it's important to group up with fellow teammates and pay attention to any callouts from them. "
+ "Team coordination is key!"),
+ COLORED_NAME(this), COLORED_NAME(this));
+}
+#endif
CLASS(ClanArena, Gametype)
INIT(ClanArena)
{
- this.gametype_init(this, _("Clan Arena"),"ca","g_ca",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=10 teams=2 leadlimit=6");
+ this.gametype_init(this, _("Clan Arena"),"ca","g_ca",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=10 teams=2 leadlimit=6",_("Kill all enemy teammates to win the round"));
}
METHOD(ClanArena, m_parse_mapinfo, bool(string k, string v))
{
TC(Gametype, this);
returns(menu, _("Round limit:"), 5, 100, 5, "fraglimit_override", "g_ca_teams_override", _("The amount of rounds won needed before the match will end"));
}
- METHOD(ClanArena, describe, string(ClanArena this))
- {
- TC(ClanArena, this);
- return _("Kill all enemy teammates to win the round");
- }
#ifdef CSQC
ATTRIB(ClanArena, m_modicons, void(vector pos, vector mySize), HUD_Mod_CA);
ATTRIB(ClanArena, m_modicons_export, void(int fh), HUD_Mod_CA_Export);
#include "ctf.qh"
+
+#ifdef MENUQC
+METHOD(CaptureTheFlag, describe, string(CaptureTheFlag this))
+{
+ TC(CaptureTheFlag, this);
+ return sprintf(_("%s is a common team-based gamemode where the object is to steal an enemy team's flag and bring it back to your own to capture it. "
+ "A flag can only be captured if your own flag is also home in its base, so it's important to collect your flag after it's dropped\n\n"
+ "The game is won once a team reaches a certain number of \"caps\" (captures), or has a considerable lead over the other team\n\n"
+ "If a flag is dropped into the void or a death trap it will be immediately returned to its base, or otherwise it will sit idle for a while before automatically returning itself. "
+ "If all flags are held by an enemy, after some time period a \"stalemate\" will initiate and all flag carriers (\"fc\"s) will be exposed on the radar and with waypoints\n\n"
+ "Some %s maps have more than two bases on it, but generally this is a 2-team gamemode\n\n"
+ "This gamemode rewards crafty movement, since the more difficult it is for enemies to attack you, the more likely you are to escape from their base with their flag. "
+ "Importantly, it also rewards base defense since if your enemies can't take your flag, they can never capture. "
+ "Lastly, good team communication is important, especially to let them know if you see the enemy flag carrier"),
+ COLORED_NAME(this), COLORED_NAME(this));
+}
+#endif
CLASS(CaptureTheFlag, Gametype)
INIT(CaptureTheFlag)
{
- this.gametype_init(this, _("Capture the Flag"),"ctf","g_ctf",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PRIORITY,"","timelimit=20 caplimit=10 leadlimit=6");
+ this.gametype_init(this, _("Capture the Flag"),"ctf","g_ctf",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PRIORITY,"","timelimit=20 caplimit=10 leadlimit=6",_("Find and bring the enemy flag to your base to capture it, defend your base from the other team"));
}
METHOD(CaptureTheFlag, m_generate_mapinfo, void(Gametype this, string v))
{
TC(Gametype, this);
returns(menu, _("Capture limit:"), 1, 20, 1, "capturelimit_override", string_null, _("The amount of captures needed before the match will end"));
}
- METHOD(CaptureTheFlag, describe, string(CaptureTheFlag this))
- {
- TC(CaptureTheFlag, this);
- return _("Find and bring the enemy flag to your base to capture it, defend your base from the other team");
- }
#ifdef CSQC
ATTRIB(CaptureTheFlag, m_modicons, void(vector pos, vector mySize), HUD_Mod_CTF);
ATTRIB(CaptureTheFlag, m_modicons_reset, void(), HUD_Mod_CTF_Reset);
#include "cts.qh"
+
+#ifdef MENUQC
+#include <common/gamemodes/gamemode/race/race.qh>
+
+METHOD(RaceCTS, describe, string(RaceCTS this))
+{
+ TC(RaceCTS, this);
+ return sprintf(_("%s is a unique gamemode, focusing on racing against other players on the map, rather than fighting them with weapons. "
+ "Players run through the map from start to finish as fast as possible and try to beat the times set by others\n\n"
+ "%s is similar to %s, except you don't run in laps, and instead run from the start line to the finish line, then start over again\n\n"
+ "Although this gamemode is quite different from the rest, it is played quite frequently since it's a great way to master movement skills and there are heaps of community-made maps available. "
+ "Also, it only requires one player to play"),
+ COLORED_NAME(this), COLORED_NAME(this), COLORED_NAME(MAPINFO_TYPE_RACE));
+}
+#endif
CLASS(RaceCTS, Gametype)
INIT(RaceCTS)
{
- this.gametype_init(this, _("Race CTS"),"cts","g_cts",0,"cloaked","timelimit=20");
+ this.gametype_init(this, _("Race CTS"),"cts","g_cts",0,"cloaked","timelimit=20",_("Race to the finish line for fastest time"));
}
METHOD(RaceCTS, m_generate_mapinfo, void(Gametype this, string v))
{
TC(Gametype, this);
returns(menu, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
}
- METHOD(RaceCTS, describe, string(RaceCTS this))
- {
- TC(RaceCTS, this);
- return _("Race for fastest time.");
- }
#ifdef CSQC
ATTRIB(RaceCTS, m_modicons, void(vector pos, vector mySize), HUD_Mod_Race);
#endif
#include "deathmatch.qh"
+
+#ifdef MENUQC
+#include <common/items/item/health.qh>
+#include <common/items/item/armor.qh>
+
+METHOD(Deathmatch, describe, string(Deathmatch this))
+{
+ TC(Deathmatch, this);
+ return sprintf(_("%s is a simple free-for-all fight to the death, where everyone plays against everyone else, and the winner is the one with the most points. "
+ "When fragged, you respawn with only the starter weapons, so any you collected up will have to be re-picked up\n\n"
+ "Scoring is quite simple, fragging an opponent adds one to your score, and fragging yourself subtracts one\n\n"
+ "Maps often have powerups and items like %s and %s, which are usually highly contested since sometimes they have the power to make or break a game, so making good use of them is important"),
+ COLORED_NAME(this), COLORED_NAME(ITEM_HealthMega), COLORED_NAME(ITEM_ArmorMega));
+}
+#endif
CLASS(Deathmatch, Gametype)
INIT(Deathmatch)
{
- this.gametype_init(this, _("Deathmatch"),"dm","g_dm",GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PREFERRED,"","timelimit=15 pointlimit=30 leadlimit=0");
+ this.gametype_init(this, _("Deathmatch"),"dm","g_dm",GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PREFERRED,"","timelimit=15 pointlimit=30 leadlimit=0",_("Score as many frags as you can"));
}
METHOD(Deathmatch, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
{
return true;
}
- METHOD(Deathmatch, describe, string(Deathmatch this))
- {
- TC(Deathmatch, this);
- return _("Score as many frags as you can");
- }
ATTRIB(Deathmatch, m_legacydefaults, string, "30 20 0");
ENDCLASS(Deathmatch)
REGISTER_GAMETYPE(DEATHMATCH, NEW(Deathmatch));
#include "domination.qh"
+
+#ifdef MENUQC
+METHOD(Domination, describe, string(Domination this))
+{
+ TC(Domination, this);
+ return sprintf(_("%s is a gamemode where teams compete to dominate the map by capturing and keeping control points\n\n"
+ "Control points are displayed on the radar to make finding them easy, and they are captured by simply walking through them. "
+ "However, an enemy can just as easily steal a control point owned by your team by doing the same. "
+ "Control points start neutral (owned by no teams)\n\n"
+ "Scoring is a combination of frags and score automatically generated by any control points held by your team, every few seconds"),
+ COLORED_NAME(this));
+}
+#endif
CLASS(Domination, Gametype)
INIT(Domination)
{
- this.gametype_init(this, _("Domination"),"dom","g_domination",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=200 teams=2 leadlimit=0");
+ this.gametype_init(this, _("Domination"),"dom","g_domination",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=200 teams=2 leadlimit=0",_("Capture and defend all the control points to win"));
}
METHOD(Domination, m_parse_mapinfo, bool(string k, string v))
{
TC(Gametype, this);
returns(menu, _("Point limit:"), 50, 500, 10, "g_domination_point_limit", "g_domination_teams_override", _("The amount of points needed before the match will end"));
}
- METHOD(Domination, describe, string(Domination this))
- {
- TC(Domination, this);
- return _("Capture and defend all the control points to win");
- }
#ifdef CSQC
ATTRIB(Domination, m_modicons, void(vector pos, vector mySize), HUD_Mod_Dom);
ATTRIB(Domination, m_modicons_export, void(int fh), HUD_Mod_Dom_Export);
#include "duel.qh"
+
+#ifdef MENUQC
+#include <common/gamemodes/gamemode/deathmatch/deathmatch.qh>
+#include <common/items/item/health.qh>
+#include <common/items/item/armor.qh>
+
+METHOD(Duel, describe, string(Duel this))
+{
+ TC(Duel, this);
+ return sprintf(_("%s is a 1-vs-1 arena battle to decide the winner, essentially a 2-player version of %s, making it one of the most competitive gamemodes\n\n"
+ "Since players on their own, important items like the %s and %s are heavily contested, "
+ "and are often \"timed\" by observing the in-game timer when it is picked up to determine when it'll next spawn. "
+ "The player with the best item control is often the winner\n\n"
+ "Once you kill your opponent, they will spawn with few weapons and limited health, so it is a good opportunity to search the map for them to pick up an easy frag and continue your streak"),
+ COLORED_NAME(this), COLORED_NAME(MAPINFO_TYPE_DEATHMATCH), COLORED_NAME(ITEM_HealthMega), COLORED_NAME(ITEM_ArmorMega));
+}
+#endif
CLASS(Duel, Gametype)
INIT(Duel)
{
- this.gametype_init(this, _("Duel"),"duel","g_duel",GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_1V1,"","timelimit=10 pointlimit=0 leadlimit=0");
+ this.gametype_init(this, _("Duel"),"duel","g_duel",GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_1V1,"","timelimit=10 pointlimit=0 leadlimit=0",_("Fight in a one versus one arena battle to decide the winner"));
}
METHOD(Duel, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
{
}
return false;
}
- METHOD(Duel, describe, string(Duel this))
- {
- TC(Duel, this);
- return _("Fight in a one versus one arena battle to decide the winner");
- }
ENDCLASS(Duel)
REGISTER_GAMETYPE(DUEL, NEW(Duel));
#define g_duel IS_GAMETYPE(DUEL)
#include "freezetag.qh"
+
+#ifdef MENUQC
+METHOD(FreezeTag, describe, string(FreezeTag this))
+{
+ TC(FreezeTag, this);
+ return sprintf(_("%s is a round-based teamplay gamemode where killed players are frozen and need to be unfrozen to re-enter the round. "
+ "The round ends when all players from all opposing teams are frozen, scoring the remaining team a point\n\n"
+ "Frozen players slowly unfreeze over time, but they unfreeze much faster when \"revived\" by a teammate standing in close proximity. "
+ "Additionally, damaging frozen players on the other team helps unfreeze them, so it is best to try to avoid doing that\n\n"
+ "Like in many other round-based gamemodes, rounds start with a ten second grace period where weapons cannot be fired, meaning it's a good opportunity to grab as many pickups as you can\n\n"
+ "Sneakily reviving a teammate will bring them back into the match to help outnumber your opponents, but it should be done with caution since often enemies pay close attention to frozen players to make sure they aren't being revived. "
+ "For this reason it's important to have good team communication especially while frozen, so you can let your teammates know where the enemies are"),
+ COLORED_NAME(this));
+}
+#endif
CLASS(FreezeTag, Gametype)
INIT(FreezeTag)
{
- this.gametype_init(this, _("Freeze Tag"),"ft","g_freezetag",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=10 teams=2 leadlimit=6");
+ this.gametype_init(this, _("Freeze Tag"),"ft","g_freezetag",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=10 teams=2 leadlimit=6",_("Kill enemies to freeze them, stand next to frozen teammates to revive them; freeze all enemies to win"));
}
METHOD(FreezeTag, m_parse_mapinfo, bool(string k, string v))
{
TC(Gametype, this);
returns(menu, _("Round limit:"), 5, 100, 5, "fraglimit_override", "g_freezetag_teams_override", _("The amount of rounds won needed before the match will end"));
}
- METHOD(FreezeTag, describe, string(FreezeTag this))
- {
- TC(FreezeTag, this);
- return _("Kill enemies to freeze them, stand next to frozen teammates to revive them; freeze all enemies to win");
- }
#ifdef CSQC
ATTRIB(FreezeTag, m_modicons, void(vector pos, vector mySize), HUD_Mod_FreezeTag);
ATTRIB(FreezeTag, m_modicons_export, void(int fh), HUD_Mod_FreezeTag_Export);
#include "invasion.qh"
+
+#ifdef MENUQC
+METHOD(Invasion, describe, string(Invasion this))
+{
+ TC(Invasion, this);
+ return sprintf(_("%s is a unique gamemode played in rounds where a herd of monsters spawn all around the map and players must try to kill as many as possible. "
+ "Since players can't damage each other, they instead fight to steal monster frags from each other. "
+ "The player who frags the most monsters overall wins the match\n\n"
+ "A round ends when either all monsters are fragged, or after a time limit"),
+ COLORED_NAME(this));
+}
+#endif
CLASS(Invasion, Gametype)
INIT(Invasion)
{
- this.gametype_init(this, _("Invasion"),"inv","g_invasion",GAMETYPE_FLAG_USEPOINTS,"","pointlimit=50 type=0");
+ this.gametype_init(this, _("Invasion"),"inv","g_invasion",GAMETYPE_FLAG_USEPOINTS,"","pointlimit=50 type=0",_("Survive against waves of monsters"));
}
METHOD(Invasion, m_parse_mapinfo, bool(string k, string v))
{
TC(Gametype, this);
returns(menu, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
}
- METHOD(Invasion, describe, string(Invasion this))
- {
- TC(Invasion, this);
- return _("Survive against waves of monsters");
- }
ENDCLASS(Invasion)
REGISTER_GAMETYPE(INVASION, NEW(Invasion));
#include "keepaway.qh"
+
+#ifdef MENUQC
+#include <common/gamemodes/gamemode/ctf/ctf.qh>
+
+METHOD(Keepaway, describe, string(Keepaway this))
+{
+ TC(Keepaway, this);
+ return sprintf(_("%s is a free-for-all match where a ball spawns randomly on the map and the goal is to hold the ball for as long as possible\n\n"
+ "Your score increases when you frag someone while you're holding a ball and when you frag the ball carrier. "
+ "The first player to reach the score limit will win the match\n\n"
+ "When the ball carrier is fragged, the ball will drop to the ground and anyone is able to pick it up. "
+ "If nobody picks it up after some time it will get bored and teleport itself elsewhere. "
+ "Unlike the flag in %s, the ball in %s can't be thrown\n\n"
+ "%s rewards good fragging but also good movement, since the better you can evade attacks, the longer you can keep the ball"),
+ COLORED_NAME(this), COLORED_NAME(MAPINFO_TYPE_CTF), COLORED_NAME(this), COLORED_NAME(this));
+}
+#endif
CLASS(Keepaway, Gametype)
INIT(Keepaway)
{
- this.gametype_init(this, _("Keepaway"),"ka","g_keepaway",GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=30");
+ this.gametype_init(this, _("Keepaway"),"ka","g_keepaway",GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
}
METHOD(Keepaway, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
{
return true;
}
- METHOD(Keepaway, describe, string(Keepaway this))
- {
- TC(Keepaway, this);
- return _("Hold the ball to get points for kills");
- }
#ifdef CSQC
ATTRIB(Keepaway, m_modicons, void(vector pos, vector mySize), HUD_Mod_Keepaway);
#endif
#include "keyhunt.qh"
+
+#ifdef MENUQC
+#include <common/gamemodes/gamemode/ctf/ctf.qh>
+
+METHOD(KeyHunt, describe, string(KeyHunt this))
+{
+ TC(KeyHunt, this);
+ return sprintf(_("%s is a round-based gamemode played with a few teams, where each team starts with 1 key and all keys must be collected to win the round. "
+ "The team member who is given the key at the start of the round is randomly selected after a ten second period, and the location of all keys will be visible in the radar after a few seconds\n\n"
+ "Scoring in %s is quite complicated, involving a mix of gathering all keys, points for collecting a key, killing an enemy key carrier, and killing other enemies. "
+ "If a key is destroyed by being dropped into the void or a death trap, points are allocated accordingly\n\n"
+ "Like in %s the key can be dropped, so you can pass it to your teammates if you're running low on health"),
+ COLORED_NAME(this), COLORED_NAME(this), COLORED_NAME(MAPINFO_TYPE_CTF));
+}
+#endif
CLASS(KeyHunt, Gametype)
INIT(KeyHunt)
{
- this.gametype_init(this, _("Key Hunt"),"kh","g_keyhunt",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=1000 teams=3 leadlimit=0");
+ this.gametype_init(this, _("Key Hunt"),"kh","g_keyhunt",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=1000 teams=3 leadlimit=0",_("Gather all the keys to win the round"));
}
METHOD(KeyHunt, m_parse_mapinfo, bool(string k, string v))
{
TC(Gametype, this);
returns(menu, _("Point limit:"), 200, 1500, 50, "g_keyhunt_point_limit", "g_keyhunt_teams_override", _("The amount of points needed before the match will end"));
}
- METHOD(KeyHunt, describe, string(KeyHunt this))
- {
- TC(KeyHunt, this);
- return _("Gather all the keys to win the round");
- }
#ifdef CSQC
ATTRIB(KeyHunt, m_modicons, void(vector pos, vector mySize), HUD_Mod_KH);
#endif
#include "lms.qh"
+
+#ifdef MENUQC
+#include <common/gamemodes/gamemode/clanarena/clanarena.qh>
+
+METHOD(LastManStanding, describe, string(LastManStanding this))
+{
+ TC(LastManStanding, this);
+ return sprintf(_("%s is a free-for-all gamemode where all players start with a certain number of lives, and are eliminated from the match once they lose all lives. "
+ "Players spawn in with all available weapons, maximum health, maximum armor, and health and armor do not regenerate, similar to gamemodes like %s. "
+ "Similarly, item pickups don't spawn on the map\n\n"
+ "Hiding is sometimes a viable strategy since if you can't be found you can't lose lives, but often you become a vulnerable target once discovered"),
+ COLORED_NAME(this), COLORED_NAME(MAPINFO_TYPE_CA));
+}
+#endif
CLASS(LastManStanding, Gametype)
INIT(LastManStanding)
{
- this.gametype_init(this, _("Last Man Standing"),"lms","g_lms",GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_HIDELIMITS,"","timelimit=20 lives=5 leadlimit=0");
+ this.gametype_init(this, _("Last Man Standing"),"lms","g_lms",GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_HIDELIMITS,"","timelimit=20 lives=5 leadlimit=0",_("Survive and kill until the enemies have no lives left"));
}
METHOD(LastManStanding, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
{
TC(Gametype, this);
returns(menu, _("Lives:"), 3, 50, 1, "g_lms_lives_override", string_null, string_null);
}
- METHOD(LastManStanding, describe, string(LastManStanding this))
- {
- TC(LastManStanding, this);
- return _("Survive and kill until the enemies have no lives left");
- }
ATTRIB(LastManStanding, m_legacydefaults, string, "9 20 0");
#ifdef CSQC
ATTRIB(LastManStanding, m_modicons, void(vector myPos, vector mySize), HUD_Mod_LMS);
#include "mayhem.qh"
+
+#ifdef MENUQC
+METHOD(mayhem, describe, string(mayhem this))
+{
+ TC(mayhem, this);
+ return sprintf(_("%s is a fast-paced free-for-all deathmatch where players spawn in with all available weapons and maximum health and armor. "
+ "There are no pickups enabled on maps, but buffs are still available\n\n"
+ "It shines in its unique handling of scoring, accouting for both frags but also damage dealt. "
+ "This means that if you almost frag a player you will still be rewarded with points, but dealing the final blow is always better if possible. "
+ "Points are deducted when you walk into damage triggers, but not when you do movement tricks like blaster jumping since self damage is disabled\n\n"
+ "Since damage is always rewarded in %s, the more you shoot the better, turning this gamemode into chaotic fun at times"),
+ COLORED_NAME(this), COLORED_NAME(this));
+}
+#endif
CLASS(mayhem, Gametype)
INIT(mayhem)
{
- this.gametype_init(this, _("Mayhem"),"mayhem","g_mayhem",GAMETYPE_FLAG_USEPOINTS,"","timelimit=15 pointlimit=1000 leadlimit=0");
+ this.gametype_init(this, _("Mayhem"),"mayhem","g_mayhem",GAMETYPE_FLAG_USEPOINTS,"","timelimit=15 pointlimit=1000 leadlimit=0",_("Compete for the most damage dealt and frags in this chaotic mayhem"));
}
METHOD(mayhem, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
{
TC(Gametype, this);
returns(menu, _("Point limit:"), 200, 2000, 100, "g_mayhem_point_limit", string_null, _("How much score is needed before the match will end"));
}
- METHOD(mayhem, describe, string(mayhem this))
- {
- TC(mayhem, this);
- return _("Compete for the most damage dealt and frags in this chaotic mayhem!");
- }
ATTRIB(mayhem, m_legacydefaults, string, "1000 20 0");
ENDCLASS(mayhem)
REGISTER_GAMETYPE(MAYHEM, NEW(mayhem));
#include "nexball.qh"
+
+#ifdef MENUQC
+#include "weapon.qh"
+
+METHOD(NexBall, describe, string(NexBall this))
+{
+ TC(NexBall, this);
+ return sprintf(_("%s is a fun ball sport game where 2 teams compete to score the most goals\n\n"
+ "%s is usually played as either soccer where players walk into the ball to kick it around, or basketball where players have a %s so can pass the ball and intercept passes\n\n"
+ "Keep in mind players can score own goals, so don't embarrass yourself in front of your team!"),
+ COLORED_NAME(this), COLORED_NAME(this), COLORED_NAME(WEP_NEXBALL));
+}
+#endif
CLASS(NexBall, Gametype)
INIT(NexBall)
{
- this.gametype_init(this, _("Nexball"),"nb","g_nexball",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_WEAPONARENA,"","timelimit=20 pointlimit=5 leadlimit=0");
+ this.gametype_init(this, _("Nexball"),"nb","g_nexball",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_WEAPONARENA,"","timelimit=20 pointlimit=5 leadlimit=0",_("Shoot and kick the ball into the enemies goal, keep your goal clean"));
}
METHOD(NexBall, m_generate_mapinfo, void(Gametype this, string v))
{
TC(Gametype, this);
returns(menu, _("Goal limit:"), 1, 50, 1, "g_nexball_goallimit", string_null, _("The amount of goals needed before the match will end"));
}
- METHOD(NexBall, describe, string(NexBall this))
- {
- TC(NexBall, this);
- return _("Shoot and kick the ball into the enemies goal, keep your goal clean");
- }
#ifdef CSQC
ATTRIB(NexBall, m_modicons, void(vector pos, vector mySize), HUD_Mod_NexBall);
#endif
return false;
}
-#endif
+#endif // CSQC
+#ifdef MENUQC
+#include <common/gamemodes/gamemode/assault/assault.qh>
+#include <common/gamemodes/gamemode/domination/domination.qh>
+
+METHOD(Onslaught, describe, string(Onslaught this))
+{
+ TC(Onslaught, this);
+ return sprintf(_("%s is a team-based gamemode similar to %s where the final goal is to destroy the enemy team core generator. "
+ "In order to destroy the generator, control points on the map (similar to those in %s) must first be captured\n\n"
+ "Since your team can only capture a control point if it is connected to another control point currently owned by your team, you have to systematically work through the map to reach the enemy generator\n\n"
+ "A control point is captured by walking into it then waiting for it to finish constructing. "
+ "Control points of the opposing team are destroyed by attacking the \"info bot\" that hovers above them, converting the control point to neutral once it is destroyed\n\n"
+ "When in overtime, the enemy's generator will start to decay, at a faster rate the more control points your team has"),
+ COLORED_NAME(this), COLORED_NAME(MAPINFO_TYPE_ASSAULT));
+}
+
+#endif // MENUQC
CLASS(Onslaught, Gametype)
INIT(Onslaught)
{
- this.gametype_init(this, _("Onslaught"),"ons","g_onslaught",GAMETYPE_FLAG_TEAMPLAY,"","pointlimit=1 timelimit=20");
+ this.gametype_init(this, _("Onslaught"),"ons","g_onslaught",GAMETYPE_FLAG_TEAMPLAY,"","pointlimit=1 timelimit=20",_("Capture control points to reach and destroy the enemy generator"));
}
METHOD(Onslaught, m_generate_mapinfo, void(Gametype this, string v))
{
TC(Gametype, this);
returns(menu, _("Point limit:"), 50, 500, 10, string_null, string_null, string_null);
}
- METHOD(Onslaught, describe, string(Onslaught this))
- {
- TC(Onslaught, this);
- return _("Capture control points to reach and destroy the enemy generator");
- }
ATTRIB(Onslaught, m_legacydefaults, string, "20 0");
ENDCLASS(Onslaught)
REGISTER_GAMETYPE(ONSLAUGHT, NEW(Onslaught));
#include "race.qh"
+
+#ifdef MENUQC
+#include <common/gamemodes/gamemode/cts/cts.qh>
+
+METHOD(Race, describe, string(Race this))
+{
+ TC(Race, this);
+ return sprintf(_("%s is a gamemode similar to %s except the start and finish line of the track are identical, so you run laps repeatedly through the track\n\n"
+ "Consequently the aim is to keep running constantly to complete as many laps as possible for the shot at the fastest time, rather than resetting runs like in %s to set the individual best time. "
+ "Since you continue straight onto the next lap, having a speedy finish to a lap means that your next lap will start off with high speed, giving you a good shot at beating your personal best"),
+ COLORED_NAME(this), COLORED_NAME(MAPINFO_TYPE_CTS), COLORED_NAME(MAPINFO_TYPE_CTS));
+}
+#endif
CLASS(Race, Gametype)
INIT(Race)
{
- this.gametype_init(this, _("Race"),"rc","g_race",GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0");
+ this.gametype_init(this, _("Race"),"rc","g_race",GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 qualifying_timelimit=5 laplimit=7 teamlaplimit=15 leadlimit=0",_("Race against other players to the finish line"));
}
METHOD(Race, m_parse_mapinfo, bool(string k, string v))
{
TC(Gametype, this);
returns(menu, _("Laps:"), 1, 25, 1, "g_race_laps_limit", string_null, string_null);
}
- METHOD(Race, describe, string(Race this))
- {
- TC(Race, this);
- return _("Race against other players to the finish line");
- }
#ifdef CSQC
ATTRIB(Race, m_modicons, void(vector pos, vector mySize), HUD_Mod_Race);
#endif
#ifdef GAMEQC
REGISTER_NET_LINKED(ENT_CLIENT_SURVIVALSTATUSES)
#endif
+#ifdef MENUQC
+METHOD(Survival, describe, string(Survival this))
+{
+ TC(Survival, this);
+ return sprintf(_("%s is a hunter-survivor gamemode involving two teams where the goal of the hunters is to frag all survivors, and the goal of the survivors is to frag all hunters or survive until time runs out. "
+ "The trick lies in the fact that players only know which team they belong to, and not the team membership of any other players\n\n"
+ "Since the goal of both teams is essentially to eliminate all members of the opposite team, it can be tricky for survivors to figure out their fellow teammates\n\n"
+ "Teams are randomly selected as the round begins, with the hunter team being a bit smaller, "
+ "and then the round starts with a brief warmup grace period in which items can be collected but weapons can't be fired\n\n"
+ "Players are rewarded a point for each member of the opposing team they frag, only if they survive the round, and points are deducted for each teammate fragged. "
+ "Extra points are also to survivors who survive until the round timer expires"),
+ COLORED_NAME(this));
+}
+#endif
CLASS(Survival, Gametype)
INIT(Survival)
{
- this.gametype_init(this, _("Survival"), "surv", "g_survival", GAMETYPE_FLAG_USEPOINTS, "", "timelimit=20 pointlimit=12");
+ this.gametype_init(this, _("Survival"), "surv", "g_survival", GAMETYPE_FLAG_USEPOINTS, "", "timelimit=20 pointlimit=12",_("Identify and eliminate all the hunters before all your allies are gone"));
}
METHOD(Survival, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
{
}
return false;
}
- METHOD(Survival, describe, string(Survival this))
- {
- TC(Survival, this);
- return _("Identify and eliminate all the hunters before all your allies are gone");
- }
#ifdef CSQC
ATTRIB(Survival, m_modicons, void(vector pos, vector mySize), HUD_Mod_Survival);
#endif
#include "tdm.qh"
+
+#ifdef MENUQC
+#include <common/gamemodes/gamemode/deathmatch/deathmatch.qh>
+
+METHOD(TeamDeathmatch, describe, string(TeamDeathmatch this))
+{
+ TC(TeamDeathmatch, this);
+ return sprintf(_("%s is the team version of %s, played with 2 teams\n\n"
+ "Scoring is quite simple, adding a point for every frag, and subtracting a point for fragging yourself or a teammate\n\n"
+ "Careful team coordination and map control is often a key to winning a match, and sometimes players will share weapons with their teammates"),
+ COLORED_NAME(this), COLORED_NAME(MAPINFO_TYPE_DEATHMATCH));
+}
+#endif
CLASS(TeamDeathmatch, Gametype)
INIT(TeamDeathmatch)
{
- this.gametype_init(this, _("Team Deathmatch"),"tdm","g_tdm",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PRIORITY,"","timelimit=15 pointlimit=50 teams=2 leadlimit=0");
+ this.gametype_init(this, _("Team Deathmatch"),"tdm","g_tdm",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS | GAMETYPE_FLAG_PRIORITY,"","timelimit=15 pointlimit=50 teams=2 leadlimit=0",_("Help your team score the most frags against the enemy team"));
}
METHOD(TeamDeathmatch, m_parse_mapinfo, bool(string k, string v))
{
TC(Gametype, this);
returns(menu, _("Point limit:"), 5, 100, 5, "g_tdm_point_limit", "g_tdm_teams_override", _("The amount of points needed before the match will end"));
}
- METHOD(TeamDeathmatch, describe, string(TeamDeathmatch this))
- {
- TC(TeamDeathmatch, this);
- return _("Help your team score the most frags against the enemy team");
- }
ATTRIB(TeamDeathmatch, m_legacydefaults, string, "50 20 2 0");
ENDCLASS(TeamDeathmatch)
REGISTER_GAMETYPE(TEAM_DEATHMATCH, NEW(TeamDeathmatch));
#include "tka.qh"
+
+#ifdef MENUQC
+#include <common/gamemodes/gamemode/keepaway/keepaway.qh>
+
+METHOD(TeamKeepaway, describe, string(TeamKeepaway this))
+{
+ TC(TeamKeepaway, this);
+ return sprintf(_("%s is the team version of %s, where teams compete to maintain superior control over the ball\n\n"
+ "Scoring is similar to in %s, except that points are awarded for frags for all members of the team of the player holding the ball"),
+ COLORED_NAME(this), COLORED_NAME(MAPINFO_TYPE_KEEPAWAY), COLORED_NAME(MAPINFO_TYPE_KEEPAWAY));
+}
+#endif
CLASS(TeamKeepaway, Gametype)
INIT(TeamKeepaway)
{
- this.gametype_init(this, _("Team Keepaway"),"tka","g_tka",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=15 pointlimit=50 teams=2 leadlimit=0");
+ this.gametype_init(this, _("Team Keepaway"),"tka","g_tka",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=15 pointlimit=50 teams=2 leadlimit=0",_("Keep the ball in your team's possession to get points for kills"));
}
METHOD(TeamKeepaway, m_parse_mapinfo, bool(string k, string v))
{
{
cvar_set("g_tka_teams", sa);
}
- METHOD(TeamKeepaway, describe, string(TeamKeepaway this))
- {
- TC(TeamKeepaway, this);
- return _("Keep the ball in your team's possession to get points for kills");
- }
#ifdef CSQC
ATTRIB(TeamKeepaway, m_modicons, void(vector pos, vector mySize), HUD_Mod_TeamKeepaway);
#endif
#include "tmayhem.qh"
+
+#ifdef MENUQC
+#include <common/gamemodes/gamemode/clanarena/clanarena.qh>
+#include <common/gamemodes/gamemode/mayhem/mayhem.qh>
+
+METHOD(tmayhem, describe, string(tmayhem this))
+{
+ TC(tmayhem, this);
+ return sprintf(_("%s is a constant action team-based gamemode based on %s, using the same scoring system. "
+ "It has a lot of similarities to %s, with one of the main differences being that %s is a round-based gamemode, and of course the scoring system differences\n\n"
+ "Since it doesn't have rounds, the chaos is nonstop. "
+ "As a consequence of the chaotic nature, team communication is less important in this gamemode than other team-based gamemodes\n\n"),
+ COLORED_NAME(this), COLORED_NAME(MAPINFO_TYPE_MAYHEM), COLORED_NAME(MAPINFO_TYPE_CA), COLORED_NAME(MAPINFO_TYPE_CA));
+}
+#endif
CLASS(tmayhem, Gametype)
INIT(tmayhem)
{
- this.gametype_init(this, _("Team Mayhem"),"tmayhem","g_tmayhem",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=1500 teams=2 leadlimit=0");
+ this.gametype_init(this, _("Team Mayhem"),"tmayhem","g_tmayhem",GAMETYPE_FLAG_TEAMPLAY | GAMETYPE_FLAG_USEPOINTS,"","timelimit=20 pointlimit=1500 teams=2 leadlimit=0",_("Compete with your team for the most damage dealt and frags in this chaotic mayhem"));
}
METHOD(tmayhem, m_parse_mapinfo, bool(string k, string v))
{
TC(Gametype, this);
returns(menu, _("Point limit:"), 200, 3000, 100, "g_tmayhem_point_limit", "g_tmayhem_teams_override", _("How much score is needed before the match will end"));
}
- METHOD(tmayhem, describe, string(tmayhem this))
- {
- TC(tmayhem, this);
- return _("Compete with your team for the most damage dealt and frags in this chaotic mayhem!");
- }
ATTRIB(tmayhem, m_legacydefaults, string, "1500 20 2 0");
ENDCLASS(tmayhem)
REGISTER_GAMETYPE(TEAM_MAYHEM, NEW(tmayhem));
string MapInfo_Type_Description(Gametype t)
{
- return t ? t.describe(t) : "";
+ return t ? t.m_description : "";
}
string MapInfo_Type_ToString(Gametype t)
ATTRIB(Gametype, mdl, string);
/** human readable name */
ATTRIB(Gametype, message, string);
+ ATTRIB(Gametype, m_name, string);
+ /** color */
+ ATTRIB(Gametype, m_color, vector, '1 1 1');
/** does this gametype support teamplay? */
ATTRIB(Gametype, team, bool, false);
/** does this gametype use a point limit? */
ATTRIB(Gametype, m_1v1, bool, false);
/** game type defaults */
ATTRIB(Gametype, model2, string);
+ /** game type description */
+ ATTRIB(Gametype, m_description, string);
/** game type priority in random selections */
ATTRIB(Gametype, m_priority, int, 0);
#ifdef CSQC
returns(menu, _("Frag limit:"), 5, 100, 5, "fraglimit_override", string_null, _("The amount of frags needed before the match will end"));
}
- /* game type description
- * previously stored in a .string gametype_description ATTRIB
+#ifdef MENUQC
+ /* game type guide description
+ * this description is used in the guide, the description stored in .m_description is shorter and used for things like the mapvoting dialog
*/
METHOD(Gametype, describe, string(Gametype this))
{
TC(Gametype, this);
return SUPER(Object).describe(this);
}
+#endif
METHOD(Gametype, display, void(Gametype this, void(string name, string icon) returns))
{
returns(this.message, strcat("gametype_", this.mdl));
}
- METHOD(Gametype, gametype_init, void(Gametype this, string hname, string sname, string g_name, int gflags, string mutators, string defaults))
+ METHOD(Gametype, gametype_init, void(Gametype this, string hname, string sname, string g_name, int gflags, string mutators, string defaults, string gdescription))
{
this.netname = g_name;
this.mdl = sname;
this.message = hname;
+ this.m_name = hname;
this.team = (gflags & GAMETYPE_FLAG_TEAMPLAY);
this.m_mutators = cons(sname, mutators);
this.model2 = defaults;
+ this.m_description = gdescription;
this.frags = (gflags & GAMETYPE_FLAG_USEPOINTS);
this.m_priority = ((gflags & GAMETYPE_FLAG_PREFERRED) ? 2 : ((gflags & GAMETYPE_FLAG_PRIORITY) ? 1 : 0));
this.m_hidelimits = (gflags & GAMETYPE_FLAG_HIDELIMITS);