]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into Mario/qc_camstuff
authorMario <mario.mario@y7mail.com>
Mon, 30 Sep 2019 14:07:37 +0000 (00:07 +1000)
committerMario <mario.mario@y7mail.com>
Mon, 30 Sep 2019 14:07:37 +0000 (00:07 +1000)
102 files changed:
.gitlab-ci.yml
_hud_descriptions.cfg
commands.cfg
crosshairs.cfg
gamemodes-server.cfg
help-xonotic.cfg
help.cfg
hud_luma.cfg
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_minimal_xhair.cfg
hud_luminos_old.cfg
hud_nexuiz.cfg
physicsCPMA.cfg
physicsQ2.cfg
physicsQ2a.cfg
physicsQ3.cfg
physicsWarsow.cfg
physicsWarsowClassicBunny.cfg
physicsWarsowDev.cfg
qcsrc/client/autocvars.qh
qcsrc/client/csqcmodel_hooks.qc
qcsrc/client/defs.qh
qcsrc/client/hud/hud_config.qc
qcsrc/client/hud/panel/ammo.qc
qcsrc/client/hud/panel/weapons.qc
qcsrc/client/teamradar.qc
qcsrc/client/view.qc
qcsrc/common/debug.qh
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc
qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qc
qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc
qcsrc/common/items/item.qh
qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/common/mapobjects/func/door.qc
qcsrc/common/mutators/mutator/buffs/sv_buffs.qc
qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc
qcsrc/common/mutators/mutator/dodging/sv_dodging.qc
qcsrc/common/mutators/mutator/instagib/sv_instagib.qc
qcsrc/common/mutators/mutator/nix/sv_nix.qc
qcsrc/common/mutators/mutator/overkill/okhmg.qc
qcsrc/common/mutators/mutator/overkill/okmachinegun.qc
qcsrc/common/mutators/mutator/overkill/oknex.qc
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/mutators/mutator/spawn_near_teammate/sv_spawn_near_teammate.qc
qcsrc/common/physics/player.qc
qcsrc/common/t_items.qc
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/crylink.qc
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/hagar.qc
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/hook.qc
qcsrc/common/weapons/weapon/machinegun.qc
qcsrc/common/weapons/weapon/seeker.qc
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/vortex.qc
qcsrc/dpdefs/csprogsdefs.qh
qcsrc/dpdefs/dpextensions.qh
qcsrc/dpdefs/progsdefs.qh
qcsrc/ecs/systems/physics.qc
qcsrc/lib/_all.inc
qcsrc/lib/csqcmodel/interpolate.qc
qcsrc/lib/deglobalization.qh [new file with mode: 0644]
qcsrc/lib/float.qh
qcsrc/lib/vector.qh
qcsrc/lib/warpzone/anglestransform.qc
qcsrc/lib/warpzone/anglestransform.qh
qcsrc/lib/warpzone/common.qc
qcsrc/lib/warpzone/mathlib.qc
qcsrc/lib/warpzone/server.qc
qcsrc/lib/warpzone/util_server.qc
qcsrc/menu/xonotic/_mod.inc
qcsrc/menu/xonotic/_mod.qh
qcsrc/menu/xonotic/dialog_disconnect.qc [new file with mode: 0644]
qcsrc/menu/xonotic/dialog_disconnect.qh [new file with mode: 0644]
qcsrc/menu/xonotic/dialog_multiplayer_join.qc
qcsrc/menu/xonotic/dialog_singleplayer.qc
qcsrc/menu/xonotic/mainwindow.qc
qcsrc/menu/xonotic/mainwindow.qh
qcsrc/menu/xonotic/serverlist.qc
qcsrc/menu/xonotic/serverlist.qh
qcsrc/server/autocvars.qh
qcsrc/server/bot/default/navigation.qc
qcsrc/server/campaign.qc
qcsrc/server/client.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/spawnpoints.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/tracing.qc
qcsrc/server/weapons/weaponsystem.qc
qcsrc/tools/compilationunits.sh
qcsrc/tools/qcc.sh
ruleset-XDF.cfg
ruleset-overkill.cfg
xonotic-client.cfg
xonotic-server.cfg

index 2a26756c55f5bb7840047adfa2163d3d062b07fa..8724d06617940c0ed8cf76c67ad0fc94a25cb5a9 100644 (file)
@@ -56,6 +56,9 @@ test_sv_unit:
       done < <(${ENGINE} +developer 1 +map gitlab-ci +sv_cmd runtest +exit)
     - exit 1
 
+# NOTE: The generated docs are incomplete - they don't contain code behind SVQC CSQC MENUQC GAMEQC ifdefs.
+# With them added to PREDEFINED, it would take over half an hour to generate the docs and even then
+# they might not be complete. Doxygen doesn't handle #elif and might not understand some QC definitions.
 doxygen:  # rename to 'pages' when gitlab.com allows pages to exceed 100MiB
   stage: deploy
   script:
index 30e5a8bee9a8756fe9fafe883306260e1e4025aa..6e393e6a57eff4fdba4a60878e94ce0a2d106ead 100644 (file)
@@ -63,6 +63,7 @@ seta hud_panel_weapons_label_scale "" "scale of the weapon text label"
 seta hud_panel_weapons_accuracy "" "show accuracy color as the weapon icon background; colors can be configured with accuracy_color* cvars"
 seta hud_panel_weapons_ammo "" "show ammo as a status bar"
 seta hud_panel_weapons_onlyowned "" "show only owned weapons, set it to 2 to show only the held weapon"
+seta hud_panel_weapons_orderbyimpulse "" "List weapons in their impulse order instead of priority"
 seta hud_panel_weapons_noncurrent_alpha "" "alpha of noncurrent weapons"
 seta hud_panel_weapons_noncurrent_scale "" "scale of noncurrent weapons, relative to the current weapon"
 seta hud_panel_weapons_selection_radius "" "number of weapons that get partially highlighted on each side of the currently selected weapon"
index d5da481b9794517a219a0879092a01bf01c64c0a..584ac0f1e4c27afcbf09cd8ca0ad2b113f39a684 100644 (file)
@@ -235,6 +235,8 @@ alias warp                 "qc_cmd_sv     warp                 ${* ?}" // Choose
 
 // other aliases for server commands
 alias endmatch "timelimit -1"
+alias bots "minplayers 4; minplayers_per_team 2"
+alias nobots "minplayers 0; minplayers_per_team 0"
 
 alias savedb "sv_cmd database save \"${1 ?}\""
 alias dumpdb "sv_cmd database dump \"${1 ?}\""
@@ -322,13 +324,13 @@ set sv_vote_command_help_gotomap "\nUsage:^3 vcall gotomap mapname\n^7  Where 'm
 // =================================
 set sv_vote_call 1 "Allow users to call a vote for the commands in sv_vote_commands"
 set sv_vote_change 1 "Allow voters to change their mind after already voting"
-set sv_vote_commands "restart fraglimit chmap gotomap nextmap endmatch reducematchtime extendmatchtime allready kick cointoss movetoauto shuffleteams" "these commands can be voted"
+set sv_vote_commands "restart fraglimit chmap gotomap nextmap endmatch reducematchtime extendmatchtime allready kick cointoss movetoauto shuffleteams bots nobots" "these commands can be voted by players or used directly by masters (vdo) in addition to sv_vote_master_commands"
 set sv_vote_only_commands ""
 set sv_vote_limit 160 "Maximum allowed length of a vote command"
-set sv_vote_master_commands "movetored movetoblue movetoyellow movetopink movetospec " "Extra commands which vote masters can execute by themselves, along with the normal sv_vote_commands." // maybe add kickban here (but then sv_vote_master 0)
+set sv_vote_master_commands "movetored movetoblue movetoyellow movetopink movetospec" "Extra commands which vote masters can execute by themselves, along with the normal sv_vote_commands." // maybe add kickban here (but then sv_vote_master 0)
 set sv_vote_master 0   "Allows the use of the vote master system"
 set sv_vote_master_callable 0 "When set, users can use \"vmaster\" to call a vote to become master of voting commands"
-set sv_vote_master_password "" "when set, users can use \"vlogin PASSWORD\" to log in as master"
+set sv_vote_master_password "" "when set, users can use \"vlogin PASSWORD\" to log in as master, then run master commands directly using vdo"
 set sv_vote_master_playerlimit 2 "Minimum number of players needed for a player to be allowed to vote for master"
 set sv_vote_no_stops_vote 1 "Allow the vote caller to stop his own vote simply by voting no"
 set sv_vote_singlecount 0      "set to 1 to count votes once after timeout or to 0 to count with every vote"
@@ -372,4 +374,4 @@ alias vext "vcall extendmatchtime"
 //  rcon server commands
 // ======================
 rcon_secure 1
-set rcon_restricted_commands "restart fraglimit chmap gotomap endmatch reducematchtime extendmatchtime allready kick kickban \"sv_cmd bans\" \"sv_cmd unban *\" status \"sv_cmd teamstatus\" movetoauto movetored movetoblue movetoyellow movetopink movetospec"
+set rcon_restricted_commands "restart fraglimit chmap gotomap nextmap endmatch reducematchtime extendmatchtime allready kick cointoss movetoauto shuffleteams bots nobots movetored movetoblue movetoyellow movetopink movetospec kickban \"sv_cmd bans\" \"sv_cmd unban *\" status \"sv_cmd teamstatus\""
index 82758fa7025dc76c8d96b722603a1f4ce40aafc4..47631f0fa6cb70b4a664e493ff5dd06bd300bfae 100644 (file)
@@ -34,7 +34,7 @@ seta crosshair_hitindication_speed 5
 set g_trueaim_minrange 44 "TrueAim minimum range (TrueAim adjusts shots so they hit the crosshair point even though the gun is not at the screen center)"
 seta crosshair_hittest 1 "do a crosshair hit evaluation, applying effects from the _blur, _scale, and _showipact cvars"
 seta crosshair_hittest_blur 1 "blur the crosshair if the shot is obstructed"
-seta crosshair_hittest_scale 1.25 "enlarge crosshair if aiming at an enemy, shrink crosshair if shot is obstructed or aiming at a teammate"
+seta crosshair_hittest_scale 1.25 "shrink crosshair if shot is obstructed or aiming at a teammate"
 seta crosshair_hittest_showimpact 0 "move the crosshair to the actual impact location if obstructed"
 
 // change color based on special case
index 548a512234f7afce4c83377131fc383592a7375c..6d8ee6f07364532ee1ecb47cc6e051b8a4181823 100644 (file)
@@ -57,15 +57,16 @@ alias sv_vote_gametype_hook_rc
 alias sv_vote_gametype_hook_tdm
 alias sv_vote_gametype_hook_duel
 
-// Example preset to allow 1v1ctf to be used for the gametype voting screen
+// Example preset to allow 1v1ctf to be used for the gametype voting screen.
+// Aliases can have max 31 chars so the gametype can have max 9 chars.
 // sv_vote_gametype_*_type Must be set to the name of the gametype the option is based on
 // sv_vote_gametype_*_name Contains a human-readable name of the gametype
 // sv_vote_gametype_*_description Contains a longer description
 //set sv_vote_gametype_1v1ctf_type ctf
 //set sv_vote_gametype_1v1ctf_name "Capture the Flag Duel"
 //set sv_vote_gametype_1v1ctf_description "One vs One match in CTF"
-//alias sv_vote_gametype_hook_all "set g_maxplayers 0"
-//alias sv_vote_gametype_hook_1v1ctf "set g_maxplayers 2"
+//alias sv_vote_gametype_hook_all "g_maxplayers 0"
+//alias sv_vote_gametype_hook_1v1ctf "g_maxplayers 2"
 
 
 // ===========
@@ -239,7 +240,7 @@ set g_ctf_leaderboard 0 "show top capture times in the scoreboard"
 set g_ctf_flag_return 1 "auto return the flag to base when touched by a teammate"
 set g_ctf_flag_return_carrying 0 "(manual return mode) auto return the flag to base if touched by a flag carrier"
 set g_ctf_flag_return_carried_radius 100 "allow flags to be returned by carrier if base is within this radius"
-set g_ctf_flag_return_time 15 "automatically return the flag to base after this amount of time"
+set g_ctf_flag_return_time 30 "automatically return the flag to base after this amount of time"
 set g_ctf_flag_return_dropped 100 "automatically return the flag to base if dropped within this distance from base (in qu)"
 set g_ctf_flag_return_damage 0 "allow the flag to be damaged, reducing time needed to automatically return to base"
 set g_ctf_flag_return_damage_delay 0 "how much time the flag takes to automatically return to base if it falls into lava/slime/trigger hurt"
@@ -366,7 +367,7 @@ set g_freezetag_revive_clearspeed 1.6 "Speed at which reviving progress gets los
 set g_freezetag_revive_extra_size 100 "Distance in qu that you can stand from a frozen teammate to keep reviving him"
 set g_freezetag_revive_nade 1 "Enable reviving from own nade explosion"
 set g_freezetag_revive_nade_health 40 "Amount of health player has if they revived from their own nade explosion"
-set g_freezetag_round_timelimit 180 "round time limit in seconds"
+set g_freezetag_round_timelimit 360 "round time limit in seconds"
 set g_freezetag_frozen_maxtime 60 "frozen players will be automatically unfrozen after this time in seconds"
 set g_freezetag_teams_override 0
 set g_freezetag_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any"
@@ -378,8 +379,8 @@ set g_freezetag_weaponarena "most_available" "starting weapons - takes the same
 //  keepaway
 // ==========
 set g_keepaway 0 "game mode which focuses around a ball"
-set g_keepaway_score_bckill 1 "enable scoring points (y/n) for ball carrier kills (value is how many points to award)"
-set g_keepaway_score_killac 1 "amount of points to give when you kill someone while you have the ball"
+set g_keepaway_score_bckill 1 "points for killing the ball barrier (Ball Carrier Kill)"
+set g_keepaway_score_killac 1 "points for kills while holding the ball (Kill As Carrier)"
 set g_keepaway_score_timeinterval 1 "amount of time it takes between intervals for timepoints to be added to the score"
 set g_keepaway_score_timepoints 0 "points to add to score per timeinterval, 0 for no points"
 set g_keepaway_ballcarrier_effects 8 "Add together the numbers you want: EF_ADDITIVE (32) / EF_NODEPTHTEST (8192) / EF_DIMLIGHT (8)"
index 1bd9e272e2ac44035cc4ade47110cf45495bcd0d..b391d0c8bd248d7858040728b373405ff74c0221 100644 (file)
@@ -1,38 +1,38 @@
 set help_msg_0 "Big Admin is watching you, so please be friendly or feel their almighty ban-hammer!"
-set help_msg_1 "If you want to learn more about Xonotic, read ^1'Halogene's Newbie Corner' (https://xonotic.org/guide) ${help_cfg_prefix}as it contains lots of useful tips and tricks, explains all the weapons and helps to improve your gameplay."
+set help_msg_1 "If you want to become better at Xonotic, read ^1'Halogene's Newbie Corner' (https://xonotic.org/guide) ${help_cfg_prefix}as it explains movement and all the weapons in detail."
 set help_msg_2 "Please watch out for balanced teams and change by pressing F5 (teammenu) or F6 (auto join 'best' team)."
-set help_msg_3 "When trying to bunny-hop you can ^1hold the jump button ${help_cfg_prefix}while you are still in the air, this will make those jumps VERY easy to time and work more reliable."
+set help_msg_3 "When trying to bunny-hop you can simply ^1keep holding the jump button${help_cfg_prefix}. Pressing and releasing it for every jump works but often makes players lose some speed. Holding it also works on stairs."
 set help_msg_4 "When a vote is called you can accept it via F1 or reject it via F2 (default keys)."
-set help_msg_5 "Spectating other (good) players helps to learn new tricks. To spectate press F3 and then Mouse1 to switch between the players you want to spectate. F5, F6 or jump will get you back into the game (default keys)."
-set help_msg_6 "Being a beginner is great! You can learn so many new tricks and improve quickly. Watch others, ask for advice and use your common sense effectively."
+set help_msg_5 "Spectating other (good) players helps to learn new tricks. To spectate press F3 and then Mouse1 to switch between the players you want to spectate."
+set help_msg_6 "Notice what other players do differently. Often winning or losing comes down to more than accuracy and evading the other player's shots. Movement, map knowledge and items are equally important."
 set help_msg_7 "If others are better than you, it does not mean they cheat. Save such complaints for when you have more experience and know what kind of funky stuff is possible."
-set help_msg_8 "In CTF, it's good to move around and get involved in the action. You get fragged quite a bit but you are also most helpful to your team."
-set help_msg_9 "Use the radar to see where your teammates are. Pressing zoom will expand the radar image to give you a better overview."
-set help_msg_10 "Most teammessages display waypoints by default. Use those to guide your teammates. You can also see them and the flagcarrier in the radar."
-set help_msg_11 "Protect your flagcarrier at all cost! Also save health and armor for him, he might need them more than you!"
-set help_msg_12 "You can use the Blaster and most explosive weapons to jump around. Just look 'at your feet' and press fire. If you also jump at the same time, you get even higher."
+set help_msg_8 "Listen and remember that the enemy is listening too. Footsteps and item pickups make sounds that can give away your position."
+set help_msg_9 "Use the radar to see where your teammates are. Try to time returning your flag with your FC (flag carrier) arriving at your base so enemies can't steal it again before the FC caps."
+set help_msg_10 "Xonotic provides a wide array of gamemodes, each rewarding their own unique skills that will help you become the best player you can be. Variety is key, try them all!"
+set help_msg_11 "Protect your FC (flag carrier) at all costs! Save health and armor for them, they need it more than you!"
+set help_msg_12 "Use the Blaster to make very high jumps. Just look 'at your feet' and press fire. Other explosive weapons work too but do a lot more damage."
 set help_msg_13 "Be friendly and helpful to other players! Being angry at others' mistakes is understandable, but nobody is perfect. Try to use calm words when telling them how to correct their mistake."
-set help_msg_14 "You can use the zoom key with all guns, only the Vortex has it as a extra function on Mouse2 (default key)."
-set help_msg_15 "Notice what is happening around you! If your base is empty in CTF, then STAY and defend the flag! Make sure someone defends the flagcarrier or assist him yourself."
+set help_msg_14 "You can use the zoom key with all guns, only the Vortex has it as an extra function on secondary fire."
+set help_msg_15 "Notice what is happening around you! If your base is empty in CTF, then STAY and defend the flag!"
 set help_msg_16 "You can drop the weapon you currently have with Backspace (default key). You can help your unarmed teammates this way."
-set help_msg_17 "Learn to use the team messages! You find them in the Setting/Input menu. Try changing them to keys you can press easier than the defaults."
+set help_msg_17 "When you see the enemy FC, use your 'flag seen' bind to point teammates at them. You can even use the bind after death."
 set help_msg_18 "Gaming should be fun! Try to have a nice time, be helpful, mindful and treat others like you want to be treated."
 set help_msg_19 "Visit the official forum on ^1https://forums.xonotic.org/ ${help_cfg_prefix}and feel free to open a thread if you have questions."
 set help_msg_20 "If you already have a good weapon, it's a great idea to let your teammates get something better than the Shotgun too!"
 set help_msg_21 "Press T to chat with others, press Y for messages to your team only, press TAB to see the scores and U for the chat history (default keys)."
-set help_msg_22 "You can use ^1'suggestmap PART_OF_NAME' ${help_cfg_prefix}to make a map come up at the vote screen after a map was played."
+set help_msg_22 "You can use ^1'suggestmap PART_OF_NAME' ${help_cfg_prefix}to make a map come up at the vote screen after the match."
 set help_msg_23 "The console is accessible through the ~ key or by pressing Shift+ESC. It has many more advanced features, use 'cmdlist' and 'cvarlist' to get a full list of available commands/settings."
-set help_msg_24 "The Blaster is a useful tool for gaining speed and jumping around, but it does little damage."
-set help_msg_25 "The Shotgun's primary firemode has spread and is more useful at a closer distance, use secondary for the melee attack and slap into other players faces!"
-set help_msg_26 "The Machine Gun secondary has a burst fire mode and less spread than the primary mode."
-set help_msg_27 "The Mortar is a good all around gun but takes some practice to aim it, because of the projectile's curve."
+set help_msg_24 "The Blaster is a movement tool more than a weapon. Use it to accelerate by blastering walls - bunny-hop along a wall and shoot it to make the explosion push you."
+set help_msg_25 "The Shotgun's primary is useful at a closer distance, use secondary for the melee attack which is surprisingly strong and has longer reach than you might expect."
+set help_msg_26 "The MachineGun's ^1secondary ${help_cfg_prefix}burst firemode has no spread, use it as a cheap Vortex substitute at long range."
+set help_msg_27 "The Mortar's secondary fire bounces before exploding - useful for hitting enemies around corners and behind obstacles"
 set help_msg_28 "The Electro has a combo attack. Fire the primary mode at the balls from the secondary mode for a huge and powerful explosion."
-set help_msg_29 "The Crylink's primary fire bounces. Both firemodes pull your enemies, making it a great tool to stop a flag carrier."
-set help_msg_30 "The Vortex is a powerful sniper gun. Aim carefully!"
-set help_msg_31 "The Hagar is underestimated, but very powerful if you aim right. The secondary mode charges up to four rockets and causes devasting damage if you release them."
-set help_msg_32 "The Devastator is powerful but slow. Keep Mouse1 pressed to guide the rockets. Secondary firemode makes the rocket(s) explode."
-set help_msg_33 "The Arc is a strong lighting beam, which bends slighty if you move your mouse. The secondary firemode is very strong but short. Both firemodes also heal teammates if you shoot at them."
-set help_msg_34 "By default, explosions go through walls. Be careful when hiding behind walls!"
+set help_msg_29 "The Crylink's primary fire bounces. Both firemodes pull your enemies, making it a great tool for stopping enemy FCs (flag carriers)."
+set help_msg_30 "The Vortex is one of the most powerful weapons in Xonotic. It has barely any competition at long range and can serve as a great combo weapon at mid and short range. Put some effort into mastering it, it'll pay off."
+set help_msg_31 "The Hagar is a powerful weapon in enclosed spaces, to use it effectively aim at the enemy's feet."
+set help_msg_32 "Guide your Devastator rockets by holding primary fire and turning or moving. Secondary fire makes the rocket(s) explode."
+set help_msg_33 "The Arc is a strong lightning beam, which bends slighty if you move your mouse. The secondary firemode is very strong but short. Both firemodes also heal teammates if you shoot at them."
+set help_msg_34 "By default, explosions go through walls and floors. Be careful where you hide!"
 set help_msg_35 "Get on IRC to chat with fellow players. Take a look at ^1https://xonotic.org/chat/${help_cfg_prefix}."
 set help_msg_36 "Don't drink and frag."
 set help_msg_37 "Don't shoot at players who are typing/chatting. You recognize those players by the keyboard symbols above their head."
@@ -40,21 +40,33 @@ set help_msg_38 "'gg' is shorthand for 'Good Game', 'gl' means 'Good luck' and '
 set help_msg_39 "Players with the prefix '$bot_prefix${help_cfg_prefix}' in their nick are bots on this server. There is also a clan named [BOT]."
 set help_msg_40 "You spawn with ^1two ${help_cfg_prefix}weapons. Use the Blaster for much faster movement."
 set help_msg_41 "Visit the stats page at ^1https://stats.xonotic.org/ ${help_cfg_prefix}and check out how you are doing in the rankings!"
