Descriptions were somewhat based on https://gitlab.com/xonotic/xonotic/-/wikis/Weapons but since that's in a format not really suitable for a guide, I took some creative liberty.
W_PROPS(X, OverkillHeavyMachineGun, okhmg)
#undef X
+METHOD(OverkillHeavyMachineGun, describe, string(OverkillHeavyMachineGun this)) {
+ TC(OverkillHeavyMachineGun, this);
+ return _("The Overkill Heavy Machine Gun is a superweapon that rapidly fires harmful bullets with a small degree of spread\n\n"
+ "Like with all Overkill weapons, the secondary fire shoots a laser which does not damage or push enemies, but can be used to push yourself around\n\n"
+ "It is a superweapon found on some maps, meaning that it breaks down after some time\n\n"
+ "The primary fire consumes Bullets ammo, although you spawn with an infinite amount of it in Overkill. "
+ "It has a limited magazine size, so needs reloading after several shots\n\n"
+ "The Overkill Heavy Machine Gun can be used in a lot of situations, and it works particularly well at long ranges since the bullets pierce the sky instantaneously\n\n"
+ "Since its bullets deal a lot more damage than the Overkill MachineGun's bullets, it is often heavily contested when it spawns in");
+}
ENDCLASS(OverkillHeavyMachineGun)
REGISTER_WEAPON(OVERKILL_HMG, NEW(OverkillHeavyMachineGun));
W_PROPS(X, OverkillMachineGun, okmachinegun)
#undef X
+METHOD(OverkillMachineGun, describe, string(OverkillMachineGun this)) {
+ TC(OverkillMachineGun, this);
+ return _("The Overkill MachineGun quickly fires bullets with a small degree of spread\n\n"
+ "Like with all Overkill weapons, the secondary fire shoots a laser which does not damage or push enemies, but can be used to push yourself around\n\n"
+ "The primary fire consumes Bullets ammo, although you spawn with an infinite amount of it in Overkill. "
+ "It has a limited magazine size, so needs reloading after several shots\n\n"
+ "The Overkill MachineGun can be used in a lot of situations, and it works particularly well at long ranges since the bullets pierce the sky instantaneously");
+}
ENDCLASS(OverkillMachineGun)
REGISTER_WEAPON(OVERKILL_MACHINEGUN, NEW(OverkillMachineGun));
W_PROPS(X, OverkillNex, oknex)
#undef X
+METHOD(OverkillNex, describe, string(OverkillNex this)) {
+ TC(OverkillNex, this);
+ return _("The Overkill Nex fires harmful beams of energy that traverse the map instantaneously and deal a significant chunk of damage on impact\n\n"
+ "Like with all Overkill weapons, the secondary fire shoots a laser which does not damage or push enemies, but can be used to push yourself around\n\n"
+ "The primary fire consumes Cells ammo, although you spawn with an infinite amount of it in Overkill. "
+ "It has a limited magazine size, so needs reloading after several shots\n\n"
+ "Since it is the only Overkill weapon with no spread, the Overkill Nex stands out at long ranges");
+}
ENDCLASS(OverkillNex)
REGISTER_WEAPON(OVERKILL_NEX, NEW(OverkillNex));
W_PROPS(X, OverkillRocketPropelledChainsaw, okrpc)
#undef X
+METHOD(OverkillRocketPropelledChainsaw, describe, string(OverkillRocketPropelledChainsaw this)) {
+ TC(OverkillRocketPropelledChainsaw, this);
+ return _("As the name suggests, the Overkill Rocket Propelled Chainsaw fires a rocket propelled chainsaw which explodes on impact, dealing a lot of splash damage to any players close by\n\n"
+ "Like with all Overkill weapons, the secondary fire shoots a laser which does not damage or push enemies, but can be used to push yourself around\n\n"
+ "The primary fire consumes Rockets ammo, although you spawn with an infinite amount of it in Overkill\n\n"
+ "Since it is the only Overkill weapon which deals splash damage, the Overkill Rocket Propelled Chainsaw is a good choice of weapon for attacking groups of enemies");
+}
ENDCLASS(OverkillRocketPropelledChainsaw)
REGISTER_WEAPON(OVERKILL_RPC, NEW(OverkillRocketPropelledChainsaw));
W_PROPS(X, OverkillShotgun, okshotgun)
#undef X
+METHOD(OverkillShotgun, describe, string(OverkillShotgun this)) {
+ TC(OverkillShotgun, this);
+ return _("The Overkill Shotgun fires a single shotgun round which spreads into multiple pellets upon exiting the barrel, dealing a deadly blow if up close\n\n"
+ "Like with all Overkill weapons, the secondary fire shoots a laser which does not damage or push enemies, but can be used to push yourself around\n\n"
+ "The primary fire consumes Shells ammo, although you spawn with an infinite amount of it in Overkill. "
+ "It has a limited magazine size, so needs reloading after several shots\n\n"
+ "The Shotgun's damage drops off quickly as the range increases, so it is only useful for close combat or sometimes medium range combat");
+}
ENDCLASS(OverkillShotgun)
REGISTER_WEAPON(OVERKILL_SHOTGUN, NEW(OverkillShotgun));
METHOD(Weapon, display, void(entity this, void(string name, string icon) returns)) {
returns(this.m_name, this.model2 ? sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.model2) : string_null);
}
+ METHOD(Weapon, describe, string(Weapon this)) {
+ TC(Weapon, this);
+ return SUPER(Object).describe(this);
+ }
ENDCLASS(Weapon)
#ifdef SVQC
W_PROPS(X, Arc, arc)
#undef X
+METHOD(Arc, describe, string(Arc this)) {
+ TC(Arc, this);
+ return _("The Arc fires a continuous stream of electricity, steadily dealing damage to any enemies that cross its path\n\n"
+ "The secondary fire rapidly shoots electro balls forward, exploding on impact and dealing some splash damage\n\n"
+ "It consumes Cells ammo, steadily churning through your supply to maintain the stream\n\n"
+ "The Arc is quite a versatile weapon, however it is more effective at close to medium ranges, since the stream is not instantaneous");
+}
ENDCLASS(Arc)
REGISTER_WEAPON(ARC, NEW(Arc));
W_PROPS(X, Blaster, blaster)
#undef X
+METHOD(Blaster, describe, string(Blaster this)) {
+ TC(Blaster, this);
+ return _("The Blaster is one of the two main default weapons, firing a relatively weak high speed laser forwards, dealing some splash damage but importantly a lot of knockback\n\n"
+ "It has no secondary fire, instead switching to the previously selected weapon\n\n"
+ "It doesn't require ammo, meaning it is a great choice if you are running low on ammo and need to preserve some\n\n"
+ "The Blaster is always available so ends up being used a lot when players spawn in, but it's difficult to master when used over a medium to long range. "
+ "One of the most common uses of the Blaster is \"laser jumping\", where you can gain height by aiming down, jumping, then firing to boost yourself up. "
+ "Because it does a lot of knockback, another common usage is alternating between a high damage weapon and the Blaster to throw the enemy's aim off");
+}
ENDCLASS(Blaster)
REGISTER_WEAPON(BLASTER, NEW(Blaster));
W_PROPS(X, Crylink, crylink)
#undef X
+METHOD(Crylink, describe, string(Crylink this)) {
+ TC(Crylink, this);
+ return _("The Crylink fires bursts of laser-like projectiles, spreading out as they travel away, and deflecting off walls. "
+ "If the primary fire is held, when it's released the projectiles will converge before spreading out again, "
+ "which can be utilized to deal more damage to an enemy by making the projectiles converge on them\n\n"
+ "The secondary fire shoots the projectiles together in a tight group, so it is often the better option in situations where the enemy is an easy target to hit\n\n"
+ "It consumes Cells ammo for each projectile, which is shared by several weapons\n\n"
+ "Close to medium range is the ideal time to use the Crylink, although the secondary fire can be useful for long range combat sometimes\n\n"
+ "The Crylink deals knockback in a unique way, pulling the player from their center to the point of impact. "
+ "This makes it one of the best weapons to slow someone down if you are chasing them, particularly with the secondary fire. "
+ "Another common use of the Crylink is \"crylink running\", where you partially angle down and use the secondary fire to pull yourself forwards, in order to gain speed");
+}
ENDCLASS(Crylink)
REGISTER_WEAPON(CRYLINK, NEW(Crylink));
W_PROPS(X, Devastator, devastator)
#undef X
+METHOD(Devastator, describe, string(Devastator this)) {
+ TC(Devastator, this);
+ return _("The Devastator launches a remote controlled rocket, dealing significant damage when it explodes on impact. "
+ "If the primary fire is held, the rocket can be guided by the user's aim, allowing steering it towards enemies\n\n"
+ "The secondary fire can be used to immediately detonate the most recently fired rocket, allowing dealing damage to enemies even if the rocket barely missed colliding with them\n\n"
+ "It consumes a bunch of Rockets ammo for each rocket, which can end up being depleted quickly, so often players alternate with another weapon like Vortex\n\n"
+ "Due to its high damage output, the Devastator is one of the most commonly used weapons. "
+ "It can be used in almost any scenario, working best in medium range combat. "
+ "In close range combat, the large splash radius means often rockets can damage yourself as well as the enemy\n\n"
+ "Due to the ability to remotely detonate rockets, a common usage is \"rocket flying\", where you fire a rocket and immediately detonate it to boost yourself while mid-air");
+}
ENDCLASS(Devastator)
REGISTER_WEAPON(DEVASTATOR, NEW(Devastator));
W_PROPS(X, Electro, electro)
#undef X
+METHOD(Electro, describe, string(Electro this)) {
+ TC(Electro, this);
+ return _("The Electro shoots electric balls forwards, dealing some splash damage when they burst on impact\n\n"
+ "The secondary fire launches similar balls that are influenced by gravity, "
+ "so they can be laid around the map at high traffic locations (like the flag in Capture The Flag) to damage enemies that walk by. "
+ "The balls burst after some time, and can be forced to burst in a \"combo\" if a primary fire ball bursts near them\n\n"
+ "It consumes some Cells ammo for each ball\n\n"
+ "The Electro is one of the best spam weapons to use in crowded areas, since combos can deal tons of damage, if the enemy is close enough. "
+ "Since the primary fire doesn't travel particularly fast, the Electro is not useful in many other situations");
+}
ENDCLASS(Electro)
REGISTER_WEAPON(ELECTRO, NEW(Electro));
W_PROPS(X, Fireball, fireball)
#undef X
+METHOD(Fireball, describe, string(Fireball this)) {
+ TC(Fireball, this);
+ return _("The Fireball supercharges then fires a massive fireball in a straight line, dealing heaps of splash damage over a large radius on impact\n\n"
+ "The secondary fire launches flaming balls that set nearby players alight\n\n"
+ "It is a superweapon, so isn't often found in game\n\n"
+ "It doesn't require ammo, but it is destroyed after some time\n\n"
+ "Since the Fireball takes a moment to charge and the fireball travels slowly, using it effectively may be difficult, "
+ "but if done properly it can deal a ton of damage");
+}
ENDCLASS(Fireball)
REGISTER_WEAPON(FIREBALL, NEW(Fireball));
W_PROPS(X, Hagar, hagar)
#undef X
+METHOD(Hagar, describe, string(Hagar this)) {
+ TC(Hagar, this);
+ return _("The Hagar rapidly fires small propelled rockets forwards, dealing some splash damage on impact\n\n"
+ "When the secondary fire is held, multiple rockets are loaded up, and they're shot at the same time when released. "
+ "These rockets can't be held forever, so it will fire itself after some time (after a warning beep) if the secondary fire isn't released\n\n"
+ "It consumes Rockets ammo for each rocket\n\n"
+ "The Hagar works best over close to medium ranges, since it's hard to land hits at a long distance. "
+ "A common usage is fully loading the secondary fire before turning a corner, so you can surprise any enemies around the corner with a bunch of rockets to the face");
+}
ENDCLASS(Hagar)
REGISTER_WEAPON(HAGAR, NEW(Hagar));
W_PROPS(X, HLAC, hlac)
#undef X
+METHOD(HLAC, describe, string(HLAC this)) {
+ TC(HLAC, this);
+ return _("The Heavy Assualt Laser Cannon (or HLAC for short) fires lasers in quick succession. "
+ "The projectiles it fires are similar to those of the Blaster\n\n"
+ "The secondary fire shoots a randomly scattered burst of multiple lasers at once\n\n"
+ "Unlike the Blaster, it consumes Cells ammo for each laser shot, meaning that it cannot be used infinitely\n\n"
+ "The HLAC works best in close ranges, but the primary fire is also useful in medium ranges\n\n"
+ "A unique aspect of the HLAC is that the longer the primary fire is held, the more that the lasers will start to spread out. "
+ "This means releasing primary fire every now and then is important to restore accuracy. "
+ "Also, the HLAC has less spread when used while crouching");
+}
ENDCLASS(HLAC)
REGISTER_WEAPON(HLAC, NEW(HLAC));
W_PROPS(X, Hook, hook)
#undef X
+METHOD(Hook, describe, string(Hook this)) {
+ TC(Hook, this);
+ return _("The Grappling Hook is a unique weapon, firing a chain forwards which pulls you in once it latches onto something\n\n"
+ "The secondary fire usually drops a gravity bomb that affects enemies, also releasing light a smoke like a flashbang\n\n"
+ "It usually requires Fuel ammo to work, consuming it both when initially firing the hook, and after a couple seconds as it reels you in\n\n"
+ "The Grappling Hook allows reaching previously unreachable places on maps and zooming around the map at high speeds, "
+ "making both surprise ambushes and miraculous escapes possible\n\n"
+ "It isn't available very often on maps, unless the Grappling Hook mutator is active, in which all players have it on their offhand, used with the +hook bind");
+}
ENDCLASS(Hook)
REGISTER_WEAPON(HOOK, NEW(Hook));
W_PROPS(X, MachineGun, machinegun)
#undef X
+METHOD(MachineGun, describe, string(MachineGun this)) {
+ TC(MachineGun, this);
+ return _("The MachineGun quickly fires bullets with a small degree of spread\n\n"
+ "The secondary fire fires a quick burst of bullets faster than the primary fire and with no spread, but there's a short delay until it can be used again\n\n"
+ "It consumes Bullets ammo for each bullet shot, until the whole magazine is emptied\n\n"
+ "The MachineGun can be used in a lot of situations, and it works particularly well at long ranges since the bullets pierce the sky instantaneously. "
+ "Since the secondary fire has no spread, it's the better option when firing over a long range");
+}
ENDCLASS(MachineGun)
REGISTER_WEAPON(MACHINEGUN, NEW(MachineGun));
END()
W_PROPS(X, MineLayer, minelayer)
#undef X
+
+METHOD(MineLayer, describe, string(MineLayer this)) {
+ TC(MineLayer, this);
+ return _("The Mine Layer places mines on the ground when fired, which detonate and damage enemies if stepped on. "
+ "Only a couple mines can be placed at any time, and after several seconds they will self-detonate\n\n"
+ "The secondary fire instantaneously detonates any mines fired by the primary fire, first waiting until you're far enough away\n\n"
+ "It consumes Rockets ammo for each mine laid\n\n"
+ "The mines are not launched very far before they hit the ground, so the Mine Layer isn't very effective at medium to long ranges. "
+ "It is often used to protect important areas of the map such as the flag in Capture The Flag, control points in Onslaught, or checkpoints in Assault");
+}
ENDCLASS(MineLayer)
REGISTER_WEAPON(MINE_LAYER, NEW(MineLayer));
END()
W_PROPS(X, Mortar, mortar)
#undef X
+
+METHOD(Mortar, describe, string(Mortar this)) {
+ TC(Mortar, this);
+ return _("The Mortar launches a grenade that explodes immediately on impact, dealing a medium amount of splash damage\n\n"
+ "The secondary fire shoots a similar grenade that explodes shortly after bouncing\n\n"
+ "It consumes Rockets ammo for every grenade launched\n\n"
+ "The Mortar works best at close to medium ranges, but it's quite tricky to hit an enemy if they're airborne. "
+ "Since the secondary fire grenade bounces before exploding, it can be bounced against walls to damage enemies lurking around a corner");
+}
ENDCLASS(Mortar)
REGISTER_WEAPON(MORTAR, NEW(Mortar));
END()
W_PROPS(X, PortoLaunch, porto)
#undef X
+
+METHOD(PortoLaunch, describe, string(PortoLaunch this)) {
+ TC(PortoLaunch, this);
+ return _("The Port-O-Launch is a unique gun that creates one-way portals between flat surfaces on the map, that immediately teleport players and projectiles\n\n"
+ "The secondary fire is used to shoot the out-portal, while the primary fire shoots the in-portal\n\n"
+ "It doesn't require ammo, but it is destroyed after some time\n\n"
+ "The portals will close either after the player who shot them dies or after some time period"
+ "The Port-O-Launch isn't often placed on maps, but if used well it can make for some interesting gameplay");
+}
ENDCLASS(PortoLaunch)
REGISTER_WEAPON(PORTO, NEW(PortoLaunch));
END()
W_PROPS(X, Rifle, rifle)
#undef X
+
+METHOD(Rifle, describe, string(Rifle this)) {
+ TC(Rifle, this);
+ return _("The Rifle fires bullets that traverse the map instantaneously and deal a significant chunk of damage on impact\n\n"
+ "The secondary fire shoots a few less powerful bullets at once with a bit of scatter\n\n"
+ "It consumes Bullets ammo for each bullet shot\n\n"
+ "Unlike the Vortex, the secondary fire doesn't zoom, so the +zoom bind needs to be used manually with the Rifle. "
+ "Also, it needs to be reloaded after its magazine is emptied\n\n"
+ "Similar to the Vortex, the Rifle can be used at any range, but it stands out at long ranges");
+}
ENDCLASS(Rifle)
REGISTER_WEAPON(RIFLE, NEW(Rifle));
END()
W_PROPS(X, Seeker, seeker)
#undef X
+
+METHOD(Seeker, describe, string(Seeker this)) {
+ TC(Seeker, this);
+ return _("The T.A.G. Seeker is a unique weapon, firing a \"tag\" which then launches a few homing missiles if it collides with a player. "
+ "The homing isn't perfect, so sometimes the missiles can hit an object or a corner\n\n"
+ "The secondary fire launches a rapid barrage of scattered explosives that travel only a short distance\n\n"
+ "It consumes Rockets ammo, even when the tag doesn't land\n\n"
+ "The T.A.G. Seeker primary fire deals quite a lot of damage when a tag lands, although it requires skill to aim effectively. "
+ "The secondary fire is only useful in close range combat, and sometimes the explosives can damage yourself too");
+}
ENDCLASS(Seeker)
REGISTER_WEAPON(SEEKER, NEW(Seeker));
W_PROPS(X, Shockwave, shockwave)
#undef X
+METHOD(Shockwave, describe, string(Shockwave this)) {
+ TC(Shockwave, this);
+ return _("The Shockwave is a unique weapon, firing shockwave blasts that deal damage over a short range\n\n"
+ "Similar to the Shotgun, the secondary fire swings the Shockwave, slapping players close enough with the head of the weapon\n\n"
+ "It doesn't require ammo to work\n\n"
+ "The Shockwave can only deal damage over a short range, so it is not useful for medium and long range combat");
+}
ENDCLASS(Shockwave)
REGISTER_WEAPON(SHOCKWAVE, NEW(Shockwave));
W_PROPS(X, Shotgun, shotgun)
#undef X
+METHOD(Shotgun, describe, string(Shotgun this)) {
+ TC(Shotgun, this);
+ return _("The Shotgun is one of the two main default weapons, firing a single shotgun round which spreads into multiple pellets upon exiting the barrel\n\n"
+ "The secondary fire swings the Shotgun, slapping players close enough with the head of the weapon. "
+ "Since the slap takes a moment to land, timing this well is difficult\n\n"
+ "The primary fire consumes Shells ammo, although if you spawn in with the Shotgun you will already have some\n\n"
+ "The Shotgun's damage drops off quickly as the range increases, so it is only useful for close combat or sometimes medium range combat");
+}
ENDCLASS(Shotgun)
REGISTER_WEAPON(SHOTGUN, NEW(Shotgun));
END()
W_PROPS(X, Tuba, tuba)
#undef X
+
+METHOD(Tuba, describe, string(Tuba this)) {
+ TC(Tuba, this);
+ return _("The @!#%'n Tuba is unique weapon that makes the ears of nearby enemies bleed by playing awful sounds, also slightly knocking them back\n\n"
+ "The secondary fire works the same way, playing a higher pitch\n\n"
+ "The only ammo it needs to operate is the breath from your lungs\n\n"
+ "Since your enemies need to be close by to hear your awful music, the @!#%'n Tuba is only effective at very close ranges\n\n"
+ "The pitch the @!#%'n Tuba plays depends on the movement keys pressed. "
+ "Reloading the weapon switches its model and notes played");
+}
ENDCLASS(Tuba)
REGISTER_WEAPON(TUBA, NEW(Tuba));
W_PROPS(X, Vaporizer, vaporizer)
#undef X
+METHOD(Vaporizer, describe, string(Vaporizer this)) {
+ TC(Vaporizer, this);
+ return _("The Vaporizer is unique weapon, firing a deadly beam of energy dealing a huge amount of damage. "
+ "In InstaGib, the beam has the ability to instantly kill enemies with a single shot, unless they have an Extra Life\n\n"
+ "The secondary fire fires a laser similar to that fired by the Blaster, with very strong knockback\n\n"
+ "It is a superweapon, so isn't often found in game, except in InstaGib where all players spawn with it\n\n"
+ "It consumes some Cells ammo with each shot");
+}
ENDCLASS(Vaporizer)
REGISTER_WEAPON(VAPORIZER, NEW(Vaporizer));
W_PROPS(X, Vortex, vortex)
#undef X
+METHOD(Vortex, describe, string(Vortex this)) {
+ TC(Vortex, this);
+ return _("The Vortex fires harmful beams of energy that traverse the map instantaneously and deal a significant chunk of damage on impact\n\n"
+ "The secondary fire zooms in when held, allowing for ease of aiming\n\n"
+ "It consumes Cells ammo for each bullet shot\n\n"
+ "Unlike the Rifle, the Vortex doesn't need to be reloaded manually, although you have to wait a couple seconds between shots. "
+ "Uniquely, the Vortex can be fired slightly before it finishes completely reloading, albeit dealing slightly less damage\n\n"
+ "Similar to the Rifle, the Vortex can be used at any range, but it stands out at long ranges");
+}
ENDCLASS(Vortex)
REGISTER_WEAPON(VORTEX, NEW(Vortex));