-set help_msg_42 "Start playing 1on1 if you want to learn fast"
+set help_msg_42 "Play with fewer players if you want to improve faster. Overcrowded DM has too much randomness so you get too little feedback if you're doing things right or wrong."
 set help_msg_43 "Visit ^1https://xonotic.org/pickup/ ${help_cfg_prefix}to get in touch with the experienced players, ask them stuff and play with them!"
 set help_msg_44 "Look for servers that have a good ping for you. You can't play this game well with a ping > 100. If there are no servers close enough to you, cooperate with your friends to setup one."
 set help_msg_45 "If you want to play the next map you can cast a vote via 'vcall endmatch' in the console. Other players can vote using F1 and F2 (default keys)."
 set help_msg_46 "Always watch your back. Do not just run away, fight back as you retreat. Otherwise, you could be shot in the back."
-set help_msg_47 "Try to get as much armor and health as you can, but remember your teammates need armor and health too."
-set help_msg_48 "Do not attack if you have neither a good weapon, nor health, nor armor."
-set help_msg_49 "Standing still makes you an easy target. You can move around the map faster by bunny hopping."
-set help_msg_50 "You can use the Blaster to climb up walls. Before trying this, become familiar with the basics of Blaster movement."
-set help_msg_51 "You can control your movement in air. Use it to prevent yourself from falling off the map when somebody starts pushing you around."
-set help_msg_52 "Use the Blaster, Mortar or Devastator in space maps to push other players off the map. They will enjoy it."
-set help_msg_53 "You can turn off automatic weapon changing in the Player menu. If you configure your key bindings, manually switching weapons can be faster and easier."
+set help_msg_47 "Get as much armor and health as you can, but remember your teammates need them too."
+set help_msg_48 "In some modes like TDM (Team Deathmatch), getting killed means the enemy gets a point. You should not only focus on getting frags but also on not dying."
+set help_msg_49 "Standing still makes you an easy target. You can move around the map faster by bunny-hopping."
+set help_msg_50 "You can use the Blaster to climb up walls. Have enough health, walk up to a wall and keep shooting downwards at a 45° angle while holding forward (to stay near the wall)."
+set help_msg_51 "You can control your movement in the air. Use it to prevent yourself from falling off the map when somebody starts pushing you around."
+set help_msg_52 "Use the Blaster, Vortex or Devastator on space maps to push other players off the map. They will enjoy it."
+set help_msg_53 "You can turn off automatic weapon changing in the Settings->Game->Weapons menu. If you configure your key bindings, manually switching weapons can be faster and easier."
 set help_msg_54 "Choose the right weapon for the job, not just the one that the game automatically puts in your hand."
 set help_msg_55 "Enter ^1'lsmaps' ${help_cfg_prefix}in the console to get a list of maps configured on the server."
-set help_msg_56 "While you are in the air, release the forward key, press one of the left/right keys and move your mouse in the same direction. This will bend your fly/jump path."
-set help_msg_57 "Hold the jump key to keep on jumping (called ^1'bunny-hopping'${help_cfg_prefix}) which will accelerate your speed."
+set help_msg_56 "While you are bunny-hopping, release forward, press left/right and move your mouse in the same direction to turn much faster than just with mouse and forward."
+set help_msg_57 "You can keep accelerating while in the air, that's why ^1'bunny-hopping'${help_cfg_prefix} can be several times faster than running."
 set help_msg_58 "'xonotic.org/guide changed my life' -- ^x777S^x090Є^x088Є^x000Қ^x900⁻ʸ${help_cfg_prefix}, 2018"
-set help_msg_count 59 // update this when adding messages - it should be the number of messages (which means last message index + 1)
+set help_msg_59 "Always remember to mind your surroundings. You should pick up items ^1while ${help_cfg_prefix}fighting too."
+set help_msg_60 "The Crylink's primary fire's projectiles expand as long as you hold the button, then converge quickly. Time it right so they all hit the enemy."
+set help_msg_61 "The Crylink's secondary mode does little damage but provides strong pull, use it to accelerate together with bunny-hopping."
+set help_msg_62 "You can switch weapons faster than some weapons can shoot. Increase your DPS (damage per second) by switching after every shot. This is called comboing."
+set help_msg_63 "The most common weapons to combo are Mortar, Vortex and Devastator. Bind them close to your movement keys or change the weapon order to make comboing possible."
+set help_msg_64 "You can blaster-jump higher if you're moving fast. Combining it with a regular jump also gets you a bit more height."
+set help_msg_65 "Xonotic is an arena shooter (aFPS) which means it focuses on fast movement and item control (in addition to positioning and aim) more than tactical shooters (tFPSes) do."
+set help_msg_66 "Try to always move with a purpose, usually that is getting more health/armor or a new weapon."
+set help_msg_67 "Clan Arena gives you all weapons, full health/armor and has no selfdamage. It's the ideal mode to learn movement using weapons."
+set help_msg_68 "The Hagar's secondary mode charges up to four rockets, each does more damage than primary. Cancel the charge by pressing primary fire."
+set help_msg_69 "In addition to gamemodes, Xonotic offers multiple rulesets. The default is known as vanilla or simply Xonotic. Xonotic ProMode (XPM) focuses on more competitive play. Other popular rulesets are Instagib, Overkill and Xonotic DeFrag (XDF)."
+set help_msg_70 "You cannot hurt teammates in vanilla Xonotic (as opposed to XPM) but you can push them, so try to avoid hitting them unnecessarily."
+set help_msg_count 71 // update this when adding messages - it should be the number of messages (which means last message index + 1)
index 52cfb09f3377f8cadb963e0577b1b542b7915e20..70b7c8a0f8242dd1391f62421dba748b8d022796 100644 (file)
--- a/help.cfg
+++ b/help.cfg
@@ -1,5 +1,6 @@
 // Simple help message system
-// It prints messages with the configured name
+
+// First exec this file, then the correct help-*.cfg for your ruleset.
 
 // You can start the help system with the command help_loop but this has been found to annoy players.
 // A better way is to put `alias sv_hook_gamestart_all "defer 20 help_next"` into your server.cfg,
index 813ecbaef0df64396789d8115bce2c758deaec4d..d8151425127d8fc80f1cd3e9d7c2250c229e06ad 100644 (file)
@@ -64,6 +64,7 @@ seta hud_panel_weapons_timeout_fadefgmin "0.4"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "1"
+seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "0.8"
 seta hud_panel_weapons_noncurrent_scale "0.9"
 seta hud_panel_weapons_selection_radius "0"
index c5cfe4ac548fdc62e070ac1cda9ed08d4a9c3524..8766bcb24835825fed6417263ba6b169455a38b4 100644 (file)
@@ -64,6 +64,7 @@ seta hud_panel_weapons_timeout_fadefgmin "0.4"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "1"
+seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "1"
 seta hud_panel_weapons_noncurrent_scale "1"
 seta hud_panel_weapons_selection_radius "0"
index b7282584637aba28087bec61f8c071f5ac97df68..02940f8d3ab5b8c1e81e61bc00c4b57381839652 100644 (file)
@@ -64,6 +64,7 @@ seta hud_panel_weapons_timeout_fadefgmin "0"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "1"
+seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "1"
 seta hud_panel_weapons_noncurrent_scale "1"
 seta hud_panel_weapons_selection_radius "0"
index 3bfd694b19cf2f0977c36c437ed7ee5c8220d5f9..41a47d7ab2d77cd1e6cc4d486eb5a0bf924b37f8 100644 (file)
@@ -64,6 +64,7 @@ seta hud_panel_weapons_timeout_fadefgmin "0"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "1"
+seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "1"
 seta hud_panel_weapons_noncurrent_scale "1"
 seta hud_panel_weapons_selection_radius "0"
index c808f62fb5b10ca9f430153f3260821fc0280ff9..f4a5e0441b97f3b5c7c5940330cc2585a9afde01 100644 (file)
@@ -64,6 +64,7 @@ seta hud_panel_weapons_timeout_fadefgmin "0"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "1"
+seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "1"
 seta hud_panel_weapons_noncurrent_scale "1"
 seta hud_panel_weapons_selection_radius "0"
index b0b02d080c6e6517407ca8706a8315bca9160f46..ea5dc69a240f1fee326c3fd58e07b94fc6add213 100644 (file)
@@ -64,6 +64,7 @@ seta hud_panel_weapons_timeout_fadefgmin "0"
 seta hud_panel_weapons_timeout_speed_in "0.25"
 seta hud_panel_weapons_timeout_speed_out "0.75"
 seta hud_panel_weapons_onlyowned "0"
+seta hud_panel_weapons_orderbyimpulse "1"
 seta hud_panel_weapons_noncurrent_alpha "1"
 seta hud_panel_weapons_noncurrent_scale "1"
 seta hud_panel_weapons_selection_radius "0"
index 3c1614dcd3b1943061a3c35ca3489127fdb7f2e1..ca688cd695136b13fb078f1d49325690ded5c2b9 100644 (file)
@@ -32,6 +32,7 @@ sv_warsowbunny_accel 0.1593
 sv_warsowbunny_topspeed 925
 sv_warsowbunny_backtosideratio 0.8
 sv_friction_on_land 0
+sv_friction_slick 0
 sv_doublejump 0
 sv_jumpspeedcap_min ""
 sv_jumpspeedcap_max ""
index f45a81b7739fb4f55ed8dd63d5504b01c2a6a236..4507cc8c86be91d5301ddf55d058135cfc3da87b 100644 (file)
@@ -32,6 +32,7 @@ sv_warsowbunny_accel 0.1593
 sv_warsowbunny_topspeed 925
 sv_warsowbunny_backtosideratio 0.8
 sv_friction_on_land 0
+sv_friction_slick 0
 sv_doublejump 1
 sv_jumpspeedcap_min ""
 sv_jumpspeedcap_max ""
index 585262a2ed0080811a1be8d47ac7fa926de4c1b9..a515e9be773b5c6d8d21a2cc2a176c1a4c7688dc 100644 (file)
@@ -33,6 +33,7 @@ sv_warsowbunny_accel 0.1593
 sv_warsowbunny_topspeed 925
 sv_warsowbunny_backtosideratio 0.8
 sv_friction_on_land 0
+sv_friction_slick 0
 sv_doublejump 1
 sv_jumpspeedcap_min ""
 sv_jumpspeedcap_max ""
index 3ce18b52a98bef30d6c6f32da3ba0fa0a2a22f5d..7b650da38e315d166977fc888f52a2937a1d7367 100644 (file)
@@ -32,6 +32,7 @@ sv_warsowbunny_accel 0.1593
 sv_warsowbunny_topspeed 925
 sv_warsowbunny_backtosideratio 0.8
 sv_friction_on_land 0
+sv_friction_slick 0
 sv_doublejump 0
 sv_jumpspeedcap_min ""
 sv_jumpspeedcap_max ""
index de7352aab54e56de9803d38cdec59a0298038583..c59b8e99e6e4dfc7a7c32fa850a9961368b7d3ff 100644 (file)
@@ -32,6 +32,7 @@ sv_warsowbunny_accel 0.1593
 sv_warsowbunny_topspeed 925
 sv_warsowbunny_backtosideratio 0.8
 sv_friction_on_land 0
+sv_friction_slick 0
 sv_doublejump 0
 sv_jumpspeedcap_min ""
 sv_jumpspeedcap_max ""
index 7705a4d512d70856f008aa0d2c1148d282581525..05ece9bea6e97d557c8917a05d793aefe939c811 100644 (file)
@@ -32,6 +32,7 @@ sv_warsowbunny_accel 0.1593
 sv_warsowbunny_topspeed 925
 sv_warsowbunny_backtosideratio 0.8
 sv_friction_on_land 0
+sv_friction_slick 0
 sv_doublejump 0
 sv_jumpspeedcap_min ""
 sv_jumpspeedcap_max ""
index 9009beab33a14e949a7f0d575d67dc7673617387..4a272261fe173802e4880874a24975a214475208 100644 (file)
@@ -32,6 +32,7 @@ sv_warsowbunny_accel 0.1585
 sv_warsowbunny_topspeed 900
 sv_warsowbunny_backtosideratio 0.9
 sv_friction_on_land 0
+sv_friction_slick 0
 sv_doublejump 0
 sv_jumpspeedcap_min ""
 sv_jumpspeedcap_max ""
index d31d12205cfa88357521cc5f6baa8baf3717cdfa..d11355659aa8071a5795e030b555a01361aeeb8b 100644 (file)
@@ -351,6 +351,7 @@ float autocvar_hud_panel_weapons_selection_radius = 0;
 float autocvar_hud_panel_weapons_selection_speed = 10;
 float autocvar_hud_panel_weapons_timeout;
 int autocvar_hud_panel_weapons_timeout_effect;
+bool autocvar_hud_panel_weapons_orderbyimpulse = true;
 float autocvar_hud_panel_weapons_timeout_fadebgmin;
 float autocvar_hud_panel_weapons_timeout_fadefgmin;
 float autocvar_hud_panel_weapons_timeout_speed_in = 0.25;
index a0641955609138a43fc1f396e6c6be54469ee716..1272758f76cee3de642322d9ce6ffb2419660e7a 100644 (file)
@@ -540,8 +540,11 @@ void CSQCModel_Effects_Apply(entity this)
                tref = EFFECT_TR_BLOOD.m_id;
        if(this.csqcmodel_modelflags & MF_ROTATE)
        {
+               // This will be hard to replace with MAKE_VECTORS because it's called as part of the predraw function
+               // as documented in csprogs.h in the engine. The globals can then be read in many places in the engine.
+               // However MF_ROTATE is currently only used in one place - might be possible to get rid of it entirely.
                this.renderflags |= RF_USEAXIS;
-               MAKEVECTORS(makevectors, this.angles + '0 100 0' * fmod(time, 3.6), v_forward, v_right, v_up);
+               makevectors(this.angles + '0 100 0' * fmod(time, 3.6));
        }
        if(this.csqcmodel_modelflags & MF_TRACER)
                tref = EFFECT_TR_WIZSPIKE.m_id;
index 5ce4c3e60c3990a1f1492789ca47dee55cdc9bc6..db1a5afacaed87760c210bde6088c475c7dab29c 100644 (file)
@@ -173,8 +173,9 @@ REPLICATE(cvar_cl_weaponpriorities[9], string, "cl_weaponpriority9");
 
 float bgmtime;
 
-string weaponorder_byimpulse;
+string weaponorder_byimpulse; // NOTE: this is a misnomer, weapon order is not always sorted by impulse
 string weaponorder_bypriority;
+bool weapons_orderbyimpulse; // update priority list when toggling this
 
 float vortex_charge_movingavg;
 
index 3043e6e6860d90a0673829688f681eff6fb44e0d..a6c22c74eee9bf113f4d71570b90ec57f7a33938 100644 (file)
@@ -97,6 +97,7 @@ void HUD_Panel_ExportCfg(string cfgname)
                                        HUD_Write_Cvar("hud_panel_weapons_timeout_speed_in");
                                        HUD_Write_Cvar("hud_panel_weapons_timeout_speed_out");
                                        HUD_Write_Cvar("hud_panel_weapons_onlyowned");
+                                       HUD_Write_Cvar("hud_panel_weapons_orderbyimpulse");
                                        HUD_Write_Cvar("hud_panel_weapons_noncurrent_alpha");
                                        HUD_Write_Cvar("hud_panel_weapons_noncurrent_scale");
                                        HUD_Write_Cvar("hud_panel_weapons_selection_radius");
index bd9aa1a21ca53afe3837d12bdf1fef3771ac4940..95ceced82c74d7ca6a39adc2084de9e950c85a2c 100644 (file)
@@ -177,7 +177,7 @@ void HUD_Ammo()
 
        Weapon wep = wepent.switchweapon;
        int i;
-       bool infinite_ammo = (STAT(ITEMS) & IT_UNLIMITED_WEAPON_AMMO);
+       bool infinite_ammo = (STAT(ITEMS) & IT_UNLIMITED_AMMO);
        row = column = 0;
        if(autocvar_hud_panel_ammo_onlycurrent)
        {
index ac32e23cb9373195df72860661d9dcce8f2d3f7b..832ffad0b38ca9b27727451808c44570e5d5eb79 100644 (file)
@@ -63,7 +63,7 @@ void HUD_Weapons()
        float when = max(1, autocvar_hud_panel_weapons_complainbubble_time);
        float fadetime = max(0, autocvar_hud_panel_weapons_complainbubble_fadetime);
 
-       bool infinite_ammo = (STAT(ITEMS) & IT_UNLIMITED_WEAPON_AMMO);
+       bool infinite_ammo = (STAT(ITEMS) & IT_UNLIMITED_AMMO);
 
        vector weapon_pos, weapon_size = '0 0 0';
        vector color;
@@ -91,11 +91,15 @@ void HUD_Weapons()
        HUD_Panel_LoadCvars();
 
        // figure out weapon order (how the weapons are sorted) // TODO make this configurable
-       if(weaponorder_bypriority != autocvar_cl_weaponpriority || !weaponorder[0])
+       if(weaponorder_bypriority != autocvar_cl_weaponpriority || autocvar_hud_panel_weapons_orderbyimpulse != weapons_orderbyimpulse || !weaponorder[0])
        {
                int weapon_cnt;
+               weapons_orderbyimpulse = autocvar_hud_panel_weapons_orderbyimpulse;
                strcpy(weaponorder_bypriority, autocvar_cl_weaponpriority);
-               strcpy(weaponorder_byimpulse, W_FixWeaponOrder_BuildImpulseList(W_FixWeaponOrder_ForceComplete(W_NumberWeaponOrder(weaponorder_bypriority))));
+               string weporder = W_FixWeaponOrder_ForceComplete(W_NumberWeaponOrder(weaponorder_bypriority));
+               if(autocvar_hud_panel_weapons_orderbyimpulse)
+                       weporder = W_FixWeaponOrder_BuildImpulseList(weporder);
+               strcpy(weaponorder_byimpulse, weporder);
                weaponorder_cmp_str = strcat(" ", weaponorder_byimpulse, " ");
 
                weapon_cnt = 0;
index 26de41e7245aaf2e323287d065eb90ec5c81f50e..c565651d4a3a0b49daee81ae6a76649b60889d66 100644 (file)
@@ -93,8 +93,8 @@ void draw_teamradar_player(vector coord3d, vector pangles, vector rgb)
 
        coord = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(coord3d));
 
-       vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
-       MAKEVECTORS(makevectors, pangles - '0 1 0' * teamradar_angle, forward, right, up);
+       vector forward, right, up;
+       MAKE_VECTORS(pangles - '0 1 0' * teamradar_angle, forward, right, up);
        if(v_flipped)
        {
                forward.x = -forward.x;
index 8eae26935b2c88eef07eb636a0af62da1bb79a3d..7a62d4ef3f5c5ad3fede9de457b260097bde18e9 100644 (file)
@@ -133,8 +133,8 @@ void calc_followmodel_ofs(entity view)
                vel = view.velocity;
        else
        {
-               vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
-               MAKEVECTORS(makevectors, view_angles, forward, right, up);
+               vector forward, right, up;
+               MAKE_VECTORS(view_angles, forward, right, up);
                vel.x = view.velocity * forward;
                vel.y = view.velocity * right * -1;
                vel.z = view.velocity * up;
@@ -159,8 +159,8 @@ void calc_followmodel_ofs(entity view)
        if (autocvar_cl_followmodel_velocity_absolute)
        {
                vector fixed_gunorg;
-               vector forward = '0 0 0', right = '0 0 0', up = '0 0 0';
-               MAKEVECTORS(makevectors, view_angles, forward, right, up);
+               vector forward, right, up;
+               MAKE_VECTORS(view_angles, forward, right, up);
                fixed_gunorg.x = gunorg * forward;
                fixed_gunorg.y = gunorg * right * -1;
                fixed_gunorg.z = gunorg * up;
@@ -492,15 +492,16 @@ vector GetCurrentFov(float fov)
                        curspeed = 0;
                else
                {
-                       makevectors(view_angles);
+                       vector forward, right, up;
+                       MAKE_VECTORS(view_angles, forward, right, up);
                        v = pmove_vel;
                        if(csqcplayer)
                                v = csqcplayer.velocity;
 
                        switch(autocvar_cl_velocityzoom_type)
                        {
-                               case 3: curspeed = max(0, v_forward * v); break;
-                               case 2: curspeed = (v_forward * v); break;
+                               case 3: curspeed = max(0, forward * v); break;
+                               case 2: curspeed = (forward * v); break;
                                case 1: default: curspeed = vlen(v); break;
                        }
                }
@@ -1093,8 +1094,10 @@ void HUD_Crosshair(entity this)
                        wcross_color.z += sin(hitindication_crosshair_size) * hitindication_color.z;
                }
 
-               if(shottype == SHOTTYPE_HITENEMY)
-                       wcross_scale *= autocvar_crosshair_hittest; // is not queried if hittest is 0
+               // no effects needed for targeting enemies, this can't possibly span all valid targets!
+               // just show for teammates to give a sign that they're an invalid target
+               //if(shottype == SHOTTYPE_HITENEMY)
+                       //wcross_scale *= autocvar_crosshair_hittest; // is not queried if hittest is 0
                if(shottype == SHOTTYPE_HITTEAM)
                        wcross_scale /= autocvar_crosshair_hittest; // is not queried if hittest is 0
 
@@ -1751,18 +1754,19 @@ void CSQC_UpdateView(entity this, float w, float h)
                        else if(eventchase_current_distance != chase_distance)
                                eventchase_current_distance = chase_distance;
 
-                       makevectors(view_angles);
+                       vector forward, right, up;
+                       MAKE_VECTORS(view_angles, forward, right, up);
 
-                       vector eventchase_target_origin = (current_view_origin - (v_forward * eventchase_current_distance));
+                       vector eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance));
                        WarpZone_TraceBox(current_view_origin, autocvar_cl_eventchase_mins, autocvar_cl_eventchase_maxs, eventchase_target_origin, MOVE_WORLDONLY, this);
 
                        // If the boxtrace fails, revert back to line tracing.
                        if(!local_player.viewloc)
                        if(trace_startsolid)
                        {
-                               eventchase_target_origin = (current_view_origin - (v_forward * eventchase_current_distance));
+                               eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance));
                                WarpZone_TraceLine(current_view_origin, eventchase_target_origin, MOVE_WORLDONLY, this);
-                               setproperty(VF_ORIGIN, (trace_endpos - (v_forward * autocvar_cl_eventchase_mins.z)));
+                               setproperty(VF_ORIGIN, (trace_endpos - (forward * autocvar_cl_eventchase_mins.z)));
                        }
                        else { setproperty(VF_ORIGIN, trace_endpos); }
 
@@ -1889,7 +1893,7 @@ void CSQC_UpdateView(entity this, float w, float h)
        // Render the Scene
        view_origin = getpropertyvec(VF_ORIGIN);
        view_angles = getpropertyvec(VF_ANGLES);
-       MAKEVECTORS(makevectors, view_angles, view_forward, view_right, view_up);
+       MAKE_VECTORS(view_angles, view_forward, view_right, view_up);
 
 #ifdef BLURTEST
        if(time > blurtest_time0 && time < blurtest_time1)
@@ -2440,14 +2444,15 @@ void CSQC_UpdateView(entity this, float w, float h)
                setproperty(VF_ORIGIN, '0 0 0');
                setproperty(VF_ANGLES, '0 0 0');
                setproperty(VF_PERSPECTIVE, 1);
-               makevectors('0 0 0');
+               vector forward, right, up;
+               MAKE_VECTORS('0 0 0', forward, right, up);
                vector v1, v2;
                cvar_set("vid_conwidth", "800");
                cvar_set("vid_conheight", "600");
-               v1 = cs_project(v_forward);
+               v1 = cs_project(forward);
                cvar_set("vid_conwidth", "640");
                cvar_set("vid_conheight", "480");
-               v2 = cs_project(v_forward);
+               v2 = cs_project(forward);
                if(v1 == v2)
                        cs_project_is_b0rked = 1;
                else
index 55b634a624ce91619b15054f7325ca5cbe071cd7..05064ca96742c395ab0beb863f6bffb186549867 100644 (file)
@@ -295,7 +295,7 @@ MUTATOR_HOOKFUNCTION(trace, SV_StartFrame)
                        it.solid = SOLID_BBOX;
                });
                vector forward = '0 0 0'; vector right = '0 0 0'; vector up = '0 0 0';
-               MAKEVECTORS(makevectors, it.v_angle, forward, right, up);
+               MAKE_VECTORS(it.v_angle, forward, right, up);
                vector pos = it.origin + it.view_ofs;
                traceline(pos, pos + forward * max_shot_distance, MOVE_NORMAL, it);
                FOREACH_ENTITY(true, {
index 4721cb38015ea7cb4ea306accd3f3389eaa14d14..408a14e0d87fbac00a3dfcc11bd6292997149fe3 100644 (file)
@@ -333,7 +333,7 @@ MUTATOR_HOOKFUNCTION(ca, GiveFragsForKill, CBC_ORDER_FIRST)
 
 MUTATOR_HOOKFUNCTION(ca, SetStartItems)
 {
-       start_items       &= ~IT_UNLIMITED_AMMO;
+       start_items       &= ~(IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS);
        start_health       = warmup_start_health       = cvar("g_lms_start_health");
        start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
        start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
index b1feaa9917c2cb913ce91f9465f795d6f40305ab..54f6268e36da53d537e2effef2c5c72c62afadbf 100644 (file)
@@ -549,7 +549,7 @@ MUTATOR_HOOKFUNCTION(ft, PlayerPreThink, CBC_ORDER_FIRST)
 
 MUTATOR_HOOKFUNCTION(ft, SetStartItems)
 {
-       start_items &= ~IT_UNLIMITED_AMMO;
+       start_items &= ~(IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS);
        //start_health       = warmup_start_health       = cvar("g_lms_start_health");
        //start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
        start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
index bd6401d172931ea66eb07776258bc26258e8c1ca..aceb66e0310db714e640c16250b7bcd8d4a547c5 100644 (file)
@@ -323,7 +323,7 @@ MUTATOR_HOOKFUNCTION(lms, GiveFragsForKill)
 
 MUTATOR_HOOKFUNCTION(lms, SetStartItems)
 {
-       start_items &= ~IT_UNLIMITED_AMMO;
+       start_items &= ~(IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS);
        start_health       = warmup_start_health       = cvar("g_lms_start_health");
        start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
        start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
index cf4e288ba6cd1769c127ef9ca27ab16ca8411579..8ba0096713342a7c7a5364b95ffe8fb58674c2e2 100644 (file)
@@ -11,7 +11,7 @@
 #include <server/items.qh>
 #endif
 
-const int IT_UNLIMITED_WEAPON_AMMO             =  BIT(0); // when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup.
+const int IT_UNLIMITED_AMMO                    =  BIT(0); // when this bit is set, using a weapon does not reduce ammo. Checkpoints can give this powerup.
 const int IT_UNLIMITED_SUPERWEAPONS            =  BIT(1); // when this bit is set, superweapons don't expire. Checkpoints can give this powerup.
 
 const int IT_JETPACK                           =  BIT(2); // actual item
@@ -44,8 +44,7 @@ const int IT_SUPERWEAPON                              = BIT(21); // suit
 const int IT_STRENGTH                                  = BIT(22);
 
 // item masks
-const int IT_UNLIMITED_AMMO                    = IT_UNLIMITED_WEAPON_AMMO | IT_UNLIMITED_SUPERWEAPONS;
-const int IT_PICKUPMASK                        = IT_UNLIMITED_AMMO | IT_JETPACK | IT_FUEL_REGEN; // strength and invincible are handled separately
+const int IT_PICKUPMASK                        = IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS | IT_JETPACK | IT_FUEL_REGEN; // strength and invincible are handled separately
 
 #ifdef SVQC
 const .float strength_finished = _STAT(STRENGTH_FINISHED);
index 617bfe85e2cde2c78d3b0f1c8fd1e617732c34df..3e6478b2db50ca25a54716a137d75ca7ba01e4e6 100644 (file)
@@ -717,9 +717,11 @@ void _MapInfo_Parse_Settemp(string pFilename, string acl, float type, string s,
                if(type == 0) // server set
                {
                        LOG_TRACE("Applying temporary setting ", t, " := ", s);
+               #if 0
                        if(cvar("g_campaign"))
                                cvar_set(t, s); // this is a wrapper and is always temporary anyway; no need to backup old values then
                        else
+               #endif
                                cvar_settemp(t, s);
                }
                else
index 60db1608a31b8eb9c0b728ca65d33ac6cd340831..b669ba1f7b63aa2a8c74ab7bc7e1f91caaed1de3 100644 (file)
@@ -124,7 +124,7 @@ REGISTER_GAMETYPE(DEATHMATCH, NEW(Deathmatch));
 CLASS(LastManStanding, Gametype)
     INIT(LastManStanding)
     {
-        this.gametype_init(this, _("Last Man Standing"),"lms","g_lms",false,true,"","timelimit=20 lives=9 leadlimit=0",_("Survive and kill until the enemies have no lives left"));
+        this.gametype_init(this, _("Last Man Standing"),"lms","g_lms",false,true,"","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))
     {
@@ -302,7 +302,7 @@ void HUD_Mod_CA(vector pos, vector mySize);
 CLASS(ClanArena, Gametype)
     INIT(ClanArena)
     {
-        this.gametype_init(this, _("Clan Arena"),"ca","g_ca",true,true,"","timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill all enemy teammates to win the round"));
+        this.gametype_init(this, _("Clan Arena"),"ca","g_ca",true,true,"","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))
     {
@@ -497,7 +497,7 @@ REGISTER_GAMETYPE(NEXBALL, NEW(NexBall));
 CLASS(FreezeTag, Gametype)
     INIT(FreezeTag)
     {
-        this.gametype_init(this, _("Freeze Tag"),"ft","g_freezetag",true,true,"","timelimit=20 pointlimit=10 teams=2 leadlimit=0",_("Kill enemies to freeze them, stand next to frozen teammates to revive them; freeze all enemies to win"));
+        this.gametype_init(this, _("Freeze Tag"),"ft","g_freezetag",true,true,"","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))
     {
@@ -672,6 +672,8 @@ void MapInfo_Cache_Destroy(); // disable caching
 void MapInfo_Cache_Create(); // enable caching
 void MapInfo_Cache_Invalidate(); // delete cache if any, but keep enabled
 
+void _MapInfo_Parse_Settemp(string pFilename, string acl, float type, string s, float recurse);
+
 void MapInfo_ClearTemps(); // call this when done with mapinfo for this frame
 
 void MapInfo_Shutdown(); // call this in the shutdown handler
index aa5b54a60ed4ba7ce22dbd761d2321610f989392..e9fd04b7263398217e507800c47261f50ab29696 100644 (file)
@@ -670,10 +670,15 @@ void door_init_shared(entity this)
                precache_sound(this.noise2);
        }
 
-       if (!this.wait)
-       {
-               this.wait = 3;
-       }
+        if(autocvar_sv_doors_always_open)
+        {
+                 this.wait = -1;
+        }
+        else if (!this.wait)
+        {
+               this.wait = 3;
+        }
+
        if (!this.lip)
        {
                this.lip = 8;
@@ -726,10 +731,14 @@ spawnfunc(func_door)
        this.pos1 = this.origin;
        this.pos2 = this.pos1 + this.movedir*(fabs(this.movedir*this.size) - this.lip);
 
-       if (!this.speed)
-       {
-               this.speed = 100;
-       }
+        if(autocvar_sv_doors_always_open)
+        {
+                this.speed = max(750, this.speed);
+        }
+        else if (!this.speed)
+        {
+                this.speed = 100;
+        }
 
        settouch(this, door_touch);
 
index 97df48106dcbc935fa4e38c0720f42b8cc3a0854..256af90affb3650cfc444b0e9d33827af1504ab1 100644 (file)
@@ -212,7 +212,7 @@ float buff_Available(entity buff)
 {
        if (buff == BUFF_Null)
                return false;
-       if (buff == BUFF_AMMO && ((start_items & IT_UNLIMITED_WEAPON_AMMO) || (start_items & IT_UNLIMITED_AMMO) || (cvar("g_melee_only"))))
+       if (buff == BUFF_AMMO && ((start_items & IT_UNLIMITED_AMMO) || cvar("g_melee_only")))
                return false;
        if (buff == BUFF_VAMPIRE && cvar("g_vampire"))
                return false;
@@ -576,7 +576,6 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerSpawn)
        entity player = M_ARGV(0, entity);
 
        player.oldbuffs = 0;
-       PS(player).buff_shield = time + 0.5; // prevent picking up buffs immediately
        // reset timers here to prevent them continuing after re-spawn
        player.buff_disability_time = 0;
        player.buff_disability_effect_time = 0;
@@ -918,8 +917,8 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
 
                BUFF_ONADD(BUFF_AMMO)
                {
-                       player.buff_ammo_prev_infitems = (player.items & IT_UNLIMITED_WEAPON_AMMO);
-                       player.items |= IT_UNLIMITED_WEAPON_AMMO;
+                       player.buff_ammo_prev_infitems = (player.items & IT_UNLIMITED_AMMO);
+                       player.items |= IT_UNLIMITED_AMMO;
 
                        if(STAT(BUFFS, player) & BUFF_AMMO.m_itemid)
                        {
@@ -937,9 +936,9 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
                BUFF_ONREM(BUFF_AMMO)
                {
                        if(player.buff_ammo_prev_infitems)
-                               player.items |= IT_UNLIMITED_WEAPON_AMMO;
+                               player.items |= IT_UNLIMITED_AMMO;
                        else
-                               player.items &= ~IT_UNLIMITED_WEAPON_AMMO;
+                               player.items &= ~IT_UNLIMITED_AMMO;
 
                        if(STAT(BUFFS, player) & BUFF_AMMO.m_itemid)
                        {
index 5e59fd9f3274471f866e363894bcb5c510eed6f8..899c6d63c1284fce107e2a348ab482d731d620ab 100644 (file)
@@ -74,9 +74,10 @@ CLASS(DamageText, Object)
         if (this.m_screen_coords) {
             screen_pos = this.origin + since_hit * autocvar_cl_damagetext_2d_velocity;
         } else {
-            makevectors(view_angles);
+            vector forward, right, up;
+            MAKE_VECTORS(view_angles, forward, right, up);
             vector world_offset = since_hit * autocvar_cl_damagetext_velocity_world + autocvar_cl_damagetext_offset_world;
-            vector world_pos = this.origin + world_offset.x * v_forward + world_offset.y * v_right + world_offset.z * v_up;
+            vector world_pos = this.origin + world_offset.x * forward + world_offset.y * right + world_offset.z * up;
             screen_pos = project_3d_to_2d(world_pos) + since_hit * autocvar_cl_damagetext_velocity_screen + autocvar_cl_damagetext_offset_screen;
         }
         screen_pos.y += size / 2;
index c97308d58ab1f8cd8a7db8adcd738c277baa739e..66d18ac671e8ad9c5ce074c8f74eee7e494fb9f5 100644 (file)
@@ -113,20 +113,20 @@ REGISTER_MUTATOR(dodging, true);
                return true;
 
 // returns true if the player is close to a wall
-bool is_close_to_wall(entity this, float threshold)
+bool is_close_to_wall(entity this, float threshold, vector forward, vector right)
 {
-       X(v_right);
-       X(-v_right);
-       X(v_forward);
-       X(-v_forward);
+       X(right);
+       X(-right);
+       X(forward);
+       X(-forward);
 
        return false;
 }
 
-bool is_close_to_ground(entity this, float threshold)
+bool is_close_to_ground(entity this, float threshold, vector up)
 {
        if (IS_ONGROUND(this)) return true;
-       X(-v_up); // necessary for dodging down a slope using doubletap (using `+dodge` works anyway)
+       X(-up); // necessary for dodging down a slope using doubletap (using `+dodge` works anyway)
 
        return false;
 }
@@ -180,10 +180,11 @@ bool PM_dodging_checkpressedkeys(entity this)
        if ((time - this.last_dodging_time) < PHYS_DODGING_DELAY)
                return false;
 
-       makevectors(this.angles);
+       vector forward, right, up;
+       MAKE_VECTORS(this.angles, forward, right, up);
 
-       bool can_dodge = (is_close_to_ground(this, PHYS_DODGING_HEIGHT_THRESHOLD) && (PHYS_DODGING_MAXSPEED == 0 || vdist(this.velocity, <, PHYS_DODGING_MAXSPEED)));
-       bool can_wall_dodge = (PHYS_DODGING_WALL && is_close_to_wall(this, PHYS_DODGING_DISTANCE_THRESHOLD));
+       bool can_dodge = (is_close_to_ground(this, PHYS_DODGING_HEIGHT_THRESHOLD, up) && (PHYS_DODGING_MAXSPEED == 0 || vdist(this.velocity, <, PHYS_DODGING_MAXSPEED)));
+       bool can_wall_dodge = (PHYS_DODGING_WALL && is_close_to_wall(this, PHYS_DODGING_DISTANCE_THRESHOLD, forward, right));
        bool can_air_dodge = (PHYS_DODGING_AIR && (PHYS_DODGING_AIR_MAXSPEED == 0 || vdist(this.velocity, <, PHYS_DODGING_AIR_MAXSPEED)));
        if (!can_dodge && !can_wall_dodge && !can_air_dodge) return false;
 
@@ -221,11 +222,11 @@ void PM_dodging(entity this)
                return;
        }
 
-       // make sure v_up, v_right and v_forward are sane
+       vector forward, right, up;
        if(PHYS_DODGING_AIR)
-               makevectors(this.v_angle);
+               MAKE_VECTORS(this.v_angle, forward, right, up);
        else
-               makevectors(this.angles);
+               MAKE_VECTORS(this.angles, forward, right, up);
 
        // fraction of the force to apply each frame
        // if we have e.g. 0.5 sec ramptime and a frametime of 0.25, then the ramp code
@@ -237,15 +238,15 @@ void PM_dodging(entity this)
 
        float velocity_increase = min(common_factor * this.dodging_force_total, this.dodging_force_remaining);
        this.dodging_force_remaining -= velocity_increase;
-       this.velocity += this.dodging_direction.x * velocity_increase * v_forward
-                      + this.dodging_direction.y * velocity_increase * v_right;
+       this.velocity += this.dodging_direction.x * velocity_increase * forward
+                      + this.dodging_direction.y * velocity_increase * right;
 
        // the up part of the dodge is a single shot action
        if (this.dodging_single_action == 1)
        {
                UNSET_ONGROUND(this);
 
-               this.velocity += PHYS_DODGING_UP_SPEED * v_up;
+               this.velocity += PHYS_DODGING_UP_SPEED * up;
 
 #ifdef SVQC
                if (autocvar_sv_dodging_sound)
index 63f3182ea6ba4746abb57d5491c5c97d29294adc..c4f4b5d00cd861d9c717beb3fcc2edeca2157346 100644 (file)
@@ -82,7 +82,7 @@ void instagib_ammocheck(entity this)
 
        if(IS_DEAD(this) || game_stopped)
                instagib_stop_countdown(this);
-       else if (GetResource(this, RES_CELLS) > 0 || (this.items & IT_UNLIMITED_WEAPON_AMMO) || (this.flags & FL_GODMODE))
+       else if (GetResource(this, RES_CELLS) > 0 || (this.items & IT_UNLIMITED_AMMO) || (this.flags & FL_GODMODE))
                instagib_stop_countdown(this);
        else if(autocvar_g_rm && autocvar_g_rm_laser)
        {
index efe8ee3aedf2449988527ca916cc77bc2055044e..7214a699e1122e759026f2b5995ee4a99305a943 100644 (file)
@@ -140,7 +140,7 @@ void NIX_GiveCurrentWeapon(entity this)
                SetResource(this, RES_CELLS, 0);
                SetResource(this, RES_PLASMA, 0);
                SetResource(this, RES_FUEL, 0);
-               if(this.items & IT_UNLIMITED_WEAPON_AMMO)
+               if(this.items & IT_UNLIMITED_AMMO)
                {
                        switch (wpn.ammo_type)
                        {
@@ -193,7 +193,7 @@ void NIX_GiveCurrentWeapon(entity this)
                        Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_NIX_COUNTDOWN, nix_nextweapon, dt);
        }
 
-       if(!(this.items & IT_UNLIMITED_WEAPON_AMMO) && time > this.nix_nextincr)
+       if(!(this.items & IT_UNLIMITED_AMMO) && time > this.nix_nextincr)
        {
                switch (wpn.ammo_type)
                {
index bee61f2fea54516c00e7be4088be64b09a8fdab4..df55fb88c42a4663b96b9aaa5a6f3b61d908692f 100644 (file)
@@ -18,7 +18,7 @@ void W_OverkillHeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity
                return;
        }
 
-       if((!thiswep.wr_checkammo1(thiswep, actor, weaponentity) && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (!(actor.items & IT_SUPERWEAPON) && !(actor.items & IT_UNLIMITED_SUPERWEAPONS)))
+       if((!thiswep.wr_checkammo1(thiswep, actor, weaponentity) && !(actor.items & IT_UNLIMITED_AMMO)) || (!(actor.items & IT_SUPERWEAPON) && !(actor.items & IT_UNLIMITED_SUPERWEAPONS)))
        {
                W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
                w_ready(thiswep, actor, weaponentity, fire);
index f8dfa89fe5b5748e72bea985b7349315f1c56780..768e364a78535f8274516388f47519ed4294da21 100644 (file)
@@ -13,7 +13,7 @@ void W_OverkillMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weap
        }
 
        if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity))
-       if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+       if(!(actor.items & IT_UNLIMITED_AMMO))
        {
                W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
                w_ready(thiswep, actor, weaponentity, fire);
index cbcc285a54585382d61e0618fa7a2269a8985860..83a3a3cc052c3e9adbaf0143af71242def1946a5 100644 (file)
@@ -221,7 +221,7 @@ METHOD(OverkillNex, wr_think, void(entity thiswep, entity actor, .entity weapone
        //                              if(fire & 2) // only eat ammo when the button is pressed
        //                              {
        //                                      dt = min(dt, (1 - actor.(weaponentity).oknex_charge) / WEP_CVAR(oknex, charge_rate));
-       //                                      if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+       //                                      if(!(actor.items & IT_UNLIMITED_AMMO))
        //                                      {
        //                                              // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
        //                                              if(autocvar_g_balance_vortex_reload_ammo)
index cb9aea5cc3b3d69206e3cec18587f83a40bdb09e..8176669dea78164c5b7bc0e8fecc9e8f4febf8a2 100644 (file)
@@ -274,6 +274,10 @@ MUTATOR_HOOKFUNCTION(ok, SetStartItems, CBC_ORDER_LAST)
        if(WEP_OVERKILL_RPC.weaponstart > 0) { ok_start_items |= WEPSET(OVERKILL_RPC); }
        if(WEP_OVERKILL_HMG.weaponstart > 0) { ok_start_items |= WEPSET(OVERKILL_HMG); }
 
+       // this gives unlimited ammo (the 4 types) but not fuel
+       // using `g_use_ammunition` instead gives also fuel which is unnecessary and distracting in the HUD
+       start_items |= IT_UNLIMITED_AMMO;
+
        start_weapons = warmup_start_weapons = ok_start_items;
 }
 
index 73435841d87c296f1119c3078b1f4c0833ba02d8..2243c9872cba4d3ed6d1b1f4c47e25d7cf41a2e9 100644 (file)
@@ -103,10 +103,15 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
                        vector horiz_vel = vec2(it.velocity);
                        // when walking slowly sideways, we assume the player wants a clear shot ahead - spawn behind him according to where he's looking
                        // when running fast, spawn behind him according to his direction of movement to prevent colliding with the newly spawned player
+                       vector forward = '0 0 0'; vector right = '0 0 0'; vector up = '0 0 0';
                        if (vdist(horiz_vel, >, autocvar_sv_maxspeed + 50))
-                               fixedmakevectors(vectoangles(horiz_vel));
+                       {
+                               FIXED_MAKE_VECTORS(vectoangles(horiz_vel), forward, right, up);
+                       }
                        else
-                               fixedmakevectors(it.angles); // .angles is the angle of the model - usually/always 0 pitch
+                       {
+                               FIXED_MAKE_VECTORS(it.angles, forward, right, up);
+                       }
 
                        // test different spots close to mate - trace upwards so it works on uneven surfaces
                        // don't spawn in front of player or directly behind to avoid players shooting each other
@@ -117,22 +122,22 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
                                switch(i)
                                {
                                        case 0:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 64 + v_right * 128 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 64 + right * 128 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                        case 1:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 64 - v_right * 128 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 64 - right * 128 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                        case 2:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin + v_right * 192 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin + right * 192 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                        case 3:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_right * 192 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - right * 192 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                        case 4:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 128 + v_right * 64 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 128 + right * 64 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                        case 5:
-                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 128 - v_right * 64 + v_up * 64, MOVE_NOMONSTERS, it);
+                                               tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 128 - right * 64 + up * 64, MOVE_NOMONSTERS, it);
                                                break;
                                }
 
@@ -142,7 +147,7 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
 
                                // 400 is about the height of a typical laser jump (in overkill)
                                // not traceline because we need space for the whole player, not just his origin
-                               tracebox(horizontal_trace_endpos, STAT(PL_MIN, player), STAT(PL_MAX, player), horizontal_trace_endpos - '0 0 400', MOVE_NORMAL, it);
+                               tracebox(horizontal_trace_endpos, STAT(PL_MIN, player), STAT(PL_MAX, player), horizontal_trace_endpos - 400 * up, MOVE_NORMAL, it);
                                vector vectical_trace_endpos = trace_endpos;
                                //te_lightning1(NULL, horizontal_trace_endpos, vectical_trace_endpos);
                                if (trace_startsolid) goto skip; // inside another player
@@ -152,8 +157,9 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
                                if (tracebox_hits_trigger_hurt(horizontal_trace_endpos, STAT(PL_MIN, player), STAT(PL_MAX, player), vectical_trace_endpos)) goto skip;
 
                                // make sure the spawned player will have floor ahead (or at least a wall - he shouldn't fall as soon as he starts moving)
-                               vector floor_test_start = vectical_trace_endpos + v_up * STAT(PL_MAX, player).z + v_forward * STAT(PL_MAX, player).x; // top front of player's bbox - highest point we know is not inside solid
-                               traceline(floor_test_start, floor_test_start + v_forward * 100 - v_up * 128, MOVE_NOMONSTERS, it);
+                               // top front of player's bbox - highest point we know is not inside solid
+                               vector floor_test_start = vectical_trace_endpos + up * STAT(PL_MAX, player).z + forward * STAT(PL_MAX, player).x; 
+                               traceline(floor_test_start, floor_test_start + forward * 100 - up * 128, MOVE_NOMONSTERS, it);
                                //te_beam(NULL, floor_test_start, trace_endpos);
                                if (trace_fraction == 1.0) goto skip;
 
@@ -171,7 +177,7 @@ MUTATOR_HOOKFUNCTION(spawn_near_teammate, PlayerSpawn)
 
                                // here, we know we found a good spot
                                RandomSelection_Add(it, 0, string_null, vectical_trace_endpos, 1, 1);
-                               //te_lightning1(NULL, vectical_trace_endpos, vectical_trace_endpos + v_forward * 10);
+                               //te_lightning1(NULL, vectical_trace_endpos, vectical_trace_endpos + forward * 10);
 
 LABEL(skip)
                                if (i % 2 == 1 && RandomSelection_chosen_ent)
index acef8c97ad183273d5e944e5c119838bc4d6eb54..5ba6e82685b3204ce2caa5da04c5862253f0c974 100644 (file)
@@ -41,14 +41,18 @@ void Physics_UpdateStats(entity this)
 
        MUTATOR_CALLHOOK(PlayerPhysics_UpdateStats, this);
        float maxspd_mod = PHYS_HIGHSPEED(this);
-
-       STAT(MOVEVARS_AIRACCEL_QW, this) = AdjustAirAccelQW(Physics_ClientOption(this, "airaccel_qw", autocvar_sv_airaccel_qw), maxspd_mod);
-       STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = (Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw))
-               ? AdjustAirAccelQW(Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw), maxspd_mod)
-               : 0;
-       STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw", autocvar_sv_airspeedlimit_nonqw) * maxspd_mod;
-       STAT(MOVEVARS_MAXSPEED, this) = Physics_ClientOption(this, "maxspeed", autocvar_sv_maxspeed) * maxspd_mod; // also slow walking
-
+        STAT(MOVEVARS_MAXSPEED, this) = Physics_ClientOption(this, "maxspeed", autocvar_sv_maxspeed) * maxspd_mod; // also slow walking
+        if (autocvar_g_movement_highspeed_q3_compat) {
+          STAT(MOVEVARS_AIRACCEL_QW, this) = Physics_ClientOption(this, "airaccel_qw", autocvar_sv_airaccel_qw);
+          STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw);
+          STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw", autocvar_sv_airspeedlimit_nonqw);
+        } else {
+          STAT(MOVEVARS_AIRACCEL_QW, this) = AdjustAirAccelQW(Physics_ClientOption(this, "airaccel_qw", autocvar_sv_airaccel_qw), maxspd_mod);
+          STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = (Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw))
+            ? AdjustAirAccelQW(Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw), maxspd_mod)
+            : 0;
+          STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, this) = Physics_ClientOption(this, "airspeedlimit_nonqw", autocvar_sv_airspeedlimit_nonqw) * maxspd_mod;
+        }
        bool vq3compat = autocvar_sv_vq3compat && autocvar_sv_vq3compat_changehitbox; // NOTE: these hitboxes are off by 1 due to engine differences
        STAT(PL_MIN, this) = (vq3compat) ? '-15 -15 -24' : autocvar_sv_player_mins;
        STAT(PL_MAX, this) = (vq3compat) ? '15 15 32' : autocvar_sv_player_maxs;
@@ -61,7 +65,12 @@ void Physics_UpdateStats(entity this)
        // fix some new settings
        STAT(MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, this) = Physics_ClientOption(this, "airaccel_qw_stretchfactor", autocvar_sv_airaccel_qw_stretchfactor);
        STAT(MOVEVARS_MAXAIRSTRAFESPEED, this) = Physics_ClientOption(this, "maxairstrafespeed", autocvar_sv_maxairstrafespeed);
-       STAT(MOVEVARS_MAXAIRSPEED, this) = Physics_ClientOption(this, "maxairspeed", autocvar_sv_maxairspeed);
+        if (autocvar_g_movement_highspeed_q3_compat) {
+          STAT(MOVEVARS_MAXAIRSPEED, this) = Physics_ClientOption(this, "maxairspeed", autocvar_sv_maxairspeed) * maxspd_mod;
+        } else {
+          STAT(MOVEVARS_MAXAIRSPEED, this) = Physics_ClientOption(this, "maxairspeed", autocvar_sv_maxairspeed);
+        }
+
        STAT(MOVEVARS_AIRSTRAFEACCELERATE, this) = Physics_ClientOption(this, "airstrafeaccelerate", autocvar_sv_airstrafeaccelerate);
        STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, this) = Physics_ClientOption(this, "warsowbunny_turnaccel", autocvar_sv_warsowbunny_turnaccel);
        STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, this) = Physics_ClientOption(this, "airaccel_sideways_friction", autocvar_sv_airaccel_sideways_friction);
@@ -472,7 +481,7 @@ void CheckPlayerJump(entity this)
 
                bool air_jump = !playerjump || M_ARGV(2, bool);
                bool activate = JETPACK_JUMP(this) && air_jump && PHYS_INPUT_BUTTON_JUMP(this) || PHYS_INPUT_BUTTON_JETPACK(this);
-               bool has_fuel = !PHYS_JETPACK_FUEL(this) || PHYS_AMMO_FUEL(this) || (ITEMS_STAT(this) & IT_UNLIMITED_WEAPON_AMMO);
+               bool has_fuel = !PHYS_JETPACK_FUEL(this) || PHYS_AMMO_FUEL(this) || (ITEMS_STAT(this) & IT_UNLIMITED_AMMO);
 
                if (!(ITEMS_STAT(this) & ITEM_Jetpack.m_itemid)) { }
                else if (this.jetpack_stopped) { }
@@ -785,7 +794,7 @@ void PM_jetpack(entity this, float maxspd_mod, float dt)
        wishvel_z = (wishvel_z - PHYS_GRAVITY(this)) * fz + PHYS_GRAVITY(this);
 
        fvel = min(1, vlen(wishvel) / best);
-       if (PHYS_JETPACK_FUEL(this) && !(ITEMS_STAT(this) & IT_UNLIMITED_WEAPON_AMMO))
+       if (PHYS_JETPACK_FUEL(this) && !(ITEMS_STAT(this) & IT_UNLIMITED_AMMO))
                f = min(1, PHYS_AMMO_FUEL(this) / (PHYS_JETPACK_FUEL(this) * dt * fvel));
        else
                f = 1;
@@ -798,7 +807,7 @@ void PM_jetpack(entity this, float maxspd_mod, float dt)
                UNSET_ONGROUND(this);
 
 #ifdef SVQC
-               if (!(ITEMS_STAT(this) & IT_UNLIMITED_WEAPON_AMMO))
+               if (!(ITEMS_STAT(this) & IT_UNLIMITED_AMMO))
                        TakeResource(this, RES_FUEL, PHYS_JETPACK_FUEL(this) * dt * fvel * f);
 
                ITEMS_STAT(this) |= IT_USING_JETPACK;
index d349f48c54653ef954d32c56ce7c0c3653d2a963..9d595b9591df90326e8d188c17ef2abfdc94f6ee 100644 (file)
@@ -1477,9 +1477,6 @@ void target_items_use(entity this, entity actor, entity trigger)
 
 spawnfunc(target_items)
 {
-       int n;
-       string s;
-
        this.use = target_items_use;
        if(!this.strength_finished)
                this.strength_finished = autocvar_g_balance_powerup_strength_time;
@@ -1488,7 +1485,7 @@ spawnfunc(target_items)
        if(!this.superweapons_finished)
                this.superweapons_finished = autocvar_g_balance_superweapons_time;
 
-       n = tokenize_console(this.netname);
+       int n = tokenize_console(this.netname);
        if(argv(0) == "give")
        {
                this.netname = substring(this.netname, argv_start_index(1), argv_end_index(-1) - argv_start_index(1));
@@ -1497,8 +1494,9 @@ spawnfunc(target_items)
        {
                for(int j = 0; j < n; ++j)
                {
-                       if     (argv(j) == "unlimited_ammo")         this.items |= IT_UNLIMITED_AMMO;
-                       else if(argv(j) == "unlimited_weapon_ammo")  this.items |= IT_UNLIMITED_WEAPON_AMMO;
+                       // this is from a time when unlimited superweapons were handled together with ammo in some parts of the code
+                       if     (argv(j) == "unlimited_ammo")         this.items |= IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS;
+                       else if(argv(j) == "unlimited_weapon_ammo")  this.items |= IT_UNLIMITED_AMMO;
                        else if(argv(j) == "unlimited_superweapons") this.items |= IT_UNLIMITED_SUPERWEAPONS;
                        else if(argv(j) == "strength")               this.items |= ITEM_Strength.m_itemid;
                        else if(argv(j) == "invincible")             this.items |= ITEM_Shield.m_itemid;
@@ -1509,7 +1507,7 @@ spawnfunc(target_items)
                        {
                                FOREACH(Buffs, it != BUFF_Null,
                                {
-                                       s = Buff_UndeprecateName(argv(j));
+                                       string s = Buff_UndeprecateName(argv(j));
                                        if(s == it.netname)
                                        {
                                                STAT(BUFFS, this) |= (it.m_itemid);
@@ -1519,7 +1517,7 @@ spawnfunc(target_items)
                                        }
                                });
                                FOREACH(Weapons, it != WEP_Null, {
-                                       s = W_UndeprecateName(argv(j));
+                                       string s = W_UndeprecateName(argv(j));
                                        if(s == it.netname)
                                        {
                                                STAT(WEAPONS, this) |= (it.m_wepset);
@@ -1559,7 +1557,7 @@ spawnfunc(target_items)
                }
 
                this.netname = "";
-               this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & IT_UNLIMITED_WEAPON_AMMO), "unlimited_weapon_ammo");
+               this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & IT_UNLIMITED_AMMO), "unlimited_weapon_ammo");
                this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & IT_UNLIMITED_SUPERWEAPONS), "unlimited_superweapons");
                this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, this.strength_finished * boolean(this.items & ITEM_Strength.m_itemid), "strength");
                this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, this.invincible_finished * boolean(this.items & ITEM_Shield.m_itemid), "invincible");
@@ -1763,7 +1761,7 @@ float GiveItems(entity e, float beginarg, float endarg)
                                got += GiveValue(e, strength_finished, op, val);
                                got += GiveValue(e, invincible_finished, op, val);
                                got += GiveValue(e, superweapons_finished, op, val);
-                               got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
+                               got += GiveBit(e, items, IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS, op, val);
                        case "all":
                                got += GiveBit(e, items, ITEM_Jetpack.m_itemid, op, val);
                                got += GiveResourceValue(e, RES_HEALTH, op, val);
@@ -1781,10 +1779,11 @@ float GiveItems(entity e, float beginarg, float endarg)
                                got += GiveResourceValue(e, RES_FUEL, op, val);
                                break;
                        case "unlimited_ammo":
-                               got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
+                               // this is from a time when unlimited superweapons were handled together with ammo in some parts of the code
+                               got += GiveBit(e, items, IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS, op, val);
                                break;
                        case "unlimited_weapon_ammo":
-                               got += GiveBit(e, items, IT_UNLIMITED_WEAPON_AMMO, op, val);
+                               got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
                                break;
                        case "unlimited_superweapons":
                                got += GiveBit(e, items, IT_UNLIMITED_SUPERWEAPONS, op, val);
@@ -1847,7 +1846,7 @@ float GiveItems(entity e, float beginarg, float endarg)
 
        POSTGIVE_BIT(e, items, ITEM_JetpackRegen.m_itemid, SND_ITEMPICKUP, SND_Null);
        POSTGIVE_BIT(e, items, IT_UNLIMITED_SUPERWEAPONS, SND_POWERUP, SND_POWEROFF);
-       POSTGIVE_BIT(e, items, IT_UNLIMITED_WEAPON_AMMO, SND_POWERUP, SND_POWEROFF);
+       POSTGIVE_BIT(e, items, IT_UNLIMITED_AMMO, SND_POWERUP, SND_POWEROFF);
        POSTGIVE_BIT(e, items, ITEM_Jetpack.m_itemid, SND_ITEMPICKUP, SND_Null);
        FOREACH(Weapons, it != WEP_Null, {
                POSTGIVE_WEAPON(e, it, SND_WEAPONPICKUP, SND_Null);
index 6efb21495bbaed25831066aba3eddc9c91c24c18..5948d6a12e2831e0fcaf2f340cd7ae781ee72ce7 100644 (file)
@@ -232,7 +232,7 @@ void W_Arc_Beam_Think(entity this)
                }
 
                if(this == own.(weaponentity).arc_beam) { own.(weaponentity).arc_beam = NULL; }
-               if(!thiswep.wr_checkammo1(thiswep, own, weaponentity) && !(own.items & IT_UNLIMITED_WEAPON_AMMO))
+               if(!thiswep.wr_checkammo1(thiswep, own, weaponentity) && !(own.items & IT_UNLIMITED_AMMO))
                {
                        // note: this doesn't force the switch
                        W_SwitchToOtherWeapon(own, weaponentity);
@@ -244,7 +244,7 @@ void W_Arc_Beam_Think(entity this)
 
        // decrease ammo
        float coefficient = frametime;
-       if(!(own.items & IT_UNLIMITED_WEAPON_AMMO))
+       if(!(own.items & IT_UNLIMITED_AMMO))
        {
                float rootammo;
                if(burst)
index db14a603068f47d3b9c267cad6369b2573359dd7..a69f43fbd3f7afbdd01bca9d88707ee5255c5729 100644 (file)
@@ -574,7 +574,7 @@ METHOD(Crylink, wr_think, void(entity thiswep, entity actor, .entity weaponentit
             }
             actor.(weaponentity).crylink_waitrelease = 0;
             if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity) && !thiswep.wr_checkammo2(thiswep, actor, weaponentity))
-            if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+            if(!(actor.items & IT_UNLIMITED_AMMO))
             {
                 // ran out of ammo!
                 actor.cnt = thiswep.m_id;
index fc42f39d71763909615daaedb2c6790445f1aa51..fce84c3b8eb88cc3d0b36a37861a361e5810f103 100644 (file)
@@ -47,7 +47,7 @@ void W_Devastator_Explode(entity this, entity directhitentity)
        if(this.realowner.(weaponentity).m_weapon == thiswep)
        {
                if(GetResource(this.realowner, thiswep.ammo_type) < WEP_CVAR(devastator, ammo))
-               if(!(this.realowner.items & IT_UNLIMITED_WEAPON_AMMO))
+               if(!(this.realowner.items & IT_UNLIMITED_AMMO))
                {
                        this.realowner.cnt = thiswep.m_id;
                        ATTACK_FINISHED(this.realowner, weaponentity) = time;
@@ -143,7 +143,7 @@ void W_Devastator_DoRemoteExplode(entity this, .entity weaponentity)
        if(this.realowner.(weaponentity).m_weapon == thiswep)
        {
                if(GetResource(this.realowner, thiswep.ammo_type) < WEP_CVAR(devastator, ammo))
-               if(!(this.realowner.items & IT_UNLIMITED_WEAPON_AMMO))
+               if(!(this.realowner.items & IT_UNLIMITED_AMMO))
                {
                        this.realowner.cnt = thiswep.m_id;
                        ATTACK_FINISHED(this.realowner, weaponentity) = time;
index 51699bf0cdc560a981cf7cb5d9abdcec4998585c..0ffa0c74d973b92f00f9c5fb4b06b22a522f0704 100644 (file)
@@ -264,7 +264,7 @@ void W_Hagar_Attack2_Load(Weapon thiswep, entity actor, .entity weaponentity)
 
        // this is different than WR_CHECKAMMO when it comes to reloading
        bool enough_ammo;
-       if(actor.items & IT_UNLIMITED_WEAPON_AMMO)
+       if(actor.items & IT_UNLIMITED_AMMO)
                enough_ammo = true;
        else if(autocvar_g_balance_hagar_reload_ammo)
                enough_ammo = actor.(weaponentity).(weapon_load[thiswep.m_id]) >= WEP_CVAR_SEC(hagar, ammo);
@@ -352,7 +352,7 @@ void W_Hagar_Attack2_Load(Weapon thiswep, entity actor, .entity weaponentity)
 
                // we aren't checking ammo during an attack, so we must do it here
                if(!(thiswep.wr_checkammo1(thiswep, actor, weaponentity) + thiswep.wr_checkammo2(thiswep, actor, weaponentity)))
-               if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+               if(!(actor.items & IT_UNLIMITED_AMMO))
                {
                        // note: this doesn't force the switch
                        W_SwitchToOtherWeapon(actor, weaponentity);
@@ -370,7 +370,7 @@ void W_Hagar_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity, int
        }
 
        if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity))
-       if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+       if(!(actor.items & IT_UNLIMITED_AMMO))
        {
                W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
                w_ready(thiswep, actor, weaponentity, fire);
index 8498597634bbcf7c689e1b5adcf2d480b75c0ff1..6511d22b572b4fab5938c035aea73d2e18dec6a2 100644 (file)
@@ -127,7 +127,7 @@ void W_HLAC_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentity, int
        if(PHYS_INPUT_BUTTON_ATCK(actor))
        {
                if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity))
-               if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+               if(!(actor.items & IT_UNLIMITED_AMMO))
                {
                        W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
                        w_ready(thiswep, actor, weaponentity, fire);
index d8cebd740ac49fc3daf8ec2c5d5111e30f27a740..d9e11dc012fb9d2736a0f04a56853d4ab9c9e14d 100644 (file)
@@ -145,7 +145,7 @@ METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity,
         actor.(weaponentity).hook_refire = max(actor.(weaponentity).hook_refire, time + WEP_CVAR_PRI(hook, refire) * W_WeaponRateFactor(actor));
 
         // hook also inhibits health regeneration, but only for 1 second
-        if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+        if(!(actor.items & IT_UNLIMITED_AMMO))
             actor.pauseregen_finished = max(actor.pauseregen_finished, time + autocvar_g_balance_pause_fuel_regen);
     }
 
@@ -163,7 +163,7 @@ METHOD(Hook, wr_think, void(entity thiswep, entity actor, .entity weaponentity,
         {
             if( time > actor.(weaponentity).hook_time_fueldecrease )
             {
-                if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+                if(!(actor.items & IT_UNLIMITED_AMMO))
                 {
                     if( GetResource(actor, RES_FUEL) >= (time - actor.(weaponentity).hook_time_fueldecrease) * hooked_fuel )
                     {
index e16ffe66bd451b1a7a4927aaa047417cd3d645db..86de79f600603d02f84bab06858b5dc533b42508 100644 (file)
@@ -84,7 +84,7 @@ void W_MachineGun_Attack_Frame(Weapon thiswep, entity actor, .entity weaponentit
        if(PHYS_INPUT_BUTTON_ATCK(actor))
        {
                if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
-               if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+               if(!(actor.items & IT_UNLIMITED_AMMO))
                {
                        W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
                        w_ready(thiswep, actor, weaponentity, fire);
@@ -110,7 +110,7 @@ void W_MachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity
        }
 
        if(!thiswep.wr_checkammo1(thiswep, actor, weaponentity))
-       if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+       if(!(actor.items & IT_UNLIMITED_AMMO))
        {
                W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
                w_ready(thiswep, actor, weaponentity, fire);
@@ -211,7 +211,7 @@ METHOD(MachineGun, wr_think, void(entity thiswep, entity actor, .entity weaponen
         if(weapon_prepareattack(thiswep, actor, weaponentity, true, 0))
         {
             if(!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
-            if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+            if(!(actor.items & IT_UNLIMITED_AMMO))
             {
                 W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
                 w_ready(thiswep, actor, weaponentity, fire);
index f8c2be1d50777e1cea209366fe830aee87381009..d7ba289f5ca7ee9f1e92669a9fd5098b93791771 100644 (file)
@@ -342,8 +342,6 @@ void W_Seeker_Attack(Weapon thiswep, entity actor, .entity weaponentity)
 
 void W_Seeker_Vollycontroller_Think(entity this) // TODO: Merge this with W_Seeker_Attack
 {
-       float c;
-       entity oldenemy;
        this.cnt = this.cnt - 1;
 
        Weapon thiswep = WEP_SEEKER;
@@ -358,11 +356,10 @@ void W_Seeker_Vollycontroller_Think(entity this) // TODO: Merge this with W_Seek
 
        entity own = this.realowner;
 
-       oldenemy = own.enemy;
+       entity oldenemy = own.enemy;
        own.enemy = this.enemy;
 
-       c = own.cnt % 4;
-       switch(c)
+       switch(own.cnt % 4)
        {
                case 0:
                        W_Seeker_Fire_Missile(thiswep, own, weaponentity, '-1.25 -3.75 0', own.enemy); // TODO
index 94f84ba5b1b8a88fa13b78e7c7afc7aed9f703a8..74986f9cc96be069154ee8c5dd35419cf07c6b85 100644 (file)
@@ -666,9 +666,8 @@ void Draw_Shockwave(entity this)
        // WEAPONTODO: trace to find what we actually hit
        vector endpos = (this.sw_shotorg + (this.sw_shotdir * this.sw_distance));
 
-       vectorvectors(this.sw_shotdir);
-       vector right = v_right; // save this for when we do makevectors later
-       vector up = v_up; // save this for when we do makevectors later
+       vector _forward, right, up;
+       VECTOR_VECTORS(this.sw_shotdir, _forward, right, up);
 
        // WEAPONTODO: combine and simplify these calculations
        vector min_end = ((this.sw_shotorg + (this.sw_shotdir * SW_DISTTOMIN)) + (up * this.sw_spread_min));
index 18e75fad26e54aba8eed9cf6269ff6a5ecd9a29a..e2f4b640aa1b818f3a6b7640c9cf7be2d61c93b2 100644 (file)
@@ -162,7 +162,7 @@ void W_Shotgun_Attack2(Weapon thiswep, entity actor, .entity weaponentity, int f
 void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor, .entity weaponentity, int fire)
 {
        if (!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
-       if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+       if (!(actor.items & IT_UNLIMITED_AMMO))
        {
                W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
                w_ready(thiswep, actor, weaponentity, fire);
@@ -183,7 +183,7 @@ void W_Shotgun_Attack3_Frame2(Weapon thiswep, entity actor, .entity weaponentity
 void W_Shotgun_Attack3_Frame1(Weapon thiswep, entity actor, .entity weaponentity, int fire)
 {
        if (!thiswep.wr_checkammo2(thiswep, actor, weaponentity))
-       if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+       if (!(actor.items & IT_UNLIMITED_AMMO))
        {
                W_SwitchWeapon_Force(actor, w_getbestweapon(actor, weaponentity), weaponentity);
                w_ready(thiswep, actor, weaponentity, fire);
@@ -263,7 +263,7 @@ METHOD(Shotgun, wr_think, void(entity thiswep, entity actor, .entity weaponentit
     }
     if(actor.(weaponentity).clip_load >= 0) // we are not currently reloading
     if(WEP_CVAR(shotgun, secondary) == 1)
-    if(((fire & 1) && GetResource(actor, thiswep.ammo_type) <= 0 && !(actor.items & IT_UNLIMITED_WEAPON_AMMO)) || (fire & 2))
+    if(((fire & 1) && GetResource(actor, thiswep.ammo_type) <= 0 && !(actor.items & IT_UNLIMITED_AMMO)) || (fire & 2))
     if(weapon_prepareattack(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(shotgun, refire)))
     {
         // attempt forcing playback of the anim by switching to another anim (that we never play) here...
index af7fac624195caa439ff0b54266f12ac80186353..46fd4d8c0887639b8b8c32e8b116c0f60ff4538e 100644 (file)
@@ -230,7 +230,7 @@ METHOD(Vortex, wr_think, void(entity thiswep, entity actor, .entity weaponentity
                         if(fire & 2) // only eat ammo when the button is pressed
                         {
                             dt = min(dt, (1 - actor.(weaponentity).vortex_charge) / WEP_CVAR(vortex, charge_rate));
-                            if(!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+                            if(!(actor.items & IT_UNLIMITED_AMMO))
                             {
                                 // if this weapon is reloadable, decrease its load. Else decrease the player's ammo
                                 if(autocvar_g_balance_vortex_reload_ammo)
index 29d797585efbe10117995db27925b739109abae6..9453157f7000591bf273c07ed20aff7438404636 100644 (file)
 #define use use1
 .void(entity this, entity actor, entity trigger) use;
 #define touch move_touch
+
+// deglobalization:
+
+void(vector ang) _makevectors_hidden = #1;
+//#define makevectors DO_NOT_USE_GLOBALS_PREFER_MAKE_VECTORS_MACRO_INSTEAD
+
+#define makestatic DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+#define skel_get_bonerel DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+vector(float skel, float bonenum) _skel_get_boneabs_hidden = #270;
+//#define skel_get_boneabs DO_NOT_USE_GLOBALS_PREFER_SKEL_GET_BONE_ABS_MACRO_INSTEAD
+
+void(float skel, float bonenum, vector org) _skel_set_bone_hidden = #271;
+//#define skel_set_bone DO_NOT_USE_GLOBALS_PREFER_SKEL_SET_BONE_MACRO_INSTEAD
+
+#define skel_mul_bone DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+#define skel_mul_bones DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+void(vector org, float radius, vector lightcolours) _adddynamiclight_hidden = #305;
+//#define adddynamiclight DO_NOT_USE_GLOBALS_PREFER_ADD_DYNAMIC_LIGHT_MACRO_INSTEAD
+#define adddynamiclight2 DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+void(vector dir) _vectorvectors_hidden = #432;
+#define vectorvectors DO_NOT_USE_GLOBALS_PREFER_VECTOR_VECTORS_MACRO_INSTEAD
+
+vector(entity ent, float tagindex) _gettaginfo_hidden = #452;
+//#define gettaginfo DO_NOT_USE_GLOBALS_PREFER_GET_TAG_INFO_MACRO_INSTEAD
+
+#define getentity DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+#define getentityvec DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
index 2ed0f9063889af40f2270740e069f47d29f62789..d6f6a072a0fea688e192219b28e21184a8c7b76b 100644 (file)
@@ -63,3 +63,20 @@ int() _buf_create = #460;
 #define buf_create _buf_create
 
 #pragma noref 0
+
+// deglobalization:
+
+#define skel_get_bonerel DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+vector(float skel, float bonenum) _skel_get_boneabs_hidden = #270;
+//#define skel_get_boneabs DO_NOT_USE_GLOBALS_PREFER_SKEL_GET_BONE_ABS_MACRO_INSTEAD
+
+void(float skel, float bonenum, vector org) _skel_set_bone_hidden = #271;
+//#define skel_set_bone DO_NOT_USE_GLOBALS_PREFER_SKEL_SET_BONE_MACRO_INSTEAD
+
+#define skel_mul_bone DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+#define skel_mul_bones DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+vector(entity ent, float tagindex) _gettaginfo_hidden = #452;
+//#define gettaginfo DO_NOT_USE_GLOBALS_PREFER_GET_TAG_INFO_MACRO_INSTEAD
index ccdf9bc0c4293353a7e8392b059831e313474958..a8d8a4a486a0824cb200182a176ebf856762f8ed 100644 (file)
@@ -29,3 +29,12 @@ MACRO_END
 
 #define use use1
 .void(entity this, entity actor, entity trigger) use;
+
+// deglobalization:
+
+void(vector ang) _makevectors_hidden = #1;
+//#define makevectors DO_NOT_USE_GLOBALS_PREFER_MAKE_VECTORS_MACRO_INSTEAD
+
+#define aim DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
+
+#define makestatic DO_NOT_USE_GLOBALS // not used anywhere so not wrapped
index ae5f119e7fe8db0eea039a57032af553cd4d7d24..f73ade3d12ea58ea6f5652554909505c0a335f79 100644 (file)
@@ -193,8 +193,8 @@ void sys_phys_simulate(entity this, float dt)
                // this mimics quakeworld code
                if (this.com_in_jump && this.waterlevel == WATERLEVEL_SWIMMING && this.velocity_z >= -180 && !this.viewloc) {
                        vector yawangles = '0 1 0' * this.v_angle.y;
-                       makevectors(yawangles);
-                       vector forward = v_forward;
+                       vector forward, right, up;
+                       MAKE_VECTORS(yawangles, forward, right, up);
                        vector spot = this.origin + 24 * forward;
                        spot_z += 8;
                        traceline(spot, spot, MOVE_NOMONSTERS, this);
@@ -210,10 +210,12 @@ void sys_phys_simulate(entity this, float dt)
                        }
                }
        }
-       makevectors(vmul(this.v_angle, (this.com_phys_vel_2d ? '0 1 0' : '1 1 1')));
-       // wishvel = v_forward * PHYS_CS(this).movement.x + v_right * PHYS_CS(this).movement.y + v_up * PHYS_CS(this).movement.z;
-       vector wishvel = v_forward * PHYS_CS(this).movement.x
-           + v_right * PHYS_CS(this).movement.y
+
+       vector forward, right, up;
+       MAKE_VECTORS(vmul(this.v_angle, (this.com_phys_vel_2d ? '0 1 0' : '1 1 1')), forward, right, up);
+       // wishvel = forward * PHYS_CS(this).movement.x + right * PHYS_CS(this).movement.y + up * PHYS_CS(this).movement.z;
+       vector wishvel = forward * PHYS_CS(this).movement.x
+           + right * PHYS_CS(this).movement.y
            + '0 0 1' * PHYS_CS(this).movement.z * (this.com_phys_vel_2d ? 0 : 1);
        if (this.com_phys_water) {
                if (PHYS_INPUT_BUTTON_CROUCH(this)) {
index ab74531605f29a44d7f69c23b7ba99e4f30a3479..3bbb17ccf8715ddfced52d63453e41e7f40cc3e2 100644 (file)
 #include "counting.qh"
 #include "cvar.qh"
 #include "defer.qh"
+#include "deglobalization.qh"
 #include "draw.qh"
 #include "enumclass.qh"
 #include "file.qh"
+#include "float.qh"
 #include "functional.qh"
 #include "i18n.qh"
 #include "intrusivelist.qh"
index 4fd138360a3548bea865f8d7292f432e477865f0..7600fdde606f5d7a5c6733c0f2822b448140d806 100644 (file)
@@ -58,7 +58,8 @@ void InterpolateOrigin_Note(entity this)
 
        if (this.iflags & IFLAG_ANGLES)
        {
-               fixedmakevectors(this.angles);
+               vector forward, right, up;
+               FIXED_MAKE_VECTORS(this.angles, forward, right, up);
                if (f0 & IFLAG_VALID)
                {
                        this.iforward1 = this.iforward2;
@@ -66,16 +67,17 @@ void InterpolateOrigin_Note(entity this)
                }
                else
                {
-                       this.iforward1 = v_forward;
-                       this.iup1 = v_up;
+                       this.iforward1 = forward;
+                       this.iup1 = up;
                }
-               this.iforward2 = v_forward;
-               this.iup2 = v_up;
+               this.iforward2 = forward;
+               this.iup2 = up;
        }
 
        if (this.iflags & IFLAG_V_ANGLE)
        {
-               fixedmakevectors(this.v_angle);
+               vector forward, right, up;
+               FIXED_MAKE_VECTORS(this.v_angle, forward, right, up);
                if (f0 & IFLAG_VALID)
                {
                        this.ivforward1 = this.ivforward2;
@@ -83,11 +85,11 @@ void InterpolateOrigin_Note(entity this)
                }
                else
                {
-                       this.ivforward1 = v_forward;
-                       this.ivup1 = v_up;
+                       this.ivforward1 = forward;
+                       this.ivup1 = up;
                }
-               this.ivforward2 = v_forward;
-               this.ivup2 = v_up;
+               this.ivforward2 = forward;
+               this.ivup2 = up;
        }
        else if (this.iflags & IFLAG_V_ANGLE_X)
        {
diff --git a/qcsrc/lib/deglobalization.qh b/qcsrc/lib/deglobalization.qh
new file mode 100644 (file)
index 0000000..3d7f820
--- /dev/null
@@ -0,0 +1,73 @@
+#include "lib/float.qh"
+#include "lib/misc.qh"
+#include "lib/static.qh"
+#include "lib/vector.qh"
+
+// These macros wrap functions which use globals so mutation only occurs inside them and is not visible from outside.
+// Functions for which all usages are replaced with these macros can be hidden by #defines inside our `*defs.qh` files
+// to prevent anyone from using them accidentally in the future
+
+// TODO stuff in the engine that uses the v_forward/v_right/v_up globals and is not wrapped yet:
+//  - RF_USEAXIS, addentities, predraw,
+//    - CL_GetEntityMatrix (in engine but is called from other functions so transitively any of them can use the globals - e.g. V_CalcRefdef, maybe others)
+//    - however RF_USEAXIS is only used if MF_ROTATE is used which is only set in one place
+//  - e.camera_transform / CL_VM_TransformView (in engine)
+//    - this is the only used function that both sets and gets the globals (aim does too but isn't used in our code)
+
+// convenience for deglobalization code - don't use these just to hide that globals are still used
+#define CLEAR_V_GLOBALS() v_forward = VEC_NAN; v_right = VEC_NAN; v_up = VEC_NAN
+#define GET_V_GLOBALS(forward, right, up) forward = v_forward; right = v_right; up = v_up
+#define SET_V_GLOBALS(forward, right, up) v_forward = forward; v_right = right; v_up = up
+
+#ifdef GAMEQC
+STATIC_INIT(globals) {
+       // set to NaN to more easily detect uninitialized use
+       // TODO when all functions are wrapped and the raw functions are not used anymore,
+       // uncomment the defines in *progs.qh files that hide the raw functions
+       // and assert that the global vectors are NaN before calling the raw functions here
+       // to make sure nobody (even builtins) is accidentally using them - NaN is the most likely value to expose remaining usages
+
+       CLEAR_V_GLOBALS();
+}
+#endif
+
+/// Same as the `makevectors` builtin but uses the provided locals instead of the `v_*` globals.
+/// Always use this instead of raw `makevectors` to make the data flow clear.
+/// Note that you might prefer `FIXED_MAKE_VECTORS` for new code.
+#define MAKE_VECTORS(angles, forward, right, up) MACRO_BEGIN \
+       _makevectors_hidden(angles); \
+       GET_V_GLOBALS(forward, right, up); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
+
+/// Returns all 4 vectors by assigning to them (instead of returning a value) for consistency (and sanity)
+#define SKEL_GET_BONE_ABS(skel, bonenum, forward, right, up, origin) MACRO_BEGIN \
+       origin = _skel_get_boneabs_hidden(skel, bonenum) \
+       GET_V_GLOBALS(forward, right, up); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
+
+#define SKEL_SET_BONE(skel, bonenum, org, forward, right, up) MACRO_BEGIN \
+       SET_V_GLOBALS(forward, right, up); \
+       _skel_set_bone_hidden(skel, bonenum, org); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
+
+#define ADD_DYNAMIC_LIGHT(org, radius, lightcolours, forward, right, up) MACRO_BEGIN \
+       SET_V_GLOBALS(forward, right, up); \
+       _adddynamiclight_hidden(org, radius, lightcolours); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
+
+#define VECTOR_VECTORS(forward_in, forward, right, up) MACRO_BEGIN \
+       _vectorvectors_hidden(forward_in); \
+       GET_V_GLOBALS(forward, right, up); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
+
+/// Note that this only avoids the v_* globals, not the gettaginfo_* ones
+#define GET_TAG_INFO(ent, tagindex, forward, right, up, origin) MACRO_BEGIN \
+       origin = _gettaginfo_hidden(ent, tagindex); \
+       GET_V_GLOBALS(forward, right, up); \
+       CLEAR_V_GLOBALS(); \
+MACRO_END
index b4d1f0bd768c785f103ad3886f5453769e10c2ff..b35494de44c0334f776d296f808565dd33af8be8 100644 (file)
@@ -2,3 +2,5 @@
 
 const float FLOAT_MAX = 340282346638528859811704183484516925440.0f;
 const float FLOAT_EPSILON = 0.00000011920928955078125f;
+/// Always use `isnan` function to compare because `float x = FLOAT_NAN; x == x;` gives true
+const float FLOAT_NAN = 0.0 / 0.0;
index 0d09ea8e6a50767bf181376b671423a9b7918070..ca0e84f67a95b4b8f118eac268d461a64ae6a8a7 100644 (file)
@@ -93,13 +93,6 @@ float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) { ret
 #define YAW(v) ((v).y)
 #define ROLL(v) ((v).z)
 
-#define MAKEVECTORS(f, angles, forward, right, up) MACRO_BEGIN \
-       f(angles); \
-       forward = v_forward; \
-       right = v_right; \
-       up = v_up; \
-MACRO_END
-
 //pseudo prototypes:
 // vector vec2(vector v); // returns a vector with just the x and y components of the given vector
 // vector vec2(float x, float y); // returns a vector with the given x and y components
@@ -112,6 +105,13 @@ noref vector _vec2;
 noref vector _vec3;
 #define vec3(_x, _y, _z) (_vec3.x = (_x), _vec3.y = (_y), _vec3.z = (_z), _vec3)
 
+#define VEC_NAN vec3(FLOAT_NAN, FLOAT_NAN, FLOAT_NAN);
+
+ERASEABLE
+bool is_all_nans(vector v) {
+       return isnan(v.x) && isnan(v.y) && isnan(v.z);
+}
+
 ERASEABLE
 vector Rotate(vector v, float a)
 {
index 9e98199f34be62fcd74fd742dc329f900c169d32..76e8d37f9a668c92bdb4e1b7ea79e010973b5e39 100644 (file)
@@ -4,34 +4,35 @@
 // angles in fixedmakevectors/fixedvectoangles space
 vector AnglesTransform_Apply(vector transform, vector v)
 {
-       fixedmakevectors(transform);
-       return v_forward * v.x
-               + v_right   * (-v.y)
-               + v_up      * v.z;
+       vector forward, right, up;
+       FIXED_MAKE_VECTORS(transform, forward, right, up);
+       return forward * v.x + right * (-v.y) + up * v.z;
 }
 
 vector AnglesTransform_Multiply(vector t1, vector t2)
 {
-       vector m_forward, m_up;
-       fixedmakevectors(t2); m_forward = v_forward; m_up = v_up;
-       m_forward = AnglesTransform_Apply(t1, m_forward); m_up = AnglesTransform_Apply(t1, m_up);
-       return fixedvectoangles2(m_forward, m_up);
+       vector forward, right, up;
+       FIXED_MAKE_VECTORS(t2, forward, right, up);
+       forward = AnglesTransform_Apply(t1, forward);
+       up = AnglesTransform_Apply(t1, up);
+       return fixedvectoangles2(forward, up);
 }
 
 vector AnglesTransform_Invert(vector transform)
 {
        vector i_forward, i_up;
-       fixedmakevectors(transform);
-       // we want angles that turn v_forward into '1 0 0', v_right into '0 1 0' and v_up into '0 0 1'
+       vector forward, right, up;
+       FIXED_MAKE_VECTORS(transform, forward, right, up);
+       // we want angles that turn forward into '1 0 0', right into '0 1 0' and up into '0 0 1'
        // but these are orthogonal unit vectors!
        // so to invert, we can simply fixedvectoangles the TRANSPOSED matrix
        // TODO is this always -transform?
-       i_forward.x = v_forward.x;
-       i_forward.y = -v_right.x;
-       i_forward.z = v_up.x;
-       i_up.x = v_forward.z;
-       i_up.y = -v_right.z;
-       i_up.z = v_up.z;
+       i_forward.x = forward.x;
+       i_forward.y = -right.x;
+       i_forward.z = up.x;
+       i_up.x = forward.z;
+       i_up.y = -right.z;
+       i_up.z = up.z;
        return fixedvectoangles2(i_forward, i_up);
 }
 
index b287651a10a4fb868acdfeca18d2c0dfaf77b4d0..92362f982fee1590b31c6340b7d576d4bcd7f68e 100644 (file)
@@ -6,6 +6,7 @@
 
 #if POSITIVE_PITCH_IS_DOWN
     #define fixedmakevectors makevectors
+    #define FIXED_MAKE_VECTORS MAKE_VECTORS
     noref vector _fixedvectoangles;
     #define fixedvectoangles(a) (_fixedvectoangles = vectoangles(a), _fixedvectoangles.x *= -1, _fixedvectoangles)
     noref vector _fixedvectoangles2;
         a.x = -a.x;
         makevectors(a);
     }
+    #define FIXED_MAKE_VECTORS(angles, forward, right, up) MACRO_BEGIN \
+        fixedmakevectors(angles); \
+        GET_V_GLOBALS(forward, right, up); \
+        CLEAR_V_GLOBALS(); \
+    MACRO_END
     #define fixedvectoangles2 vectoangles2
     #define fixedvectoangles vectoangles
 #endif
index b70e938fe7e987ee9dded47a2e721b151bd9d10d..3bff39be1fd954f89ff4984828aa0af67dad42bd 100644 (file)
@@ -71,8 +71,11 @@ void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, ve
        e.warpzone_targetorigin = other_org;
        e.warpzone_angles = my_ang;
        e.warpzone_targetangles = other_ang;
-       fixedmakevectors(my_ang); e.warpzone_forward = v_forward;
-       fixedmakevectors(other_ang); e.warpzone_targetforward = v_forward;
+       vector forward, right, up;
+       FIXED_MAKE_VECTORS(my_ang, forward, right, up);
+       e.warpzone_forward = forward;
+       FIXED_MAKE_VECTORS(other_ang, forward, right, up);
+       e.warpzone_targetforward = forward;
        setcamera_transform(e, WarpZone_camera_transform);
 }
 
@@ -201,7 +204,6 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end,
        float nomonsters_adjusted;
        float frac, sol, i;
        float contentshack;
-       vector o0, e0;
        entity wz;
        vector vf, vr, vu;
 
@@ -231,8 +233,6 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end,
        vf = v_forward;
        vr = v_right;
        vu = v_up;
-       o0 = org;
-       e0 = end;
 
        switch(nomonsters)
        {
index 4a7c8861069f7eb8420ec819b9525d606ffbe2d2..cf86d97f9cb5e22e6a2123eaf6f7136630cd590e 100644 (file)
@@ -24,8 +24,16 @@ bool isinf(float e)
 }
 bool isnan(float e)
 {
-       float f = e;
-       return (e != f);
+       // the sane way to detect NaN is broken because of a compiler bug
+       // (works with constants but breaks when assigned to variables)
+       // use conversion to string instead
+       //float f = e;
+       //return (e != f);
+
+       // Negative NaN ("-nan") is much more common but plain "nan" can be created by negating *some* -nans so we need to check both.
+       // DP's QCVM and GMQCC's QCVM behave differently - one needs ftos(-(0.0 / 0.0)), the other ftos(-sqrt(-1)).
+       string s = ftos(e);
+       return s == "nan" || s == "-nan";
 }
 bool isnormal(float e)
 {
@@ -217,6 +225,7 @@ float copysign(float e, float f)
 {
        return fabs(e) * ((f>0) ? 1 : -1);
 }
+/// Always use `isnan` function to compare because `float x = nan(); x == x;` gives true
 float nan(string tag)
 {
        return sqrt(-1);
index 9958a5df4a4497242afc4b0f7028bba54500be64..0244b40a9d724c33713d95e4b694cce4b6f84849 100644 (file)
@@ -602,15 +602,16 @@ void WarpZone_InitStep_UpdateTransform(entity this)
                if(area > 0)
                {
                        org = org - ((org - point) * norm) * norm; // project to plane
-                       makevectors(ang);
-                       if(norm * v_forward < 0)
+                       vector forward, right, up;
+                       MAKE_VECTORS(ang, forward, right, up);
+                       if(norm * forward < 0)
                        {
                                LOG_INFO("Position target of trigger_warpzone near ", vtos(this.aiment.origin), " points into trigger_warpzone. BEWARE.");
                                norm = -1 * norm;
                        }
-                       ang = vectoangles2(norm, v_up); // keep rotation, but turn exactly against plane
+                       ang = vectoangles2(norm, up); // keep rotation, but turn exactly against plane
                        ang.x = -ang.x;
-                       if(norm * v_forward < 0.99)
+                       if(norm * forward < 0.99)
                                LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been turned to match plane orientation (", vtos(this.aiment.angles), " -> ", vtos(ang));
                        if(vdist(org - this.aiment.origin, >, 0.5))
                                LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been moved to match the plane (", vtos(this.aiment.origin), " -> ", vtos(org), ").");
index d5533647f51e7727cb19b886e9fd3eea6887bb8c..658716052f6e9d0f2865a12808328b4bb2e74870 100644 (file)
@@ -15,8 +15,9 @@ void WarpZoneLib_ExactTrigger_Init(entity this)
        if (this.movedir == '0 0 0')
        if (this.angles != '0 0 0')
        {
-               makevectors (this.angles);
-               this.movedir = v_forward;
+               vector forward, _r, _u;
+               MAKE_VECTORS(this.angles, forward, _r, _u);
+               this.movedir = forward;
        }
        if(this.model == "")
        {
index 3f324ba397318c3cfd23ddef2915a07c15e21dae..e77af222bcbad51502f4e6f521e2cd19cbca9d6b 100644 (file)
@@ -19,6 +19,7 @@
 #include <menu/xonotic/demolist.qc>
 #include <menu/xonotic/dialog.qc>
 #include <menu/xonotic/dialog_credits.qc>
+#include <menu/xonotic/dialog_disconnect.qc>
 #include <menu/xonotic/dialog_firstrun.qc>
 #include <menu/xonotic/dialog_hudpanel_ammo.qc>
 #include <menu/xonotic/dialog_hudpanel_centerprint.qc>
index 1b3e09081aab1c6075b26eb94b2e704e2ad6b31a..50eabce95999675614d4700f4fbea7191adbc6b1 100644 (file)
@@ -19,6 +19,7 @@
 #include <menu/xonotic/demolist.qh>
 #include <menu/xonotic/dialog.qh>
 #include <menu/xonotic/dialog_credits.qh>
+#include <menu/xonotic/dialog_disconnect.qc>
 #include <menu/xonotic/dialog_firstrun.qh>
 #include <menu/xonotic/dialog_hudpanel_ammo.qh>
 #include <menu/xonotic/dialog_hudpanel_centerprint.qh>
diff --git a/qcsrc/menu/xonotic/dialog_disconnect.qc b/qcsrc/menu/xonotic/dialog_disconnect.qc
new file mode 100644 (file)
index 0000000..b50f4bd
--- /dev/null
@@ -0,0 +1,25 @@
+#include "dialog_disconnect.qh"
+
+#include "textlabel.qh"
+#include "button.qh"
+
+void Disconnect_Click(entity btn, entity me)
+{
+       localcmd("disconnect");
+       Dialog_Close(btn, me);
+}
+
+void XonoticDisconnectDialog_fill(entity me)
+{
+       entity e;
+       me.TR(me);
+               me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("Are you sure to disconnect from server?")));
+       me.TR(me);
+       me.TR(me);
+               me.TD(me, 1, 1, e = makeXonoticButton_T(_("Yes"), '1 0 0', _("I would disconnect from server...")));
+                       e.onClick = Disconnect_Click;
+                       e.onClickEntity = me;
+               me.TD(me, 1, 1, e = makeXonoticButton_T(_("No"), '0 1 0', _("I would play more!")));
+                       e.onClick = Dialog_Close;
+                       e.onClickEntity = me;
+}
\ No newline at end of file
diff --git a/qcsrc/menu/xonotic/dialog_disconnect.qh b/qcsrc/menu/xonotic/dialog_disconnect.qh
new file mode 100644 (file)
index 0000000..e4ea22b
--- /dev/null
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "dialog.qh"
+CLASS(XonoticDisconnectDialog, XonoticDialog)
+       METHOD(XonoticDisconnectDialog, fill, void(entity));
+       ATTRIB(XonoticDisconnectDialog, title, string, _("Disconnect"));
+       ATTRIB(XonoticDisconnectDialog, tooltip, string, _("Disconnect server"));
+       ATTRIB(XonoticDisconnectDialog, color, vector, SKINCOLOR_DIALOG_QUIT);
+       ATTRIB(XonoticDisconnectDialog, intendedWidth, float, 0.5);
+       ATTRIB(XonoticDisconnectDialog, rows, float, 3);
+       ATTRIB(XonoticDisconnectDialog, colums, float, 2);
+       ATTRIB(XonoticDisconnectDialog, name, string, "Disconnect");
+ENDCLASS(XonoticDisconnectDialog)
\ No newline at end of file
index 1792ec635b41f1e594e3be4fbf6b455980f9d204..c79b124d66659f43e062e39341d5e4125b86b68e 100644 (file)
@@ -82,10 +82,14 @@ void XonoticServerListTab_fill(entity me)
                        e.onClickEntity = slist;
                        slist.infoButton = e;
        me.TR(me);
+       
+               /*
                me.TD(me, 1, 1, e = makeXonoticCommandButton_T(_("Disconnect"), '0 0 0', "disconnect", 0,
                        _("Disconnect from the server")));
                        slist.disconnectButton = e;
-               me.TD(me, 1, me.columns-1, e = makeXonoticButton(_("Join!"), '0 0 0'));
+               */
+
+               me.TD(me, 1, me.columns, e = makeXonoticButton(_("Join!"), '0 0 0'));
                        e.onClick = ServerList_Connect_Click;
                        e.onClickEntity = slist;
                        slist.connectButton = e;
index 20984034db9c8887cf186ace4ba7be84e0e47a6f..dc39346aa61f962f323964e81b05eccec083dc4f 100644 (file)
@@ -11,7 +11,6 @@ void InstantAction_LoadMap(entity btn, entity dummy)
        float pmin = 2, pmax = 16, pstep = 1;
 
        cvar_set("timelimit_override", "10");
-       cvar_set("g_lms_lives_override", "9");
 
        if(random() < 0.4) // 40% are DM
        {
index 602fcc33cccf5f068995d07a558a3ce376e17c18..55f922929fde71fc0b3670ebde078e19ae7d0efc 100644 (file)
 #include "dialog_credits.qh"
 #include "dialog_quit.qh"
 
+#include "dialog_disconnect.qh"
+
+
+
 void MainWindow_draw(entity me)
 {
        SUPER(MainWindow).draw(me);
@@ -58,6 +62,33 @@ void MainWindow_draw(entity me)
                DialogOpenButton_Click_withCoords(NULL, me.dialogToShow, '0 0 0', eX * conwidth + eY * conheight);
                me.dialogToShow = NULL;
        }
+
+       //-------------------------------------
+       // Part of Disconnect Dialog button:
+       // In case of this function is recalling every time, need to use condition of visibility 
+       
+       if (me.disconnectDialogVisibility && !(gamestatus & (GAME_ISSERVER | GAME_CONNECTED))) 
+       {
+               // If gamestate is not "ingame" (and it is a first "frame" of drawing (or dialog is visible)), 
+               // disconnect button is unnecessary, remove it
+               me.removeItem(me.mainNexposee, me.disconnectDialog);
+               me.disconnectDialogVisibility = 0;
+
+       } else if(!me.disconnectDialogVisibility && (gamestatus & (GAME_ISSERVER | GAME_CONNECTED))) {
+               
+               // If gamestate is "ingame" (and dialog is not visible), 
+               // make disconnect button visible
+               entity n, i;
+               n = me.mainNexposee;
+               i = me.disconnectDialog;
+               n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+               n.setNexposee(n, i, '0.5 1.2 0.0', SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y);
+               me.disconnectDialogVisibility = 1;
+       }
+
+       // I haven't found the best solution for making button visible. 
+       // Alpha channel is the worst thing, because dialog with alpha is also clickable
+       //-------------------------------------
 }
 
 void DemoButton_Click(entity me, entity other)
@@ -245,6 +276,7 @@ void MainWindow_configureMainWindow(entity me)
 
        // main dialogs/windows
        me.mainNexposee = n = NEW(XonoticNexposee);
+       
        /*
                if(checkextension("DP_GECKO_SUPPORT"))
                {
@@ -254,6 +286,7 @@ void MainWindow_configureMainWindow(entity me)
                        n.setNexposee(n, i, '0.1 0.1 0', SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y);
                }
        */
+       
                i = NEW(XonoticSingleplayerDialog);
                i.configureDialog(i);
                n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
@@ -275,6 +308,14 @@ void MainWindow_configureMainWindow(entity me)
                n.setNexposee(n, i, SKINPOSITION_DIALOG_CREDITS, SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y);
                n.pullNexposee(n, i, eY * (SKINHEIGHT_TITLE * SKINFONTSIZE_TITLE / conheight));
 
+               //Disconnect dialog at center of screen (between credits and quit)
+               i = NEW(XonoticDisconnectDialog);
+               i.configureDialog(i);
+               n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+               n.setNexposee(n, i, '0.5 1.2 0.0', SKINALPHAS_MAINMENU_x, SKINALPHAS_MAINMENU_y);
+               n.pullNexposee(n, i, eY * (SKINHEIGHT_TITLE * SKINFONTSIZE_TITLE / conheight));
+               me.disconnectDialog = i;
+       
                i = NEW(XonoticQuitDialog);
                i.configureDialog(i);
                n.addItemCentered(n, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
@@ -285,6 +326,7 @@ void MainWindow_configureMainWindow(entity me)
        me.moveItemAfter(me, n, NULL);
 
        me.initializeDialog(me, n);
+       me.disconnectDialogVisibility = 1;
 
        if(cvar_string("_cl_name") == cvar_defstring("_cl_name"))
                me.dialogToShow = me.firstRunDialog;
index 924f145ba7d5f27143029d03417d8042d2b503e6..1e8afa4a39b1b3344ee7c4990247cdec9acd120e 100644 (file)
@@ -24,4 +24,6 @@ CLASS(MainWindow, ModalController)
        ATTRIB(MainWindow, demostartconfirmDialog, entity);
        ATTRIB(MainWindow, demotimeconfirmDialog, entity);
        ATTRIB(MainWindow, resetDialog, entity);
+       ATTRIB(MainWindow, disconnectDialog, entity);
+       ATTRIB(MainWindow, disconnectDialogVisibility, float, 1);
 ENDCLASS(MainWindow)
index 11266b7c2f9e35948574f54fbd3bd9c5b60e1373..021e9765119d7bf70861a5cdccca8d99c1108280 100644 (file)
@@ -542,7 +542,7 @@ void XonoticServerList_draw(entity me)
        else { me.nItems = gethostcachevalue(SLIST_HOSTCACHEVIEWCOUNT); }
 
        me.connectButton.disabled = (me.lockedSelectedItem || (me.nItems == 0 && me.ipAddressBox.text == ""));
-       me.disconnectButton.disabled = (!(gamestatus & (GAME_ISSERVER | GAME_CONNECTED)));
+       //me.disconnectButton.disabled = (!(gamestatus & (GAME_ISSERVER | GAME_CONNECTED)));
        me.infoButton.disabled = (me.lockedSelectedItem || me.nItems == 0 || !owned);
        me.favoriteButton.disabled = (me.lockedSelectedItem || (me.nItems == 0 && me.ipAddressBox.text == ""));
 
index 74f3bd570d5fee88efdcdbab3fbdaa341c2545a6..01b065df78b302d31d160590b7c76489ed19c189 100644 (file)
@@ -52,7 +52,7 @@ CLASS(XonoticServerList, XonoticListBox)
        ATTRIB(XonoticServerList, sortButton4, entity);
        ATTRIB(XonoticServerList, sortButton5, entity);
        ATTRIB(XonoticServerList, connectButton, entity);
-       ATTRIB(XonoticServerList, disconnectButton, entity);
+       //ATTRIB(XonoticServerList, disconnectButton, entity);
        ATTRIB(XonoticServerList, infoButton, entity);
        ATTRIB(XonoticServerList, currentSortOrder, float, 0);
        ATTRIB(XonoticServerList, currentSortField, float, -1);
index 274b8be90b0a22187b319f340943b9e2b6c134f4..a783d72314a7a1c571014ce6b5cbe70d2d0ac440 100644 (file)
@@ -169,6 +169,7 @@ float autocvar_g_maxspeed;
 bool autocvar_g_mirrordamage_onlyweapons;
 
 float autocvar_g_movement_highspeed = 1;
+bool autocvar_g_movement_highspeed_q3_compat = 0;
 string autocvar_g_mutatormsg;
 //float autocvar_g_nick_flood_penalty;
 int autocvar_g_nick_flood_penalty_red;
@@ -290,6 +291,7 @@ string autocvar_sv_defaultplayermodel_pink;
 string autocvar_sv_defaultplayermodel_red;
 string autocvar_sv_defaultplayermodel_yellow;
 int autocvar_sv_defaultplayerskin;
+bool autocvar_sv_doors_always_open;
 bool autocvar_sv_doublejump;
 bool autocvar_sv_eventlog;
 bool autocvar_sv_eventlog_console;
index c666fa94e3f308ff4694ba5e08a938e202b661b5..01352d0e4d94ba4702fdb727a8818dc1e946d02b 100644 (file)
@@ -921,19 +921,33 @@ entity navigation_findnearestwaypoint_withdist_except(entity ent, float walkfrom
        vector pm1 = ent.origin + ent.mins;
        vector pm2 = ent.origin + ent.maxs;
 
-       // do two scans, because box test is cheaper
-       IL_EACH(g_waypoints, it != ent && it != except && !(it.wpflags & (WAYPOINTFLAG_TELEPORT | WAYPOINTFLAG_JUMP)),
+       if (autocvar_g_waypointeditor && !IS_BOT_CLIENT(ent))
        {
-               if(boxesoverlap(pm1, pm2, it.absmin, it.absmax))
+               // this code allows removing waypoints in the air and seeing jumppad/telepport waypoint links
+               // FIXME it causes a bug where a waypoint spawned really close to another one (max 16 qu)
+               // isn't detected as the nearest waypoint
+               IL_EACH(g_waypoints, it != ent && it != except,
                {
-                       if(!autocvar_g_waypointeditor && walkfromwp && !ent.navigation_dynamicgoal)
+                       if (boxesoverlap(pm1, pm2, it.absmin, it.absmax))
+                               return it;
+               });
+       }
+       else
+       {
+               // do two scans, because box test is cheaper
+               IL_EACH(g_waypoints, it != ent && it != except && !(it.wpflags & (WAYPOINTFLAG_TELEPORT | WAYPOINTFLAG_JUMP)),
+               {
+                       if(boxesoverlap(pm1, pm2, it.absmin, it.absmax))
                        {
-                               waypoint_clearlinks(ent); // initialize wpXXmincost fields
-                               navigation_item_addlink(it, ent);
+                               if(walkfromwp && !ent.navigation_dynamicgoal)
+                               {
+                                       waypoint_clearlinks(ent); // initialize wpXXmincost fields
+                                       navigation_item_addlink(it, ent);
+                               }
+                               return it;
                        }
-                       return it;
-               }
-       });
+               });
+       }
 
        vector org = ent.origin;
        if (navigation_testtracewalk)
@@ -1340,7 +1354,7 @@ void navigation_routerating(entity this, entity e, float f, float rangebias)
                        LOG_DEBUG("jetpack ai: required fuel ", ftos(fuel), ", have ", ftos(GetResource(this, RES_FUEL)));
 
                        // enough fuel ?
-                       if(GetResource(this, RES_FUEL) > fuel || (this.items & IT_UNLIMITED_WEAPON_AMMO))
+                       if(GetResource(this, RES_FUEL) > fuel || (this.items & IT_UNLIMITED_AMMO))
                        {
                                // Estimate cost
                                // (as onground costs calculation is mostly based on distances, here we do the same establishing some relationship
index ddc7e47fa6c31386d3ff17c3d9b2d6e0a441ecbc..76e2cdeb8480069230118925719d77d9e105ae5b 100644 (file)
@@ -21,9 +21,11 @@ string campaign_index_var;
 
 float CampaignBailout(string s)
 {
+#if 0
        cvar = cvar_normal;
        cvar_string = cvar_string_normal;
        cvar_set = cvar_set_normal;
+#endif
        cvar_set("g_campaign", "0");
        LOG_INFO("^4campaign initialization failed: ", s);
        if(autocvar__campaign_testrun)
@@ -31,6 +33,7 @@ float CampaignBailout(string s)
        return 1;
 }
 
+#if 0
 string cvar_campaignwrapper_list; // string of format ; var value; var value; var value;
 string cvar_string_campaignwrapper(string theCvar)
 {
@@ -57,6 +60,7 @@ void cvar_set_campaignwrapper(string theCvar, string theValue)
        strunzone(s);
        //print(cvar_campaignwrapper_list, "\n");
 }
+#endif
 
 float Campaign_Invalid()
 {
@@ -104,16 +108,36 @@ void CampaignPreInit()
        cvar_set("sv_public", "0");
        cvar_set("pausable", "1");
 
+#if 0
        cvar_campaignwrapper_list = strzone(strcat("; ", campaign_mutators[0], "; "));
+#else
+       string cvar_campaignwrapper_list = strcat("; ", campaign_mutators[0], "; ");
+       int argc = tokenizebyseparator(cvar_campaignwrapper_list, "; ");
+       if(argc > 0)
+       {
+               for(int j = 0; j < argc; ++j)
+               {
+                       string arg = argv(j);
+                       if(arg == "") continue;
+                       _MapInfo_Parse_Settemp(mapname, MAPINFO_SETTEMP_ACL_USER, 0, arg, 0); // no recursion!
+               }
+       }
+#endif
 
+#if 0
        cvar = cvar_campaignwrapper;
        cvar_string = cvar_string_campaignwrapper;
        cvar_set = cvar_set_campaignwrapper;
-
        cvar_set("g_campaign", "1");
        cvar_set("g_dm", "0");
        cvar_set("skill", ftos(baseskill));
        cvar_set("bot_number", ftos(campaign_bots[0]));
+#else
+       cvar_settemp("g_campaign", "1");
+       cvar_settemp("g_dm", "0");
+       cvar_settemp("skill", ftos(baseskill));
+       cvar_settemp("bot_number", ftos(campaign_bots[0]));
+#endif
        MapInfo_SwitchGameType(MapInfo_Type_FromString(campaign_gametype[0]));
 
        // copy sv_gravity cvar, as the engine needs it too (sorry, this will mess
index 0034c2dd9ee3b687a0b600eee0b850cc056dfb89..98616a76341f76ac901e838fdd7b81cb39478911 100644 (file)
@@ -1617,7 +1617,7 @@ void player_regen(entity this)
                        this.event_damage(this, this, this, 1, DEATH_ROT.m_id, DMG_NOWEP, this.origin, '0 0 0');
        }
 
-       if (!(this.items & IT_UNLIMITED_WEAPON_AMMO))
+       if (!(this.items & IT_UNLIMITED_AMMO))
        {
                float minf, maxf, limitf;
 
index 4606638f621ac1240078f0149b2e27ef5cb17c78..6928957d6d812e6f15511d2b82e421d8f0c7f877 100644 (file)
@@ -768,6 +768,12 @@ void ClientCommand_voice(entity caller, int request, int argc, string command)
                                        // we still allow them to see warnings if it's invalid, so a dead player can find out the sounds in peace
                                        return;
                                }
+                               if (IS_SPEC(caller) || IS_OBSERVER(caller))
+                               {
+                                       // observers/spectators have no player model of their own to play taunts from
+                                       // again, allow them to see warnings
+                                       return;
+                               }
                                string msg = "";
                                if (argc >= 3)
                                        msg = substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2));
index a5cc7383404d0f3bc4d179f2be0e1ad4631dfa49..b611ab2665896975ab0b4ce15c24da2480f61190 100644 (file)
@@ -711,7 +711,9 @@ int VoteCommand_parse(entity caller, string vote_command, string vote_list, floa
                        break;
                }
 
-               case "nextmap": // TODO: replicate the old behaviour of being able to vote for maps from different modes on multimode servers (possibly support it in gotomap too), maybe fallback instead of aborting if map name is invalid?
+               // TODO: replicate the old behaviour of being able to vote for maps from different modes on multimode servers (possibly support it in gotomap too)
+               // maybe fallback instead of aborting if map name is invalid?
+               case "nextmap":
                {
                        vote_command = ValidateMap(argv(startpos + 1), caller);
                        if (!vote_command)  return -1;
@@ -721,6 +723,21 @@ int VoteCommand_parse(entity caller, string vote_command, string vote_list, floa
                        break;
                }
 
+               case "timelimit": // include restrictions on the maximum votable time limit
+               {
+                       float timelimit_vote = stof(argv(startpos + 1));
+                       if(timelimit_vote > autocvar_timelimit_max || timelimit_vote < autocvar_timelimit_min)
+                       {
+                               print_to(caller, strcat("Invalid timelimit vote, accepted values are between ", ftos(autocvar_timelimit_min), " and ", ftos(autocvar_timelimit_max), "."));
+                               return -1;
+                       }
+                       timelimit_vote = bound(autocvar_timelimit_min, timelimit_vote, autocvar_timelimit_max);
+                       vote_parsed_command = strcat("timelimit ", ftos(timelimit_vote));
+                       vote_parsed_display = strzone(strcat("^1", vote_parsed_command));
+
+                       break;
+               }
+
                case "restart":
                {
                        // add a delay so that vote result can be seen and announcer can be heard
index 30ed368f3a8ecbf4592a9d62b13e8bc563c5dbe2..0c44a95f17bf5385372fb106e1dd4e37114930ee 100644 (file)
@@ -360,6 +360,7 @@ void cvar_changes_init()
                BADCVAR("sv_damagetext");
                BADCVAR("sv_db_saveasdump");
                BADCVAR("sv_intermission_cdtrack");
+               BADCVAR("sv_mapchange_delay");
                BADCVAR("sv_minigames");
                BADCVAR("sv_namechangetimer");
                BADCVAR("sv_precacheplayermodels");
index 026e1d7ceb9e9fa190633702e12f819a09526f49..ded47a6387f97920ce32f2fa41851a7b8ec32dea 100644 (file)
@@ -715,7 +715,7 @@ void readplayerstartcvars()
        {
                g_weapon_stay = 0; // incompatible
                start_weapons = g_weaponarena_weapons;
-               start_items |= IT_UNLIMITED_AMMO;
+               start_items |= IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS;
        }
        else
        {
@@ -737,7 +737,7 @@ void readplayerstartcvars()
        if(!cvar("g_use_ammunition"))
                start_items |= IT_UNLIMITED_AMMO;
 
-       if(start_items & IT_UNLIMITED_WEAPON_AMMO)
+       if(start_items & IT_UNLIMITED_AMMO)
        {
                start_ammo_shells = 999;
                start_ammo_nails = 999;
index 730c92884f75b09ddf7ff1cf890a610272ad084e..5aa81a2a73b0e9ad3fae1304237f863e71c9a2ed 100644 (file)
@@ -119,9 +119,10 @@ void relocate_spawnpoint(entity this)
     if (autocvar_r_showbboxes)
     {
         // show where spawnpoints point at too
-        makevectors(this.angles);
+        vector forward, right, up;
+        MAKE_VECTORS(this.angles, forward, right, up);
         entity e = new(info_player_foo);
-        setorigin(e, this.origin + v_forward * 24);
+        setorigin(e, this.origin + forward * 24);
         setsize(e, '-8 -8 -8', '8 8 8');
         e.solid = SOLID_TRIGGER;
     }
index 7f9c6ad0d76c379481cb3613fe3b322b0d7ecdff..f1866eab089311a0ce2c2a052d6b9b3fbaf00031 100644 (file)
@@ -70,7 +70,7 @@ bool client_hasweapon(entity this, Weapon wpn, .entity weaponentity, float andam
        {
                if (andammo)
                {
-                       if(this.items & IT_UNLIMITED_WEAPON_AMMO)
+                       if(this.items & IT_UNLIMITED_AMMO)
                        {
                                f = 1;
                        }
index 06bebeba2746f09b57e3cc37e6f0c4c95075f5c5..6209710b6dea85697a40639ebc18c2d7f47d509b 100644 (file)
@@ -51,14 +51,14 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect
                WarpZone_TraceLine(ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + s_forward * range, MOVE_NOMONSTERS, ent);
        ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
 
-       vector vf, vr, vu;
-       vf = v_forward;
-       vr = v_right;
-       vu = v_up;
+       vector forward, right, up;
+       forward = v_forward;
+       right = v_right;
+       up = v_up;
        w_shotend = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos); // warpzone support
-       v_forward = vf;
-       v_right = vr;
-       v_up = vu;
+       v_forward = forward;
+       v_right = right;
+       v_up = up;
 
        // un-adjust trueaim if shotend is too close
        if(vdist(w_shotend - (ent.origin + ent.view_ofs), <, autocvar_g_trueaim_minrange))
@@ -69,27 +69,27 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vect
                accuracy_add(ent, wep, maxdamage, 0);
 
        if(IS_PLAYER(ent))
-               W_HitPlotAnalysis(ent, wep, v_forward, v_right, v_up);
+               W_HitPlotAnalysis(ent, wep, forward, right, up);
 
        vector md = ent.(weaponentity).movedir;
        vector vecs = ((md.x > 0) ? md : '0 0 0');
 
        // TODO this is broken - see 637056bea7bf7f5c9c0fc6113e94731a2767476 for an attempted fix
        // which fixes issue #1957 but causes #2129
-       vector dv = v_right * -vecs.y + v_up * vecs.z;
+       vector dv = right * -vecs.y + up * vecs.z;
        w_shotorg = ent.origin + ent.view_ofs + dv;
 
        // now move the shotorg forward as much as requested if possible
        if(antilag)
        {
                if(CS(ent).antilag_debug)
-                       tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + v_forward * (vecs.x + nudge), MOVE_NORMAL, ent, CS(ent).antilag_debug);
+                       tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + forward * (vecs.x + nudge), MOVE_NORMAL, ent, CS(ent).antilag_debug);
                else
-                       tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + v_forward * (vecs.x + nudge), MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
+                       tracebox_antilag(ent, w_shotorg, mi, ma, w_shotorg + forward * (vecs.x + nudge), MOVE_NORMAL, ent, ANTILAG_LATENCY(ent));
        }
        else
-               tracebox(w_shotorg, mi, ma, w_shotorg + v_forward * (vecs.x + nudge), MOVE_NORMAL, ent);
-       w_shotorg = trace_endpos - v_forward * nudge;
+               tracebox(w_shotorg, mi, ma, w_shotorg + forward * (vecs.x + nudge), MOVE_NORMAL, ent);
+       w_shotorg = trace_endpos - forward * nudge;
        // calculate the shotdir from the chosen shotorg
        if(W_DualWielding(ent))
                w_shotdir = s_forward;
index f1655b632269bb79a4c6b4ae732b2886f928c77d..6e74738c738eaf5a1bbabcf155bef94c74416ad2 100644 (file)
@@ -224,7 +224,7 @@ void w_ready(Weapon thiswep, entity actor, .entity weaponentity, int fire)
 .float prevwarntime;
 bool weapon_prepareattack_checkammo(Weapon thiswep, entity actor, bool secondary, .entity weaponentity)
 {
-       if ((actor.items & IT_UNLIMITED_WEAPON_AMMO)) return true;
+       if ((actor.items & IT_UNLIMITED_AMMO)) return true;
        bool ammo = false;
        if (secondary) ammo = thiswep.wr_checkammo2(thiswep, actor, weaponentity);
        else ammo = thiswep.wr_checkammo1(thiswep, actor, weaponentity);
@@ -374,10 +374,6 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(
                restartanim = fr != WFRAME_IDLE;
        }
 
-       vector of = v_forward;
-       vector or = v_right;
-       vector ou = v_up;
-
        vector a = '0 0 0';
     this.wframe = fr;
     if (fr == WFRAME_IDLE) a = this.anim_idle;
@@ -387,10 +383,6 @@ void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(
         a = this.anim_reload;
     a.z *= g_weaponratefactor;
 
-       v_forward = of;
-       v_right = or;
-       v_up = ou;
-
        if (this.weapon_think == w_ready && func != w_ready && this.state == WS_RAISE) backtrace(
                        "Tried to override initial weapon think function - should this really happen?");
 
@@ -508,10 +500,8 @@ void W_WeaponFrame(Player actor, .entity weaponentity)
                return;
        }
 
-       makevectors(actor.v_angle);
-       vector fo = v_forward;  // save them in case the weapon think functions change it
-       vector ri = v_right;
-       vector up = v_up;
+       vector fo, ri, up;
+       MAKE_VECTORS(actor.v_angle, fo, ri, up);
 
        // Change weapon
        if (this.m_weapon != this.m_switchweapon)
@@ -688,7 +678,7 @@ void W_AttachToShotorg(entity actor, .entity weaponentity, entity flash, vector
 void W_DecreaseAmmo(Weapon wep, entity actor, float ammo_use, .entity weaponentity)
 {
        if (MUTATOR_CALLHOOK(W_DecreaseAmmo, actor, actor.(weaponentity), ammo_use)) return;
-       if ((actor.items & IT_UNLIMITED_WEAPON_AMMO) && !wep.reloading_ammo) return;
+       if ((actor.items & IT_UNLIMITED_AMMO) && !wep.reloading_ammo) return;
 
        ammo_use = M_ARGV(2, float);
 
@@ -735,7 +725,7 @@ void W_ReloadedAndReady(Weapon thiswep, entity actor, .entity weaponentity, int
        w_ent.clip_load = w_ent.old_clip_load;  // restore the ammo counter, in case we still had ammo in the weapon before reloading
 
        // if the gun uses no ammo, max out weapon load, else decrease ammo as we increase weapon load
-       if (!w_ent.reload_ammo_min || (actor.items & IT_UNLIMITED_WEAPON_AMMO) || wpn.ammo_type == RES_NONE)
+       if (!w_ent.reload_ammo_min || (actor.items & IT_UNLIMITED_AMMO) || wpn.ammo_type == RES_NONE)
        {
                w_ent.clip_load = w_ent.reload_ammo_amount;
        }
@@ -791,7 +781,7 @@ void W_Reload(entity actor, .entity weaponentity, float sent_ammo_min, Sound sen
        {
                if (!GetResource(actor, e.ammo_type) && this.reload_ammo_min)
                {
-                       if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO))
+                       if (!(actor.items & IT_UNLIMITED_AMMO))
                        {
                                if (IS_REAL_CLIENT(actor) && actor.reload_complain < time)
                                {
index e3d1eb01368df1c714c55d7264eda99e89ff8bbd..7a7ff17b6d554cbe6451ae2dda773ec81b017088 100755 (executable)
@@ -38,6 +38,11 @@ QCCDEFS="${QCCDEFS[@]}"
 
 declare -a QCCFLAGS=(
     -std=gmqcc
+    # Without -O3, GMQCC thinks some variables are used uninitialized if the initialization is done inside an `if (1)` block
+    # (which is created by e.g. BEGIN_MACRO) which would cause the compilation units test to fail.
+    # There doesn't appear to be any measurable increase in compile time
+    # and it allows us to get rid of some explicit initializations which are just useless noise.
+    -O3
     -Wall -Werror
     -futf8
     -freturn-assignments
index 865e6e592ca48c037932fa643ec80e9dd1b20f83..dfc375bb5a984fab52d12b4720c62b2e7e70c225 100755 (executable)
@@ -20,7 +20,7 @@ function qpp() {
         server) DEFS="-DGAMEQC -DSVQC"
         ;;
     esac
-    >&2 echo + ${CPP} "${@:3}" ${DEFS} "${IN}"
+    #>&2 echo + ${CPP} "${@:3}" ${DEFS} "${IN}"
     set +e
     # additional information
     ${CPP} "${@:3}" ${DEFS} \
@@ -36,7 +36,7 @@ function qpp() {
 }
 
 function qcc() {
-    >&2 echo + $(basename ${QCC}) $@
+    #>&2 echo + $(basename ${QCC}) $@
     # FIXME: relative compiler path is too deep
     (cd tools && ${QCC} "$@")
 }
index a0cc24b7b991b2f32c025e75591c20e5f5f75e4d..668d10484b461c3503188e346606b2827482fdba 100644 (file)
@@ -12,17 +12,46 @@ g_shootfromcenter 1 // hit where you point at with the crosshair (almost so, no
 g_balance_kill_antispam 0
 g_forced_respawn 1
 // g_playerclip_collisions 0 // do not check playerclips
-g_powerups 0  // set to -1 or patch xonotic
+g_powerups 0
 g_spawnpoints_auto_move_out_of_solid 1
 g_start_delay 3
-g_use_ammunition 0 "if set to 0 all weapons have unlimited ammunition"
-g_weapon_stay 1 "1: ghost weapons can be picked up too but give no ammo, 2: ghost weapons refill ammo to one pickup size, thrown guns have no ammo"
+g_use_ammunition 0
+g_weapon_stay 1
 teamplay_mode 2 // friendly fire and self damage
 sv_vote_nospectators 1
 timelimit_override 20
-g_buffs_cooldown_respawn 0.1
+
+// general buff settings
+g_buffs_cooldown_activate 0
+g_buffs_cooldown_respawn 0
 g_buffs_randomize 0
 
+// disabled buffs
+g_buffs_ammo 0
+g_buffs_resistance 0
+g_buffs_medic 0
+g_buffs_vengeance 0
+g_buffs_bash 0
+g_buffs_disability 0
+g_buffs_vampire 0
+g_buffs_jump 0
+g_buffs_invisible 0
+g_buffs_inferno 0
+g_buffs_swapper 0
+g_buffs_magnet 0
+g_buffs_luck 0
+g_buffs_flight 0
+
+// speed buff (q3 haste replacement)
+g_movement_highspeed_q3_compat 1
+g_buffs_speed 1
+g_buffs_speed_time 30
+g_buffs_speed_speed 1.3  // q3 haste lasts 30 seconds
+g_buffs_speed_rate 0.7692307692   // 1/1.3
+g_buffs_speed_weaponspeed 1  // do not increase projectile speed
+g_buffs_speed_damage_take 1
+g_buffs_speed_regen 1.2
+
 // game mode settings
 g_cts_finish_kill_delay 2
 g_cts_selfdamage 0
index f74c1e9b0249467f0a66aec39360c27aec0ea326..cb39b2a10ce1a16c1b5cb554be256a42e01c52f5 100644 (file)
@@ -10,8 +10,6 @@ if_dedicated exec help-overkill.cfg
 
 g_overkill 1
 
-g_use_ammunition 0
-
 // hack - eventually, we should be able to choose overkill models in menu like for vanilla
 sv_defaultcharacter 1
 sv_defaultplayermodel "models/ok_player/okrobot1.dpm models/ok_player/okrobot2.dpm models/ok_player/okrobot3.dpm models/ok_player/okrobot4.dpm models/ok_player/okmale1.dpm models/ok_player/okmale2.dpm models/ok_player/okmale3.dpm models/ok_player/okmale4.dpm"
index dfa3c0c57c26f8efe0862618918f653612dbe750..a6494cc088a0551d2856b8cfc8c4c3539cc49657 100644 (file)
@@ -854,7 +854,7 @@ seta cl_ghost_items 0.45 "enable ghosted items (when between 0 and 1, overrides
 seta cl_ghost_items_color "-1 -1 -1" "color of ghosted items (colormod format: 0 0 0 leaves the color unchanged, negative values allowed)"
 seta cl_simple_items 0 "enable simple items (if server allows)"
 set cl_simpleitems_postfix "_luma" "posfix to add fo model name when simple items are enabled"
-set cl_fullbright_items 0 "enable fullbright items (if server allows, controlled by g_fullbrightitems)"
+set cl_fullbright_items 0 "enable fullbright items (if server allows, controlled by g_fullbrightitems) - items are more visible in shadows"
 set cl_weapon_stay_color "2 0.5 0.5" "Color of picked up weapons when g_weapon_stay > 0 (colormod format: 0 0 0 leaves the color unchanged, negative values allowed)"
 set cl_weapon_stay_alpha 0.75 "Alpha of picked up weapons when g_weapon_stay > 0"
 
index 89a04782f8828ccf4329fe30a10a48121bfdf864..e66f051cd848ab7ae05a5544adc6c3f90e9b9cea 100644 (file)
@@ -10,42 +10,42 @@ set sv_autotaunt 1 "allow autotaunts on the server"
 
 // server settings
 hostname "Xonotic $g_xonoticversion Server"
-set sv_mapchange_delay 5
+set sv_mapchange_delay 5 "delay by this many seconds after the match ends before showing selection screen or changing maps"
 set minplayers 0 "fill server with bots to reach this number of players in teamless games (if bot_number is not enough)"
 set minplayers_per_team 0 "fill server with bots to reach this number of players per team (if bot_number is not enough)"
 
 // restart server if all players hit "ready"-button
 set sv_ready_restart 0 "allow a map to be restarted once all players pressed the \"ready\" button"
-set sv_ready_restart_after_countdown 0 "reset players and map items after the countdown ended, instead of at the beginning of the countdown"
-set sv_ready_restart_repeatable 0      "allows the players to restart the game as often as needed"
+set sv_ready_restart_after_countdown 0 "reset players and map items after the countdown ended, instead of at the beginning of the countdown"
+set sv_ready_restart_repeatable 0 "allows the players to restart the game as often as needed"
 
 //nifreks lockonrestart feature, used in team-based game modes, if set to 1 and all players readied up no other player can then join the game anymore, useful to block spectators from joining
 set teamplay_lockonrestart 0 "lock teams once all players readied up and the game restarted (no new players can join after restart unless using the server-command unlockteams)"
 
-set g_maxplayers 0     "maximum number of players allowed to play at the same time, set to 0 to allow all players to join the game"
-set g_maxplayers_spectator_blocktime 5 "if the players voted for the \"nospectators\" command, this setting defines the number of seconds a observer/spectator has time to join the game before he gets kicked"
+set g_maxplayers 0 "maximum number of players allowed to play at the same time, set to 0 to allow all players to join the game"
+set g_maxplayers_spectator_blocktime 5 "if the players voted for the \"nospectators\" command, this setting defines the number of seconds a observer/spectator has time to join the game before he gets kicked"
 
 // tournament mod
-set g_warmup 0 "split the game into a warmup- and match-stage"
-set g_warmup_limit 180 "limit warmup-stage to this time (in seconds); if set to -1 the warmup-stage is not affected by any timelimit, if set to 0 the usual timelimit also affects warmup-stage"
-set g_warmup_allow_timeout 0   "allow calling timeouts in the warmup-stage (if sv_timeout is set to 1)"
-set g_warmup_allguns 1 "provide more weapons on start while in warmup: 0 = normal start weapons, 1 = all guns available on the map, 2 = all normal weapons"
+set g_warmup 0 "split the game into a warmup- and match-stage"
+set g_warmup_limit 180 "limit warmup-stage to this time (in seconds); if set to -1 the warmup-stage is not affected by any timelimit, if set to 0 the usual timelimit also affects warmup-stage"
+set g_warmup_allow_timeout 0 "allow calling timeouts in the warmup-stage (if sv_timeout is set to 1)"
+set g_warmup_allguns 1 "provide more weapons on start while in warmup: 0 = normal start weapons, 1 = all guns available on the map, 2 = all normal weapons"
 set g_warmup_majority_factor 0.8 "minimum percentage of players ready needed for warmup to end"
 
 alias sv_hook_warmupend
 
-set g_chat_nospectators 0      "if 0 spec/observer chat is always visible to the player, if 1 it is never visible to players, if 2 it is only visible to players during warmup stage"
-set sv_vote_nospectators 0     "only players can call a vote (thus spectators and observers can't call a vote): 0 = all people can vote, 1 = spectators can vote in warmup stage, 2 = only players can vote (no exceptions)."
+set g_chat_nospectators 0 "if 0 spec/observer chat is always visible to the player, if 1 it is never visible to players, if 2 it is only visible to players during warmup stage"
+set sv_vote_nospectators 0 "only players can call a vote (thus spectators and observers can't call a vote): 0 = all people can vote, 1 = spectators can vote in warmup stage, 2 = only players can vote (no exceptions)."
 
 alias g_tourney "g_tourney_$1"
 alias g_tourney_1 "g_warmup 1; g_chat_nospectators 2; sv_vote_nospectators 1"
 alias g_tourney_0 "g_warmup 0; g_chat_nospectators 0; sv_vote_nospectators 0"
 
-set sv_timeout 0       "allow a player to call a timeout, this will pause the game for some time"
-set sv_timeout_length 120      "how long the game will be paused at max, in seconds"
-set sv_timeout_number 2        "how many timeouts one player is allowed to call (gets reset after a restart)"
-set sv_timeout_leadtime 4      "how long the players will be informed that a timeout was called before it starts, in seconds"
-set sv_timeout_resumetime 3    "how long the remaining timeout-time will be after a player called the timein command"
+set sv_timeout 0 "allow a player to call a timeout, this will pause the game for some time"
+set sv_timeout_length 120 "how long the game will be paused at max, in seconds"
+set sv_timeout_number 2 "how many timeouts one player is allowed to call (gets reset after a restart)"
+set sv_timeout_leadtime 4 "how long the players will be informed that a timeout was called before it starts, in seconds"
+set sv_timeout_resumetime 3 "how long the remaining timeout-time will be after a player called the timein command"
 
 set g_allow_oldvortexbeam 1 "If enabled, clients are allowed to use old v2.3 Vortex beam"
 
@@ -92,7 +92,7 @@ set sv_defaultcharacter 0 "master switch, if set to 1 the further configuration
 set sv_defaultcharacterskin 0 "if set to 1 the further configuration for replacing all skins is taken from the sv_defaultplayerskin variables"
 set sv_defaultplayermodel "models/player/erebus.iqm" "default model selection, only works if sv_defaultcharacter is set to 1; you may append a :<skinnumber> suffix to model names; you can specify multiple, separated by space, and a random one will be chosen"
 set sv_defaultplayerskin 0 "each model has 1 or more skins (combination of model and skin = character), set which skin of the model you wish the default character to have, only works if sv_defaultcharacter is set to 1; can be overridden by :<skinnumber> suffix in sv_defaultplayermodel"
-set sv_defaultplayermodel_red ""       "\"\" means see sv_defaultplayermodel"
+set sv_defaultplayermodel_red "" "\"\" means see sv_defaultplayermodel"
 set sv_defaultplayerskin_red 0 "skin to use on the red team, set to 0 to instead use sv_defaultplayerskin"
 set sv_defaultplayermodel_blue "" "\"\" means see sv_defaultplayermodel"
 set sv_defaultplayerskin_blue 0 "skin to use on the blue team, set to 0 to instead use sv_defaultplayerskin"
@@ -100,7 +100,7 @@ set sv_defaultplayermodel_yellow "" "\"\" means see sv_defaultplayermodel"
 set sv_defaultplayerskin_yellow 0 "skin to use on the yellow team, set to 0 to instead use sv_defaultplayerskin"
 set sv_defaultplayermodel_pink "" "\"\" means see sv_defaultplayermodel"
 set sv_defaultplayerskin_pink 0 "skin to use on the pink team, set to 0 to instead use sv_defaultplayerskin"
-set sv_defaultplayercolors ""  "set to 16*shirt+pants to force a color, note: it does NOT depend on defaultcharacter! Set to \"\" to disable"
+set sv_defaultplayercolors "" "set to 16*shirt+pants to force a color, note: it does NOT depend on defaultcharacter! Set to \"\" to disable"
 set sv_autoscreenshot 0 "if set to 1, the server forces all clients to create a local screenshot once the map ended"
 net_messagetimeout 30
 net_connecttimeout 30
@@ -109,12 +109,13 @@ sv_jumpstep 1 // step up stairs while jumping, makes it easier to reach ledges
 set sv_shownames_cull_distance 2500 "distance after which to not send origin/health/armor of another player"
 
 set bot_config_file bots.txt "Name and path of the bot configuration file"
-set bot_number 0       "Minimum number of bots"
-set bot_usemodelnames 0        "Use player model names for bot names"
-set bot_nofire 0       "When set, bots never fire. Mainly for testing in g_waypointeditor mode"
-set bot_prefix [BOT]   "Prefix in front of the bot names"
-set bot_suffix ""      "Suffix behind the bot names"
-set skill_auto 0       "when 1, \"skill\" gets adjusted to match the best player on the map"
+set bot_number 0 "Minimum number of bots"
+set bot_usemodelnames 0 "Use player model names for bot names"
+set bot_nofire 0 "When set, bots never fire. Mainly for testing in g_waypointeditor mode"
+set bot_prefix [BOT] "Prefix in front of the bot names"
+set bot_suffix "" "Suffix behind the bot names"
+skill 8
+set skill_auto 0 "when 1, \"skill\" gets adjusted to match the best player on the map"
 set bot_debug_tracewalk 0 "Enable visual indicators for short-term navigation. Green: Goal Reached / Yellow: Obstacle found / Red: Unsolvable obstacle found"
 set bot_debug_goalstack 0 "Visualize the current path that each bot is following. Use with as few bots as possible."
 set bot_wander_enable 1 "Have bots wander around if they are unable to reach any useful goal. Disable only for debugging purposes."
@@ -129,7 +130,7 @@ set bot_ai_dodgeupdateinterval 0.2 "How often scan for items to dodge. Currently
 set bot_ai_chooseweaponinterval 0.5 "How often the best weapon according to the situation will be chosen"
 set bot_ai_dangerdetectioninterval 0.25 "How often scan for waypoints with dangers near"
 set bot_ai_dangerdetectionupdates 64 "How many waypoints will be considered for danger detection"
-set bot_ai_aimskill_blendrate 2        "How much correction will be applied to the aiming angle"
+set bot_ai_aimskill_blendrate 2 "How much correction will be applied to the aiming angle"
 set bot_ai_aimskill_fixedrate 15 "Distance based scale from which correction will be applied to the aiming angle"
 set bot_ai_aimskill_firetolerance 0 "enable fire tolerance"
 set bot_ai_aimskill_firetolerance_distdegrees 100 "Rate at which the aiming angle is updated, scales by skill"
@@ -140,15 +141,15 @@ set bot_ai_keyboard_distance 250 "Keyboard emulation is disabled after this dist
 set bot_ai_keyboard_threshold 0.57
 set bot_ai_aimskill_offset 0.3 "Amount of error induced to the bots aim"
 set bot_ai_aimskill_think 1 "Aiming velocity. Use values below 1 for slower aiming"
-set bot_ai_custom_weapon_priority_distances "300 850"  "Define close and far distances in any order. Based on the distance to the enemy bots will choose different weapons"
-set bot_ai_custom_weapon_priority_far   "vaporizer oknex vortex rifle electro devastator mortar hagar hlac crylink blaster okmachinegun machinegun fireball seeker okshotgun shotgun shockwave tuba minelayer" "Desired weapons for far distances ordered by priority"
-set bot_ai_custom_weapon_priority_mid   "vaporizer devastator oknex vortex fireball seeker mortar electro okmachinegun machinegun arc crylink hlac hagar okshotgun shotgun shockwave blaster rifle tuba minelayer"     "Desired weapons for middle distances ordered by priority"
-set bot_ai_custom_weapon_priority_close "vaporizer oknex vortex okshotgun shotgun shockwave okmachinegun machinegun arc hlac tuba seeker hagar crylink mortar electro devastator blaster fireball rifle minelayer"     "Desired weapons for close distances ordered by priority"
-set bot_ai_weapon_combo 1      "Enable bots to do weapon combos"
-set bot_ai_weapon_combo_threshold 0.4  "Try to make a combo N seconds after the last attack"
-set bot_ai_friends_aware_pickup_radius "500"   "Bots will not pickup items if a team mate is this distance near the item"
-set bot_ai_ignoregoal_timeout 3        "Ignore goals making bots to get stuck in front of a wall for N seconds"
-set bot_ai_bunnyhop_skilloffset 7      "Bots with skill equal or greater than this value will perform the \"bunnyhop\" technique"
+set bot_ai_custom_weapon_priority_distances "300 850" "Define close and far distances in any order. Based on the distance to the enemy bots will choose different weapons"
+set bot_ai_custom_weapon_priority_far   "vaporizer oknex vortex rifle electro devastator mortar hagar hlac crylink blaster okmachinegun machinegun fireball seeker okshotgun shotgun shockwave tuba minelayer" "Desired weapons for far distances ordered by priority"
+set bot_ai_custom_weapon_priority_mid   "vaporizer devastator oknex vortex fireball seeker mortar electro okmachinegun machinegun arc crylink hlac hagar okshotgun shotgun shockwave blaster rifle tuba minelayer" "Desired weapons for middle distances ordered by priority"
+set bot_ai_custom_weapon_priority_close "vaporizer oknex vortex okshotgun shotgun shockwave okmachinegun machinegun arc hlac tuba seeker hagar crylink mortar electro devastator blaster fireball rifle minelayer" "Desired weapons for close distances ordered by priority"
+set bot_ai_weapon_combo 1 "Enable bots to do weapon combos"
+set bot_ai_weapon_combo_threshold 0.4 "Try to make a combo N seconds after the last attack"
+set bot_ai_friends_aware_pickup_radius "500" "Bots will not pickup items if a team mate is this distance near the item"
+set bot_ai_ignoregoal_timeout 3 "Ignore goals making bots to get stuck in front of a wall for N seconds"
+set bot_ai_bunnyhop_skilloffset 7 "Bots with skill equal or greater than this value will perform the \"bunnyhop\" technique"
 set bot_ai_bunnyhop_startdistance 200 "Run to goals located further than this distance"
 set bot_ai_bunnyhop_stopdistance 300 "Stop jumping after reaching this distance to the goal"
 set bot_ai_bunnyhop_firstjumpdelay 0.2 "Start running to the goal only if it was seen for more than N seconds"
@@ -177,43 +178,43 @@ set g_waypointeditor_symmetrical_allowload 1 "Allow loading symmetry settings fr
 set g_waypointeditor_symmetrical_origin "0 0" "Custom origin of symmetry (x y)"
 set g_waypointeditor_symmetrical_order 0 "if >= 2 apply rotational symmetry (around origin of symmetry) of this order, otherwise apply autodetected order of symmetry"
 set g_waypointeditor_symmetrical_axis "0 0" "Custom axis of symmetry (m q parameters of y = mx + q)"
-set bot_ignore_bots 0  "When set, bots don't shoot at other bots"
-set bot_join_empty 0   "When set, bots also play if no player has joined the server"
-set bot_vs_human 0     "Bots and humans play in different teams when set. positive values to make an all-bot blue team, set to negative values to make an all-bot red team, the absolute value is the ratio bots vs humans (1 for equal count). Changes will be correctly applied only from the next game"
+set bot_ignore_bots 0 "When set, bots don't shoot at other bots"
+set bot_join_empty 0 "When set, bots also play if no player has joined the server"
+set bot_vs_human 0 "Bots and humans play in different teams when set. positive values to make an all-bot blue team, set to negative values to make an all-bot red team, the absolute value is the ratio bots vs humans (1 for equal count). Changes will be correctly applied only from the next game"
 
 set g_spawnshieldtime 1 "number of seconds you are invincible after you spawned, this shield is lost after you fire"
 set g_spawnshield_blockdamage 1 "how much spawn shield protects you from damage (1 = full protection)"
-set g_antilag 2        "AntiLag (0 = no AntiLag, 1 = verified client side hit scan, 2 = server side hit scan in the past)"
+set g_antilag 2 "AntiLag (0 = no AntiLag, 1 = verified client side hit scan, 2 = server side hit scan in the past)"
 set g_antilag_nudge 0 "don't touch"
 set g_shootfromeye 0 "shots are fired from your eye/crosshair; visual gun position can still be influenced by cl_gunalign 1 and 2"
 set g_shootfromcenter 0 "weapon gets moved to the center, shots still come from the barrel of your weapon; visual gun position can still be influenced by cl_gunalign 1 and 2"
 set g_shootfromfixedorigin "" "if set to a string like 0 y z, the gun is moved to the given y and z coordinates. If set to a string like x y z, the whole shot origin is used"
 set g_pinata 0 "if set to 1 you will not only drop your current weapon when you are killed, but you will drop all weapons that you possessed"
-set g_weapon_stay 0 "1: ghost weapons can be picked up too but give no ammo, 2: ghost weapons refill ammo to one pickup size, thrown guns have no ammo"
+set g_weapon_stay 0 "1: ghost weapons can be picked up but give no ammo, thrown guns have ammo 2: ghost weapons can be picked up and refill ammo to one pickup size, thrown guns have no ammo (to prevent infinite ammo abuse)"
 set g_weapon_throwable 1 "if set to 1, weapons can be dropped"
 set g_powerups -1 "if set to 0 the strength and shield (invincibility) will not spawn on the map, if 1 they will spawn in all game modes, -1 is game mode default"
-set g_use_ammunition 1 "if set to 0 all weapons have unlimited ammunition"
+set g_use_ammunition 1 "if set to 0 all weapons have unlimited ammo"
 set g_pickup_items -1 "if set to 0 all items (health, armor, ammo, weapons...) are removed from the map, if 1 they are forced to spawn"
 set g_pickup_respawntime_scaling_reciprocal 0 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `reciprocal` (with `offset` and `linear` set to 0) can be used to achieve a constant number of items spawned *per player*"
 set g_pickup_respawntime_scaling_offset 0 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `offset` offsets the curve left or right - the results are not intuitive and I recommend plotting the respawn time and the number of items per player to see what's happening"
 set g_pickup_respawntime_scaling_linear 1 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `linear` can be used to simply scale the respawn time linearly"
-set g_weaponarena "0"  "put in a list of weapons to enable a weapon arena mode, or try \"all\", \"most\", \"all_available\" or \"most_available\" (available only gives the weapon if the map normally has it as a pickup item)"
-set g_weaponarena_random "0"   "if set to a number, only that weapon count is given on every spawn (randomly)"
-set g_weaponarena_random_with_blaster "1"      "additionally, always provide the blaster in random weapon arena games"
+set g_weaponarena "0" "put in a list of weapons to enable a weapon arena mode, or try \"all\", \"most\", \"all_available\" or \"most_available\" (available only gives the weapon if the map normally has it as a pickup item)"
+set g_weaponarena_random "0" "if set to a number, only that weapon count is given on every spawn (randomly)"
+set g_weaponarena_random_with_blaster "1" "additionally, always provide the blaster in random weapon arena games"
 set g_spawnpoints_auto_move_out_of_solid 0 "if set to 1 you will see a warning if a spawn point was placed inside a solid"
 set g_forced_respawn 0 "if set to 1 and a player died, that player gets automatically respawned once <g_respawn_delay> seconds are over"
 set g_fullbrightplayers 0 "brightens up player models (note that the color, skin or model of the players does not change!)"
-set g_fullbrightitems 0 "brightens up items"
+set g_fullbrightitems 0 "allows players to use cl_fullbright_items"
 set g_nodepthtestplayers 0 "disables depth testing on players"
 set g_nodepthtestitems 0 "disables depth testing on items"
 set g_casings 2 "specifies which casings (0: none, 1: only shotgun casings, 2: shotgun and machine gun casings) are sent to the client"
 set g_norecoil 0 "if set to 1 shooting weapons won't make you crosshair to move upwards (recoil)"
 set g_maplist_mostrecent "" "contains the name of the maps that were most recently played"
-set g_maplist_mostrecent_count 3       "number of most recent maps that are blocked from being played again"
-set g_maplist_index 0  "this is used internally for saving position in maplist cycle"
-set g_maplist_selectrandom 0   "if 1, a random map will be chosen as next map - DEPRECATED in favor of g_maplist_shuffle"
-set g_maplist_shuffle 1        "new randomization method: like selectrandom, but avoid playing the same maps in short succession. This works by taking out the first element and inserting it into g_maplist with a bias to the end of the list"
-set g_maplist_check_waypoints 0        "when 1, maps are skipped if there currently are bots, but the map has no waypoints"
+set g_maplist_mostrecent_count 3 "number of most recent maps that are blocked from being played again"
+set g_maplist_index 0 "this is used internally for saving position in maplist cycle"
+set g_maplist_selectrandom 0 "if 1, a random map will be chosen as next map - DEPRECATED in favor of g_maplist_shuffle"
+set g_maplist_shuffle 1 "new randomization method: like selectrandom, but avoid playing the same maps in short succession. This works by taking out the first element and inserting it into g_maplist with a bias to the end of the list"
+set g_maplist_check_waypoints 0 "when 1, maps are skipped if there currently are bots, but the map has no waypoints"
 set g_maplist_ignore_sizes 0 "when 1, all maps are shown in the map list regardless of player count"
 set g_maplist_sizes_count_bots 1 "include the number of bots currently in the server when counting the number of players for size restrictions"
 
@@ -224,7 +225,7 @@ set g_grab_range 200 "distance at which dragable objects can be grabbed"
 
 set g_cloaked 0 "display all players mostly invisible"
 set g_player_alpha 1 "default opacity of players"
-set g_player_brightness 0      "set to 2 for brighter players"
+set g_player_brightness 0 "set to 2 for brighter players"
 set g_player_damageforcescale 2 "push multiplier of attacks against players"
 set g_balance_cloaked_alpha 0.25 "opacity of cloaked players"
 
@@ -260,15 +261,15 @@ set g_friendlyfire_virtual_force 1  "for teamplay_mode 4: apply force even thoug
 set g_teamdamage_threshold 40       "for teamplay_mode 4: threshold over which to apply mirror damage"
 set g_teamdamage_resetspeed 20      "for teamplay_mode 4: how fast player's teamdamage count decreases"
 
-set g_balance_teams 1  "automatically balance out players entering instead of asking them for their preferred team"
-set g_balance_teams_prevent_imbalance  1       "prevent players from changing to larger teams"
-set g_changeteam_banned 0      "not allowed to change team"
+set g_balance_teams 1 "automatically balance out players entering instead of asking them for their preferred team"
+set g_balance_teams_prevent_imbalance 1 "prevent players from changing to larger teams"
+set g_changeteam_banned 0 "not allowed to change team"
 
 set sv_teamnagger 1 "enable a nag message when the teams are unbalanced"
 
 set g_bloodloss 0   "amount of health below which blood loss occurs"
 
-set g_footsteps 1      "serverside footstep sounds"
+set g_footsteps 1 "serverside footstep sounds"
 
 set g_throughfloor_debug 0 "enable debugging messages for throughfloor calculations"
 set g_throughfloor_damage_max_stddev 2 "Maximum standard deviation for splash damage"
@@ -298,13 +299,13 @@ set _sv_init 0
 alias startmap_dm "set _sv_init 0; map _init/_init; exec $serverconfig; set _sv_init 1"
 
 // score log
-set sv_logscores_console 0     "print scores to server console"
-set sv_logscores_file 0        "print scores to file"
-set sv_logscores_filename scores.log   "filename"
-set sv_logscores_bots 0        "exclude bots by default"
+set sv_logscores_console 0 "print scores to server console"
+set sv_logscores_file 0 "print scores to file"
+set sv_logscores_filename scores.log "filename"
+set sv_logscores_bots 0 "exclude bots by default"
 
 // spam (frag/capture) log
-set sv_eventlog 0      "the master switch for efficiency reasons"
+set sv_eventlog 0 "the master switch for efficiency reasons"
 set sv_eventlog_console 1 "print event log entries to the console as well"
 set sv_eventlog_files 0 "save the event log to individual files instead of the main server log"
 set sv_eventlog_files_timestamps 1 "include timestamps in the log file names"
@@ -312,10 +313,10 @@ set sv_eventlog_files_counter 0 "internal counter cvar, do not modify"
 set sv_eventlog_files_nameprefix xonotic "prefix of individual log file names"
 set sv_eventlog_files_namesuffix .log "suffix of individual log file names"
 
-set nextmap "" "override the maplist when switching to the next map"
+set nextmap "" "override the maplist when switching to the next map"
 set lastlevel "" "for singleplayer use, shows the menu once the match has ended"
-set quit_when_empty 0  "set to 1, then the server exits when the next level would start but is empty"
-set quit_and_redirect ""       "set to an IP to redirect all players at the end of the match to another server. Set to \"self\" to let all players reconnect at the end of the match (use it to make seamless engine updates)"
+set quit_when_empty 0 "set to 1, then the server exits when the next level would start but is empty"
+set quit_and_redirect "" "set to an IP to redirect all players at the end of the match to another server. Set to \"self\" to let all players reconnect at the end of the match (use it to make seamless engine updates)"
 set quit_and_redirect_timer 1.5 "set to number of seconds after quit before performing the connect operation of quit_and_redirect"
 
 // Green's fullbright skins, updated by Samual
@@ -334,34 +335,34 @@ set sv_curl_serverpackages_auto 1 "automatically add packs with *.serverpackage
 
 set sv_motd "" "additional information to show on the welcome screen that greets joining players"
 
-set g_waypoints_for_items 0    "make waypoints out of items, values: 0 = never, 1 = unless the mapper prevents it by worldspawn.spawnflags & 1, 2 = always"
+set g_waypoints_for_items 0 "make waypoints out of items, values: 0 = never, 1 = unless the mapper prevents it by worldspawn.spawnflags & 1, 2 = always"
 
-set g_maplist_votable 6 "number of maps that are shown in the map voting at the end of a match"
+set g_maplist_votable 6 "number of maps that are shown in the map voting at the end of a match, 0 to disable"
 set g_maplist_votable_keeptwotime 15 "show only 2 options after this amount of time during map vote screen"
-set g_maplist_votable_timeout 30       "timeout for the map voting; must be below 50 seconds!"
-set g_maplist_votable_suggestions 2 "number of maps a player is allowed to suggest for the map voting screen"
+set g_maplist_votable_timeout 30 "timeout for the map voting; must be below 50 seconds!"
+set g_maplist_votable_suggestions 2 "number of maps a player is allowed to suggest for the map voting screen using 'suggestmap'"
 set g_maplist_votable_suggestions_override_mostrecent 0 "allow players to suggest maps that have been played recently"
-set g_maplist_votable_nodetail 0       "nodetail only shows total count instead of all vote counts per map, so votes don't influence others that much"
-set g_maplist_votable_abstain 0        "when 1, you can abstain from your vote"
+set g_maplist_votable_nodetail 0 "hide per-map vote counts (to avoid influential first votes)"
+set g_maplist_votable_abstain 0 "offer a "\don't care\" option on the voting screen"
 set g_maplist_votable_screenshot_dir "maps levelshots" "where to look for map screenshots"
 
 set sv_vote_gametype 0 "show a vote screen for gametypes before map vote screen"
 set sv_vote_gametype_keeptwotime 10 "show only 2 options after this amount of time during gametype vote screen"
-set sv_vote_gametype_options "dm tdm ctf" "Keep the identifiers short, otherwise you'll run into issues with too long alias names (max is 31 characters) when using sv_vote_gametype_hook_*"
+set sv_vote_gametype_options "dm tdm ca ctf" "identifiers of gamemodes on the voting screen, can be custom (max 9 chars) - see example in server/server.cfg"
 set sv_vote_gametype_timeout 20 "how long the gametype vote screen lasts"
 set sv_vote_gametype_default_current 1 "Keep the current gametype if no one votes"
 
-set g_chat_flood_spl 3 "normal chat: seconds between lines to not count as flooding"
-set g_chat_flood_lmax 2        "normal chat: maximum number of lines per chat message at once"
-set g_chat_flood_burst 2       "normal chat: allow bursts of so many chat lines"
-set g_chat_flood_spl_team 1    "team chat: seconds between lines to not count as flooding"
-set g_chat_flood_lmax_team 2   "team chat: maximum number of lines per chat message at once"
-set g_chat_flood_burst_team 2  "team chat: allow bursts of so many chat lines"
-set g_chat_flood_spl_tell 1    "private chat: seconds between lines to not count as flooding"
-set g_chat_flood_lmax_tell 2   "private chat: maximum number of lines per chat message at once"
-set g_chat_flood_burst_tell 2  "private chat: allow bursts of so many chat lines"
-set g_chat_flood_notify_flooder 1      "when 0, the flooder still can see his own message"
-set g_chat_teamcolors 0        "colorize nicknames in team color for chat"
+set g_chat_flood_spl 3 "normal chat: seconds between lines to not count as flooding"
+set g_chat_flood_lmax 2 "normal chat: maximum number of lines per chat message at once"
+set g_chat_flood_burst 2 "normal chat: allow bursts of so many chat lines"
+set g_chat_flood_spl_team 1 "team chat: seconds between lines to not count as flooding"
+set g_chat_flood_lmax_team 2 "team chat: maximum number of lines per chat message at once"
+set g_chat_flood_burst_team 2 "team chat: allow bursts of so many chat lines"
+set g_chat_flood_spl_tell 1 "private chat: seconds between lines to not count as flooding"
+set g_chat_flood_lmax_tell 2 "private chat: maximum number of lines per chat message at once"
+set g_chat_flood_burst_tell 2 "private chat: allow bursts of so many chat lines"
+set g_chat_flood_notify_flooder 1 "when 0, the flooder still can see his own message"
+set g_chat_teamcolors 0 "colorize nicknames in team color for chat"
 set g_chat_tellprivacy 1 "when disabled, tell messages are also sent to the server console log... otherwise they're kept private between players."
 set g_nick_flood_timeout 120 "time after which nick flood protection resets (set to 0 to disable nick flood checking)"
 set g_nick_flood_penalty 0.5 "duration of the nick flood penalty"
@@ -374,17 +375,17 @@ set sv_waypointsprite_limitedrange 5120 "default maximum viewing distance of way
 
 set sv_itemstime 1 "enable networking of time left until respawn for items such as mega health/armor and powerups"
 
-set g_ban_default_bantime 5400 "90 minutes"
-set g_ban_default_masksize 3   "masksize 0 means banning by UID only, 1 means banning by /8 (IPv6: /32) network, 2 means banning by /16 (IPv6: /48) network, 3 means banning by /24 (IPv6: /56) network, 4 means banning by single IP (IPv6: /64 network)"
+set g_ban_default_bantime 5400 "90 minutes"
+set g_ban_default_masksize 3 "masksize 0 means banning by UID only, 1 means banning by /8 (IPv6: /32) network, 2 means banning by /16 (IPv6: /48) network, 3 means banning by /24 (IPv6: /56) network, 4 means banning by single IP (IPv6: /64 network)"
 set g_ban_telluser 1 "notify the banned player about it when they try to join"
-set g_banned_list ""   "format: IP remainingtime IP remainingtime ..."
-set g_banned_list_idmode "1"   "when set, the IP banning system always uses the ID over the IP address (so a user in a banned IP range can connect if they have a valid signed ID)"
+set g_banned_list "" "format: IP remainingtime IP remainingtime ..."
+set g_banned_list_idmode "1" "when set, the IP banning system always uses the ID over the IP address (so a user in a banned IP range can connect if they have a valid signed ID)"
 
 // useful vote aliases
 set timelimit_increment 5 "number of minutes added to the timer when voting for extendmatchtime"
 set timelimit_decrement 5 "number of minutes removed from the timer when voting for reducematchtime"
-set timelimit_min 5 "shortest match time achieveable with reducematchtime votes"
-set timelimit_max 60 "maximum match time achieveable with extendmatchtime votes"
+set timelimit_min 5 "shortest match time achieveable with reducematchtime and timelimit votes"
+set timelimit_max 60 "maximum match time achieveable with extendmatchtime and timelimit votes"
 
 sv_gameplayfix_delayprojectiles 0
 sv_gameplayfix_q2airaccelerate 1
@@ -408,18 +409,18 @@ set sv_maxidle_slots_countbots 1 "count bots as player slots"
 sv_allowdownloads_inarchive 1 // for csprogs.dat
 sv_allowdownloads 0 // download protocol is evil
 
-set g_jump_grunt 0     "Do you make a grunting noise every time you jump? Is it the same grunting noise every time?"
+set g_jump_grunt 0 "Do you make a grunting noise every time you jump? Is it the same grunting noise every time?"
 
-set g_maplist_allow_hidden 0           "allow hidden maps to be, e.g., voted for and in the maplist"
-set g_maplist_allow_frustrating 0      "allow impossible maps to be, e.g., voted for and in the maplist (if set to 2, ONLY impossible maps are allowed)"
+set g_maplist_allow_hidden 0  "allow hidden maps to be, e.g., voted for and in the maplist"
+set g_maplist_allow_frustrating 0 "allow impossible maps to be, e.g., voted for and in the maplist (if set to 2, ONLY impossible maps are allowed)"
 
-set sv_clones 0        "number of clones a player may make (reset by the \"kill\" command)"
+set sv_clones 0 "number of clones a player may make (reset by the \"kill\" command)"
 
-set g_ban_sync_uri ""  "sync using this ban list provider (empty string to disable)"
-set g_ban_sync_interval 5      "sync every 5 minutes"
-set g_ban_sync_trusted_servers ""      "request ban lists from these xonotic servers (do not include your own server there, or unbanning may fail)"
-set g_ban_sync_timeout 45      "time out in seconds for the ban sync requests"
-set g_ban_sync_trusted_servers_verify 0        "when set to 1, additional bans sent by the servers are ignored, and only bans for the requested IP are used"
+set g_ban_sync_uri "" "sync using this ban list provider (empty string to disable)"
+set g_ban_sync_interval 5 "sync every 5 minutes"
+set g_ban_sync_trusted_servers "" "request ban lists from these xonotic servers (do not include your own server there, or unbanning may fail)"
+set g_ban_sync_timeout 45 "time out in seconds for the ban sync requests"
+set g_ban_sync_trusted_servers_verify 0 "when set to 1, additional bans sent by the servers are ignored, and only bans for the requested IP are used"
 
 set g_showweaponspawns 1 "1: display waypoints for weapon spawns found on the map when a weapon key is pressed and the weapon is not owned; 2: for dropped weapons too; 3: for all the weapons sharing the same impulse"
 
@@ -429,11 +430,11 @@ set g_ballistics_density_corpse 0.10 "how hard corpses are to shoot through comp
 set g_ballistics_penetrate_clips 1 "allow ballistics to pass through weapon clips"
 set g_ballistics_solidpenetration_exponent 0.25 "how fast damage falls off when bullets pass through walls - 1 means linear, lower values mean slower initial falloff but faster once there's little solidpenetration left (damage_fraction = solidpen_fraction^exp for solidpen_fraction between 0 and 1)"
 
-sv_status_show_qcstatus 1      "Xonotic uses this field instead of frags"
-set g_full_getstatus_responses 0       "this currently breaks qstat"
+sv_status_show_qcstatus 1 "Xonotic uses this field instead of frags"
+set g_full_getstatus_responses 0 "this currently breaks qstat"
 
 // "Gentle mode": show no blood
-set sv_gentle 0                "force gentle mode for everyone, also remove references to acts of killing from the messages"
+set sv_gentle 0 "force gentle mode for everyone, also remove references to acts of killing from the messages"
 
 set g_jetpack 0 "Jetpack mutator"
 
@@ -486,7 +487,8 @@ sv_gameplayfix_nogravityonground 1
 set sv_q3acompat_machineshotgunswap 0 "shorthand for swapping machinegun and shotgun (for Q3A map compatibility in mapinfo files)"
 set sv_vq3compat 0 "toggle for some compatibility hacks (for VQ3 and CPM map compatibility in mapinfo files)"
 
-set g_movement_highspeed 1 "movement speed modification factor (only changes movement when above maxspeed)"
+set g_movement_highspeed 1 "multiplier scale for movement speed (applies to sv_maxspeed and sv_maxairspeed, also applies to air acceleration when g_movement_highspeed_q3_compat is set to 0)"
+set g_movement_highspeed_q3_compat 0 "apply speed modifiers to air movement in a more Q3-compatible way (only apply speed buffs and g_movement_highspeed to max air speed, not to acceleration)"
 
 set g_maxspeed 0 "player speed limit, faster players are killed (0 for unlimited speed)"
 
@@ -565,3 +567,4 @@ set sv_showspectators 1 "Show who's spectating who in the player info panel when
 set sv_damagetext 2 "<= 0: disabled, >= 1: visible to spectators, >= 2: visible to attacker, >= 3: all players see everyone's damage"
 
 set sv_showfps 5 "Show player's FPS counters in the scoreboard. This setting acts as a delay in seconds between updates"
+set autocvar_sv_doors_always_open 0 "If set to 1 don't close doors which after they were open"