Index: data/defaultNexuiz.cfg
===================================================================
--- data/defaultNexuiz.cfg	(revision 7552)
+++ data/defaultNexuiz.cfg	(working copy)
@@ -26,7 +26,7 @@
 seta g_configversion 0	"Configuration file version (used to upgrade settings) 0: first run, or previous start was <2.4.1  Later, it's overridden by config.cfg, version ranges are defined in config_update.cfg"
 
 // default.cfg versioning (update using update-cvarcount.sh, run that every time after adding a new cvar)
-set cvar_check_default ff6f4ae047891b3b61ecfc5b3d3b38b4
+set cvar_check_default 40fd98ae84e7814d9494ef3cef6fb162
 
 // Nexuiz version (formatted for machines)
 // used to determine if a client version is compatible
@@ -110,7 +110,7 @@
 _cl_name Player
 _cl_playermodel models/player/marine.zym
 _cl_playerskin 0
-crosshair 1
+crosshair 5
 seta crosshair_per_weapon 0	"when 1, each gun will display a different crosshair"
 seta crosshair_color_override 0	"when 1, crosshair_color_* overrides the per-weapon color"
 seta crosshair_hittest 1 "do a crosshair hit evaluation; also, the crosshair is scaled by the given number when aiming at an enemy, and blurred when aiming at a team mate"
@@ -252,8 +252,6 @@
 
 // taunts and voices
 seta cl_autotaunt 0 "automatically taunt enemies when fragging them"
-seta sv_taunt 1 "allow taunts on the server"
-seta sv_autotaunt 1 "allow autotaunts on the server"
 seta cl_voice_directional 1	"0 = all voices are non-directional, 1 = all voices are directional, 2 = only taunts are directional"
 seta cl_voice_directional_taunt_attenuation 0.5 "this defines the distance from which taunts can be heared"
 
@@ -278,7 +276,7 @@
 //tournament mod
 set g_warmup 0	"split the game into a warmup- and match-stage when set to 1"
 set g_warmup_limit 60	"if set to -1 the warmup-stage is not affected by any timelimit, if set to 0 the usual timelimit also affects warmup-stage, otherwise warmup will be limited to this time in SECONDS (useful for public matches)"
-set g_warmup_allow_timeout 0	"if set to 1 timeouts can also be called in the warmup-stage, when sv_timeout is set to 1"
+set g_warmup_allow_timeout 0	"if set to 0 you cannot use the calltimeout command during the warmup-stage but only during the match stage"
 set g_warmup_allguns 0	"if set players start with all guns in warmup mode"
 set g_warmup_start_health 250	"starting values when being in warmup-stage"
 set g_warmup_start_armor 100 "starting values when being in warmup-stage"
@@ -298,8 +296,8 @@
 set sv_timeout 0	"allows 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_leadtime 4	"how long the players will be informed that a timeout was calledbefore it starts, in seconds"
+set sv_timeout_resumetime 3	"how long the remaining timeout-time will be after a player called the resumegame command"
 
 set g_allow_oldnexbeam 0 "If enabled, clients are allowed to use old v2.3 Nexgun beam"
 seta cl_particles_oldnexbeam 0 "Uses the old v2.3 Nexgun beam instead of the new beam, only works if server allows it (g_allow_oldnexbeam 1)"
@@ -401,7 +399,7 @@
 set bot_ai_bunnyhop_stopdistance 220 "Stop jumping after reaching this distance to the goal"
 set bot_ai_bunnyhop_firstjumpdelay 0.5 "Start running to the goal only if it was seen for more than N seconds"
 set bot_god 0 "god mode for bots"
-set bot_ai_navigation_jetpack 0 "Enable bots to navigat maps using the jetpack"
+set bot_ai_navigation_jetpack 1 "Enable bots to navigat maps using the jetpack"
 set bot_ai_navigation_jetpack_mindistance 2500 "Bots will try fly to objects located farther than this distance"
 // Better don't touch these, there are hard to tweak!
 set bot_ai_aimskill_order_mix_1st 0.01 "Amount of the 1st filter output to apply to the aiming angle"
@@ -431,9 +429,9 @@
 seta g_spawnshieldtime 0 "number of seconds you are invincible after you spawned, this shield is lost after you fire"
 seta g_antilag 2	"AntiLag (0 = no AntiLag, 1 = verified client side hit scan, 2 = server side hit scan in the past, 3 = unverified client side hit scan)"
 set g_antilag_bullets 1 "Bullets AntiLag (0 = no AntiLag, 1 = server side hit scan in the past) - DO NOT TOUCH (severely changes weapon balance)"
-set g_shootfromclient 1 "let client decide if it has the gun left or right; if set to 2, center handedness is allowed, and defaulted to, too; see also cl_gunalign"
-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_shootfromclient 0 "let client decide if it has the gun left, center or right (WARNING: cheating potential)"
+set g_shootfromeye 0 "shots are fired from your eye/crosshair"
+set g_shootfromcenter 0 "weapon gets moved to the center, shots still come from the barrel of your weapon"
 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 "if set to 1 or 2, weapons stay after they were picked up (1: weapons you don't have yet give you ammo of their type, 2: weapons don't give ammo, but instead players start with one pickup-load of ammo by default)"
@@ -465,7 +463,7 @@
 set g_throughfloor 1 "set to 0 to disable damage through floor"
 set g_maplist_mostrecent "" "contains the name of the maps that were most recently played"
 seta g_maplist_mostrecent_count 3	"number of most recent maps that are blocked from being played again"
-seta g_maplist "accident aggressor aneurysm basement basementctf bleach bloodprison bloodprisonctf bluesky cyberparcour01 darkzone desertfactory dieselpower downer eggandbacon evilspace farewell final_rage nr_piece-o-cake ons-reborn racetrack reslimed ruiner runningman runningman_1on1remix runningmanctf silvercity skyway slimepit soylent starship stormkeep2 strength toxic warfare"
+seta g_maplist "accident aggressor aneurysm basement basementctf bleach bloodprison bloodprisonctf bluesky cyberparcour01 darkzone desertfactory dieselpower downer eggandbacon evilspace farewell final_rage nr_piece-o-cake ons-reborn racetrack reslimed ruiner runningman runningman_1on1remix runningmanctf silvercity skyway slimepit soylent starship stormkeep strength toxic warfare"
 seta g_maplist_index 0	"this is used internally for saving position in maplist cycle"
 seta g_maplist_selectrandom 0	"if 1, a random map will be chosen as next map - DEPRECATED in favor of g_maplist_shuffle"
 seta 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"
@@ -643,7 +641,6 @@
 // domination
 set g_domination			0 "Domination: capture and hold control points to gain points"
 set g_domination_default_teams		2 "default number of teams for maps that aren't domination-specific"
-seta g_domination_teams_override		0 "use a specific number of teams in domination games (minimum 2), disables dom_team entities"
 set g_domination_disable_frags		0 "players can't get frags normally, only get points from kills"
 set g_domination_point_amt		0 "override: how many points to get per ping"
 set g_domination_point_fullbright	0 "domination point fullbright"
@@ -755,6 +752,26 @@
 
 set g_nexball_radar_showallplayers 1  "1: show every player and the ball on the radar  0: only show teammates and the ball on the radar"
 
+//Keep Away
+set g_keepaway 0
+set g_keepawayball_respawntime 30
+set g_keepaway_pointamt 1
+set g_keepaway_pointrate 1
+set g_keepaway_pointlimit -1
+set g_keepaway_pointleadlimit -1
+set g_keepawayball_trail_color 254
+set g_keepawayball_damageforcescale 1
+set g_keepaway_powerup_damage 1.5
+set g_keepaway_powerup_force 1.5
+set g_keepaway_powerup_selfdamage 1
+set g_keepaway_powerup_selfforce 1.5
+set g_keepaway_noncarrier_damage 0.75
+set g_keepaway_noncarrier_force 0.75
+set g_keepaway_noncarrier_selfdamage 1
+set g_keepaway_noncarrier_selfforce 1
+
+seta g_keepaway_win_mode 0
+
 // server game balance settings
 set g_balance_armor_regen 0
 set g_balance_armor_rot 0.1
@@ -811,9 +828,8 @@
 seta r_ambient 4
 cl_decals_fadetime 1
 cl_decals_time 2
-seta cl_gunalign 3 "Gun alignment; 1 = right, 2 = left, 3 = center or right, 4 = center or left"
+set  cl_gunalign 3 "Gun alignment; 1 = right, 2 = left, 3 = center"
 seta cl_nogibs 0 "reduce number of violence effects, or remove them totally"
-seta cl_particlegibs 0 "simpler gibs"
 seta cl_gibs_damageforcescale 3.5 "force to push around gibs"
 seta cl_gibs_lifetime 14 "average lifetime of gibs"
 seta cl_gibs_velocity_scale 1 "gib throw velocity force scale"
@@ -1217,7 +1233,7 @@
 set g_balance_keyhunt_throwvelocity 400
 set g_balance_keyhunt_protecttime 0.8
 set g_balance_keyhunt_damageforcescale 1
-seta g_keyhunt_teams_override 0
+set g_keyhunt_teams_override 0
 set g_keyhunt_teams 0
 
 // so it can be stuffcmd-ed still
@@ -1294,7 +1310,7 @@
 
 // good settings for these fonts
 con_chat 5
-con_chatpos -9
+con_chatpos -7
 con_chatsize 10
 con_chatwidth 0.6
 con_notifysize 10
@@ -1412,7 +1428,6 @@
 
 // sbar: font size
 seta sbar_fontsize 11
-seta sbar_fontsize_spec 16
 seta scr_centersize 11
 seta sbar_width 560
 alias sbar_font "loadfont user1 $*; loadfont user2 ${*}-big; sbar_columns_set"
@@ -1640,20 +1655,3 @@
 set g_mapinfo_settemp_acl "+*" "ACL for mapinfo setting cvars"
 
 cl_netfps 32 // moar
-
-seta cl_casings_maxcount 100 "maximum amount of shell casings (must be at least 1)"
-seta cl_gibs_maxcount 100 "maximum amount of gibs (must be at least 1)"
-seta cl_vehicle_spiderbot_cross_alpha 0.6
-seta cl_vehicle_spiderbot_cross_size 1
-
-//cl_gunalign calculator
-seta menu_cl_gunalign 3 "Gun alignment; 1 = right, 2 = left, 3 = center or right, 4 = center or left"
-alias _gunalign_01 "cl_gunalign 1"
-alias _gunalign_02 "cl_gunalign 2"
-alias _gunalign_03 "cl_gunalign 3"
-alias _gunalign_04 "cl_gunalign 4"
-alias _gunalign_11 "cl_gunalign 2"
-alias _gunalign_12 "cl_gunalign 1"
-alias _gunalign_13 "cl_gunalign 4"
-alias _gunalign_14 "cl_gunalign 3"
-alias _gunalign_update "_gunalign_$v_flipped$menu_cl_gunalign"
Index: data/maps/aggressor.mapinfo
===================================================================
--- data/maps/aggressor.mapinfo	(revision 7552)
+++ data/maps/aggressor.mapinfo	(working copy)
@@ -12,4 +12,5 @@
 type arena 10 20
 type kh 1000 20 3
 type rc 20 5 10 20
+type keepaway 30 20
 cdtrack 4
Index: data/maps/aneurysm.mapinfo
===================================================================
--- data/maps/aneurysm.mapinfo	(revision 7552)
+++ data/maps/aneurysm.mapinfo	(working copy)
@@ -11,4 +11,5 @@
 type arena 10 20
 type kh 1000 30 2
 type tdm 50 20 2
+type keepaway 30 20
 cdtrack 6
Index: data/maps/basement.mapinfo
===================================================================
--- data/maps/basement.mapinfo	(revision 7552)
+++ data/maps/basement.mapinfo	(working copy)
@@ -9,4 +9,5 @@
 type rune 200 20
 type lms 9 20
 type arena 10 20
+type keepaway 30 20
 cdtrack 4
Index: data/maps/bleach.mapinfo
===================================================================
--- data/maps/bleach.mapinfo	(revision 7552)
+++ data/maps/bleach.mapinfo	(working copy)
@@ -10,4 +10,5 @@
 type rune 200 20
 type lms 9 20
 type kh 1000 20 3
+type keepaway 30 20
 cdtrack 8
Index: data/maps/bloodprison.mapinfo
===================================================================
--- data/maps/bloodprison.mapinfo	(revision 7552)
+++ data/maps/bloodprison.mapinfo	(working copy)
@@ -7,4 +7,5 @@
 type dm 30 20
 type tdm 50 20 2
 type lms 9 20
+type keepaway 30 20
 cdtrack 2
Index: data/maps/darkzone.mapinfo
===================================================================
--- data/maps/darkzone.mapinfo	(revision 7552)
+++ data/maps/darkzone.mapinfo	(working copy)
@@ -9,4 +9,5 @@
 type rune 200 20
 type lms 9 20
 type arena 10 20
+type keepaway 30 20
 cdtrack 8
Index: data/maps/desertfactory.mapinfo
===================================================================
--- data/maps/desertfactory.mapinfo	(revision 7552)
+++ data/maps/desertfactory.mapinfo	(working copy)
@@ -8,3 +8,4 @@
 type lms 9 20
 type arena 10 20
 type kh 1000 20 2
+type keepaway 30 20
Index: data/maps/dieselpower.mapinfo
===================================================================
--- data/maps/dieselpower.mapinfo	(revision 7552)
+++ data/maps/dieselpower.mapinfo	(working copy)
@@ -10,4 +10,5 @@
 type rune 200 20
 type lms 9 20
 type kh 1000 20 3
+type keepaway 30 20
 cdtrack 15
Index: data/maps/downer.mapinfo
===================================================================
--- data/maps/downer.mapinfo	(revision 7552)
+++ data/maps/downer.mapinfo	(working copy)
@@ -10,4 +10,5 @@
 type rune 200 20
 type lms 9 20
 type arena 10 20
+type keepaway 30 20
 cdtrack 8
Index: data/maps/eggandbacon.mapinfo
===================================================================
--- data/maps/eggandbacon.mapinfo	(revision 7552)
+++ data/maps/eggandbacon.mapinfo	(working copy)
@@ -9,3 +9,4 @@
 type lms 16 20
 type arena 10 20
 type ctf 300 20
+type keepaway 30 20
Index: data/maps/final_rage.mapinfo
===================================================================
--- data/maps/final_rage.mapinfo	(revision 7552)
+++ data/maps/final_rage.mapinfo	(working copy)
@@ -10,4 +10,5 @@
 type rune 200 20
 type lms 9 20
 type arena 10 20
+type keepaway 30 20
 cdtrack 7
Index: data/maps/reslimed.mapinfo
===================================================================
--- data/maps/reslimed.mapinfo	(revision 7552)
+++ data/maps/reslimed.mapinfo	(working copy)
@@ -9,4 +9,5 @@
 type dom 200 20
 type rune 200 20
 type lms 9 20
+type keepaway 30 20
 cdtrack 4
Index: data/maps/ruiner.mapinfo
===================================================================
--- data/maps/ruiner.mapinfo	(revision 7552)
+++ data/maps/ruiner.mapinfo	(working copy)
@@ -9,6 +9,7 @@
 type rune 200 20
 type lms 9 20
 type arena 10 20
+type keepaway 30 20
 cdtrack 11
 clientsettemp_for_type all r_shadow_glossexponent 96
 clientsettemp_for_type all r_shadow_glossintensity 2
Index: data/maps/runningman.mapinfo
===================================================================
--- data/maps/runningman.mapinfo	(revision 7552)
+++ data/maps/runningman.mapinfo	(working copy)
@@ -10,4 +10,5 @@
 type rune 200 20
 type lms 9 20
 type arena 10 20
+type keepaway 30 20
 cdtrack 2
Index: data/maps/runningman_1on1remix.mapinfo
===================================================================
--- data/maps/runningman_1on1remix.mapinfo	(revision 7552)
+++ data/maps/runningman_1on1remix.mapinfo	(working copy)
@@ -11,4 +11,5 @@
 type lms 9 20
 type arena 10 20
 type kh 1000 20 3
+type keepaway 30 20
 cdtrack 2
Index: data/maps/silvercity.mapinfo
===================================================================
--- data/maps/silvercity.mapinfo	(revision 7552)
+++ data/maps/silvercity.mapinfo	(working copy)
@@ -10,4 +10,5 @@
 type rune 200 20
 type lms 9 20
 type kh 1000 20 3
+type keepaway 30 20
 cdtrack 10
Index: data/maps/skyway.mapinfo
===================================================================
--- data/maps/skyway.mapinfo	(revision 7552)
+++ data/maps/skyway.mapinfo	(working copy)
@@ -10,4 +10,5 @@
 type lms 9 20
 type arena 10 20
 type kh 1000 20 3
+type keepaway 30 20
 cdtrack 9
Index: data/maps/slimepit.mapinfo
===================================================================
--- data/maps/slimepit.mapinfo	(revision 7552)
+++ data/maps/slimepit.mapinfo	(working copy)
@@ -9,4 +9,5 @@
 type rune 200 20
 type lms 9 20
 type arena 10 20
+type keepaway 30 20
 cdtrack 4
Index: data/maps/starship.mapinfo
===================================================================
--- data/maps/starship.mapinfo	(revision 7552)
+++ data/maps/starship.mapinfo	(working copy)
@@ -9,4 +9,5 @@
 type rune 200 20
 type lms 9 20
 type arena 10 20
+type keepaway 30 20
 cdtrack 16
Index: data/maps/stormkeep.mapinfo
===================================================================
--- data/maps/stormkeep.mapinfo	(revision 7552)
+++ data/maps/stormkeep.mapinfo	(working copy)
@@ -12,4 +12,5 @@
 type arena 10 20
 type kh 1000 20 3
 type tdm 50 20 2
+type keepaway 30 20
 cdtrack 6
Index: data/maps/strength.mapinfo
===================================================================
--- data/maps/strength.mapinfo	(revision 7552)
+++ data/maps/strength.mapinfo	(working copy)
@@ -10,4 +10,5 @@
 type lms 9 20
 type arena 10 20
 type tdm 50 20 2
+type keepaway 30 20
 cdtrack 5
Index: data/maps/toxic.mapinfo
===================================================================
--- data/maps/toxic.mapinfo	(revision 7552)
+++ data/maps/toxic.mapinfo	(working copy)
@@ -10,4 +10,5 @@
 type rune 200 20
 type lms 9 20
 type arena 10 20
+type keepaway 30 20
 cdtrack 3
Index: data/maps/warfare.mapinfo
===================================================================
--- data/maps/warfare.mapinfo	(revision 7552)
+++ data/maps/warfare.mapinfo	(working copy)
@@ -10,4 +10,5 @@
 type tdm 50 20 2
 type lms 9 20
 type arena 10 20
+type keepaway 30 20
 cdtrack 6
Index: data/qcsrc/client/sbar.qc
===================================================================
--- data/qcsrc/client/sbar.qc	(revision 7552)
+++ data/qcsrc/client/sbar.qc	(working copy)
@@ -26,6 +26,7 @@
 void CSQC_kh_hud();
 void CSQC_ctf_hud();
 void CSQC_nb_hud();
+void CSQC_ka_hud();
 void MapVote_Draw();
 void Sbar_FinaleOverlay()
 {
@@ -421,12 +422,12 @@
 {
 	return strcat( // fteqcc sucks
 		"ping pl name | ",
-		"-teams,race,lms/kills -teams,lms/deaths -teams,lms,race/suicides -race,dm,tdm/frags ", // tdm already has this in "score"
+		"-teams,race,lms/kills -teams,lms/deaths -teams,lms,race,keepaway/suicides -race,dm,tdm,keepaway/frags ", // tdm already has this in "score"
 		"+ctf/caps +ctf/pickups +ctf/fckills +ctf/returns ",
 		"+lms/lives +lms/rank ",
 		"+kh/caps +kh/pushes +kh/destroyed ",
 		"?+race/laps ?+race/time ?+race/fastest ",
-		"+as/objectives +nexball/faults +nexball/goals ",
+		"+as/objectives +nexball/faults +nexball/goals +keepaway/drops +keepaway/pickups +keepaway/bckills ",
 		"-lms,race,nexball/score");
 }
 
@@ -2579,7 +2580,10 @@
 		} else if(gametype == GAME_NEXBALL)
 		{
 			CSQC_nb_hud();
-  		}
+  		} else if(gametype == GAME_KEEPAWAY)
+		{
+			CSQC_ka_hud();
+		}
 	}
 }
 
@@ -2741,3 +2745,18 @@
 	if (stat_items & IT_KEY1)
 		drawpic(pos, "gfx/hud/sb_nexball_carrying", '80 34 0', '1 1 1', 1, DRAWFLAG_NORMAL);
 }
+
+void CSQC_ka_hud(void)
+{
+	vector pos;
+	float stat_items;
+	
+	stat_items = getstati(STAT_ITEMS);
+	
+	pos_x = 4;
+	pos_y = vid_conheight - 42;
+	pos_z = 0;
+	
+	if (stat_items & IT_KEY1)
+		drawpic(pos, "gfx/hud/sb_nexball_carrying", '80 34 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+}
Index: data/qcsrc/common/constants.qh
===================================================================
--- data/qcsrc/common/constants.qh	(revision 7552)
+++ data/qcsrc/common/constants.qh	(working copy)
@@ -38,6 +38,7 @@
 const float GAME_RACE	= 11;
 const float GAME_NEXBALL = 12;
 const float GAME_CTS = 13;
+const float GAME_KEEPAWAY = 14;
 
 const float AS_STRING		= 1;
 const float AS_INT		= 2;
Index: data/qcsrc/common/mapinfo.qc
===================================================================
--- data/qcsrc/common/mapinfo.qc	(revision 7552)
+++ data/qcsrc/common/mapinfo.qc	(working copy)
@@ -518,21 +518,22 @@
 
 float MapInfo_Type_FromString(string t)
 {
-	if     (t == "dm")      return MAPINFO_TYPE_DEATHMATCH;
-	else if(t == "tdm")     return MAPINFO_TYPE_TEAM_DEATHMATCH;
-	else if(t == "dom")     return MAPINFO_TYPE_DOMINATION;
-	else if(t == "ctf")     return MAPINFO_TYPE_CTF;
-	else if(t == "rune")    return MAPINFO_TYPE_RUNEMATCH;
-	else if(t == "lms")     return MAPINFO_TYPE_LMS;
-	else if(t == "arena")   return MAPINFO_TYPE_ARENA;
-	else if(t == "kh")      return MAPINFO_TYPE_KEYHUNT;
-	else if(t == "as")      return MAPINFO_TYPE_ASSAULT;
-	else if(t == "ons")     return MAPINFO_TYPE_ONSLAUGHT;
-	else if(t == "rc")      return MAPINFO_TYPE_RACE;
-	else if(t == "nexball") return MAPINFO_TYPE_NEXBALL;
-	else if(t == "cts")     return MAPINFO_TYPE_CTS;
-	else if(t == "all")     return MAPINFO_TYPE_ALL;
-	else                    return 0;
+	if     (t == "dm")       return MAPINFO_TYPE_DEATHMATCH;
+	else if(t == "tdm")      return MAPINFO_TYPE_TEAM_DEATHMATCH;
+	else if(t == "dom")      return MAPINFO_TYPE_DOMINATION;
+	else if(t == "ctf")      return MAPINFO_TYPE_CTF;
+	else if(t == "rune")     return MAPINFO_TYPE_RUNEMATCH;
+	else if(t == "lms")      return MAPINFO_TYPE_LMS;
+	else if(t == "arena")    return MAPINFO_TYPE_ARENA;
+	else if(t == "kh")       return MAPINFO_TYPE_KEYHUNT;
+	else if(t == "as")       return MAPINFO_TYPE_ASSAULT;
+	else if(t == "ons")      return MAPINFO_TYPE_ONSLAUGHT;
+	else if(t == "rc")       return MAPINFO_TYPE_RACE;
+	else if(t == "nexball")  return MAPINFO_TYPE_NEXBALL;
+	else if(t == "cts")      return MAPINFO_TYPE_CTS;
+	else if(t == "keepaway") return MAPINFO_TYPE_KEEPAWAY;
+	else if(t == "all")      return MAPINFO_TYPE_ALL;
+	else                     return 0;
 }
 
 void _MapInfo_Parse_Settemp(string pFilename, string acl, string s, float recurse)
@@ -669,6 +670,7 @@
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_ONSLAUGHT)       fputs(fh, "type ons 20\n");
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_NEXBALL)         fputs(fh, "type nexball 5 20\n");
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_CTS)             fputs(fh, "type cts 20 -1\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_KEEPAWAY)		  fputs(fh, "type keepaway 30 20\n");
 
 		fh2 = fopen(strcat("scripts/", pFilename, ".arena"), FILE_READ);
 		if(fh2 >= 0)
@@ -940,6 +942,8 @@
 		return MAPINFO_TYPE_NEXBALL;
 	else if(cvar("g_cts"))
 		return MAPINFO_TYPE_CTS;
+	else if(cvar("g_keepaway"))
+		return MAPINFO_TYPE_KEEPAWAY;
 	else
 		return MAPINFO_TYPE_DEATHMATCH;
 }
@@ -1000,6 +1004,7 @@
 	cvar_set("g_race",       (t == MAPINFO_TYPE_RACE)            ? "1" : "0");
 	cvar_set("g_nexball",    (t == MAPINFO_TYPE_NEXBALL)         ? "1" : "0");
 	cvar_set("g_cts",        (t == MAPINFO_TYPE_CTS)             ? "1" : "0");
+	cvar_set("g_keepaway",   (t == MAPINFO_TYPE_KEEPAWAY)		 ? "1" : "0");
 }
 
 void MapInfo_LoadMap(string s)
Index: data/qcsrc/common/mapinfo.qh
===================================================================
--- data/qcsrc/common/mapinfo.qh	(revision 7552)
+++ data/qcsrc/common/mapinfo.qh	(working copy)
@@ -11,6 +11,7 @@
 float MAPINFO_TYPE_KEYHUNT			= 1024;
 float MAPINFO_TYPE_NEXBALL          = 2048;
 float MAPINFO_TYPE_CTS              = 4096;
+float MAPINFO_TYPE_KEEPAWAY			= 8192;
 float MAPINFO_TYPE_ALL              = 65535; // this has to include all above bits
 
 float MAPINFO_FEATURE_WEAPONS       = 1; // not defined for minstagib-only maps
Index: data/qcsrc/common/util.qc
===================================================================
--- data/qcsrc/common/util.qc	(revision 7552)
+++ data/qcsrc/common/util.qc	(working copy)
@@ -428,6 +428,7 @@
 	else if (g == GAME_RACE) return "rc";
 	else if (g == GAME_NEXBALL) return "nexball";
 	else if (g == GAME_CTS) return "cts";
+	else if (g == GAME_KEEPAWAY) return "keepaway";
 	return "dm";
 }
 
Index: data/qcsrc/menu/nexuiz/dialog_multiplayer_create.c
===================================================================
--- data/qcsrc/menu/nexuiz/dialog_multiplayer_create.c	(revision 7552)
+++ data/qcsrc/menu/nexuiz/dialog_multiplayer_create.c	(working copy)
@@ -32,7 +32,7 @@
 	float n;
 
 	me.TR(me);
-		n = 6;
+		n = 7;
 		me.TD(me, 1, me.columns / n, e = makeNexuizGametypeButton(1, "g_dm", "DM"));
 			e0 = e;
 		me.TD(me, 1, me.columns / n, e = makeNexuizGametypeButton(1, "g_lms", "LMS"));
@@ -45,6 +45,8 @@
 			if(e.checked) e0 = NULL;
 		me.TD(me, 1, me.columns / n, e = makeNexuizGametypeButton(1, "g_cts", "Race CTS"));
 			if(e.checked) e0 = NULL;
+		me.TD(me, 1, me.columns / n, e = makeNexuizGametypeButton(1, "g_keepaway", "Keep Away"));
+			if(e.checked) e0 = NULL;
 	me.TR(me);
 		n = 7;
 		me.TD(me, 1, me.columns / n, e = makeNexuizGametypeButton(1, "g_tdm", "TDM"));
Index: data/qcsrc/server/cl_client.qc
===================================================================
--- data/qcsrc/server/cl_client.qc	(revision 7552)
+++ data/qcsrc/server/cl_client.qc	(working copy)
@@ -556,7 +556,9 @@
 	if(self.flagcarried)
 		DropFlag(self.flagcarried, world, world);
 	if(self.ballcarried)
-		DropBall(self.ballcarried, self.origin + self.ballcarried.origin, self.velocity);
+			DropBall(self.ballcarried, self.origin + self.ballcarried.origin, self.velocity);
+	if(self.kaballcarried)
+		DropBallKA(self, self.kaballcarried);
 
 	WaypointSprite_PlayerDead();
 
@@ -1492,6 +1494,8 @@
 		DropFlag(self.flagcarried, world, world);
 	if(self.ballcarried)
 		DropBall(self.ballcarried, self.origin + self.ballcarried.origin, self.velocity);
+	if(self.kaballcarried)
+		DropBallKA(self, self.kaballcarried);
 
 	// Here, everything has been done that requires this player to be a client.
 
@@ -2269,6 +2273,7 @@
 */
 void() ctf_setstatus;
 void() nexball_setstatus;
+void() keepaway_setstatus;
 .float items_added;
 void PlayerPreThink (void)
 {
@@ -2520,6 +2525,7 @@
 		ctf_setstatus();
 		kh_setstatus();
 		nexball_setstatus();
+		keepaway_setstatus();
 
 		self.dmg_team = max(0, self.dmg_team - cvar("g_teamdamage_resetspeed") * frametime);
 
Index: data/qcsrc/server/cl_player.qc
===================================================================
--- data/qcsrc/server/cl_player.qc	(revision 7552)
+++ data/qcsrc/server/cl_player.qc	(working copy)
@@ -540,6 +540,9 @@
 		}
 		if(self.ballcarried)
 			DropBall(self.ballcarried, self.origin, self.velocity);
+		if(self.kaballcarried)
+			DropBallKA(self, self.kaballcarried);
+
 		Portal_ClearAllLater(self);
 		// clear waypoints
 		WaypointSprite_PlayerDead();
Index: data/qcsrc/server/defs.qh
===================================================================
--- data/qcsrc/server/defs.qh	(revision 7552)
+++ data/qcsrc/server/defs.qh	(working copy)
@@ -17,7 +17,7 @@
 
 float ctf_score_value(string parameter);
 
-float g_dm, g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught, g_assault, g_arena, g_lms, g_runematch, g_race, g_nexball, g_cts;
+float g_dm, g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught, g_assault, g_arena, g_lms, g_runematch, g_race, g_nexball, g_cts, g_keepaway;
 float g_cloaked, g_footsteps, g_jump_grunt, g_grappling_hook, g_laserguided_missile, g_midair, g_minstagib, g_nixnex, g_nixnex_with_laser, g_pinata, g_norecoil, g_vampire, g_minstagib_invis_alpha, g_bloodloss;
 float g_warmup_limit;
 float g_warmup_allguns;
@@ -26,6 +26,7 @@
 float g_ctf_ignore_frags;
 float g_ctf_reverse;
 float g_race_qualifying;
+float g_keepaway_win_mode;
 float inWarmupStage;
 float g_pickup_respawntime_weapon;
 float g_pickup_respawntime_ammo;
@@ -358,6 +359,7 @@
 void DropFlag(entity flag, entity penalty_receiver, entity attacker);
 void DropBall(entity ball, vector org, vector vel);
 void DropAllRunes(entity pl);
+void DropBallKA(entity pl, entity ball);
 
 
 typedef .float floatfield;
@@ -556,6 +558,8 @@
 .float metertime;
 float g_nexball_meter_period;
 
+.entity kaballcarried;
+
 void SUB_DontUseTargets();
 void SUB_UseTargets();
 
Index: data/qcsrc/server/g_damage.qc
===================================================================
--- data/qcsrc/server/g_damage.qc	(revision 7552)
+++ data/qcsrc/server/g_damage.qc	(working copy)
@@ -91,6 +91,7 @@
 	PlayerTeamScore_AddScore(player, f);
 }
 
+float KeepAway_HandleFrags(entity, entity, float);
 // NOTE: f=0 means still count as a (positive) kill, but count no frags for it
 void GiveFrags (entity attacker, entity targ, float f)
 {
@@ -152,6 +153,10 @@
 		if(g_ctf_ignore_frags)
 			f = 0;
 	}
+	else if(g_keepaway)
+	{
+		f = KeepAway_HandleFrags(attacker, targ, f);
+	}
 
 	attacker.totalfrags += f;
 
@@ -407,6 +412,7 @@
 					PlayerScore_Add(attacker, SP_CTF_FCKILLS, 1);
 					GiveFrags(attacker, targ, 0); // for logging
 				}
+				
 				else
 					GiveFrags(attacker, targ, 1);
 
@@ -743,7 +749,36 @@
 			damage = damage * cvar("g_ctf_flagcarrier_selfdamage");
 			force = force * cvar("g_ctf_flagcarrier_selfforce");
 		}
-
+		if(g_keepaway)
+		{	
+			if (attacker.items & IT_KEY1)
+			{
+				if(targ == attacker)
+				{
+					damage = damage * cvar("g_keepaway_powerup_selfdamage");
+					force = force * cvar("g_keepaway_powerup_selfforce");
+				}
+				else
+				{
+					damage = damage * cvar("g_keepaway_powerup_damage");
+					force = force * cvar("g_keepaway_powerup_force");
+				}
+			}
+			else if not(targ.items & IT_KEY1)
+			{
+				if(targ == attacker)
+				{
+					damage = damage * cvar("g_keepaway_noncarrier_selfdamage");
+					force = force * cvar("g_keepaway_noncarrier_selfforce");
+				}
+				else
+				{
+					damage = damage * cvar("g_keepaway_noncarrier_damage");
+					force = force * cvar("g_keepaway_noncarrier_force");
+				}
+			}
+			
+		}
 		if(g_runematch)
 		{
 			// apply strength rune
Index: data/qcsrc/server/g_world.qc
===================================================================
--- data/qcsrc/server/g_world.qc	(revision 7552)
+++ data/qcsrc/server/g_world.qc	(working copy)
@@ -255,6 +255,7 @@
 		BADCVAR("g_runematch");
 		BADCVAR("g_tdm");
 		BADCVAR("g_nexball");
+		BADCVAR("g_keepaway");
 		BADCVAR("teamplay");
 
 		// long
Index: data/qcsrc/server/keepaway.qc
===================================================================
--- data/qcsrc/server/keepaway.qc	(revision 0)
+++ data/qcsrc/server/keepaway.qc	(revision 0)
@@ -0,0 +1,221 @@
+void keepawayball_touch (entity);
+void keepawayball_respawn (void);
+void DropBallKA (entity, entity);
+float KeepAway_HandleFrags(entity, entity, float);
+
+void keepawayball_touch (entity plyr)
+{	
+	if ((other.classname != "player" || other.health < 1) &&  (time > self.ctf_droptime + cvar("g_keepawayball_respawn_time")))
+		return;
+		
+	if (self.wait > time)
+		return;	
+		
+	if (other.solid == SOLID_BSP) {
+		if (time > self.lastground + 0.1)
+		{
+			sound (self, CHAN_PROJECTILE, self.noise, VOL_BASE, ATTN_NORM);
+			self.lastground = time;
+		}
+		return;
+	}
+	
+	self.owner = other;
+	other.kaballcarried = self;
+	setattachment(self, other, "");
+	setorigin(self, BALL_ATTACHORG);
+	
+	self.velocity = '0 0 0';
+	self.movetype = MOVETYPE_NONE;
+	self.touch = SUB_Null;
+	self.scale = 1; // scale down
+	self.alpha = 0.01; // make invisible
+	
+	self.think = SUB_Null;
+	self.nextthink = 0;
+	
+	self.glow_color = cvar("g_keepawayball_trail_color");
+	self.glow_trail = TRUE;
+	plyr.effects |= 8;
+	plyr.alpha = 0.6;
+	
+	bprint(other.netname, "^7 has picked up the ball!\n");
+	WriteByte(MSG_BROADCAST, SVC_CENTERPRINT);
+	WriteString(MSG_BROADCAST, strcat("\n\n", other.netname, "^7 has picked up the ball!\n"));
+	sound(self.owner, CHAN_AUTO, "keepaway/pickedup.wav", VOL_BASE, ATTN_NORM);
+		
+	PlayerScore_Add(other, SP_KEEPAWAY_PICKUPS, 1);
+	
+	WaypointSprite_AttachCarrier("ka-ballcarrier", other);
+	WaypointSprite_UpdateRule(other.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT);
+	WaypointSprite_Kill(self.waypointsprite_attachedforcarrier);
+}
+
+void keepaway_setstatus()
+{	
+	if(self.kaballcarried)
+		self.items |= IT_KEY1;
+}
+
+void keepawayball_spawn()
+{
+	if(!g_keepaway){ remove(self); return; }
+	
+	if (!self.model) {
+		self.model = "models/keepaway/ballblue.md3";
+		self.scale = 0.8;
+	}
+
+	precache_model (self.model);
+	setmodel (self, self.model);
+	setsize (self, BALL_MINS, BALL_MAXS);
+	ball_scale = self.scale;
+	self.classname = "keepawayball";
+	
+	self.damageforcescale = cvar("g_keepawayball_damageforcescale");
+	
+	self.effects = self.effects | EF_FULLBRIGHT;
+	
+	self.movetype = MOVETYPE_BOUNCE;
+	
+	self.touch = keepawayball_touch;
+	self.think = keepawayball_respawn;
+	self.nextthink = time;
+	
+	self.noise = "sound/nexball/bounce.wav";
+	
+	precache_sound (self.noise);
+	
+	WaypointSprite_AttachCarrier("ka-ball", self);
+}
+
+float keepawayball_spawn_somewhere(entity e)
+{
+	if(MoveToRandomMapLocation(e, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, 10, 1024, 256))
+	{
+		makevectors(self.angles),
+		self.movetype = MOVETYPE_BOUNCE;
+		self.velocity = '0 0 200' + '0 100 0'*crandom() + '100 0 0'*crandom();
+		self.angles = '0 0 0';
+		return TRUE;
+	}
+	else
+	{
+		// sorry, can't spawn, better luck next frame
+		return FALSE;
+	}
+}
+
+void keepawayball_respawn()
+{
+	if(keepawayball_spawn_somewhere(self))
+	{
+		self.solid = SOLID_TRIGGER;
+		//self.movetype = MOVETYPE_TOSS;
+		self.touch = keepawayball_touch;
+		self.think = keepawayball_respawn;
+		self.nextthink = time + cvar("g_keepawayball_respawntime");
+	}
+	else
+	{
+		// try again later
+		self.think = keepawayball_respawn;
+		self.nextthink = time;
+	}
+}
+
+void DropBallKA (entity plyr, entity ball)
+{
+	entity player;
+	
+	setattachment(ball, world, "");
+	ball.movetype = MOVETYPE_BOUNCE;
+	ball.solid = SOLID_TRIGGER;
+	ball.wait = time + 1;
+	ball.ctf_droptime = time;
+	ball.think = keepawayball_respawn;
+	ball.nextthink = time + cvar("g_keepawayball_respawntime");
+	ball.touch = keepawayball_touch;
+	plyr.effects = EF_LOWPRECISION;
+	plyr.alpha = 1.0;
+	ball.alpha = 1.0;
+	setorigin(ball, plyr.origin + '0 0 10');
+	ball.velocity = '0 0 200' + '0 100 0'*crandom() + '100 0 0'*crandom();
+	
+	bprint(plyr.netname, "^7 has dropped the ball!\n");
+	WriteByte(MSG_BROADCAST, SVC_CENTERPRINT);
+	WriteString(MSG_BROADCAST, strcat("\n\n", plyr.netname, "^7 has dropped the ball!\n"));
+    sound(other, CHAN_AUTO, "keepaway/dropped.wav", VOL_BASE, ATTN_NORM);	
+	
+	PlayerScore_Add(plyr, SP_KEEPAWAY_DROPS, 1);
+	
+	WaypointSprite_AttachCarrier("ka-ball", ball);
+	WaypointSprite_Kill(plyr.waypointsprite_attachedforcarrier);
+	
+	ball.owner.kaballcarried = world;
+	ball.owner = world;
+}
+
+float holdtime;
+float keepaway_point_time;
+void KeepAway_Score()
+{
+	if(g_keepaway_win_mode == 0)
+	{
+		entity ball;
+	
+		if(!g_keepaway || !cvar("g_keepaway_pointamt"))
+			return;
+
+		if(gameover)
+			return;
+
+		if(keepaway_point_time > time)
+			return;
+
+		keepaway_point_time = time + cvar("g_keepaway_pointrate");
+		ball = world;
+		do
+		{
+			ball = find(ball, classname, "keepawayball");
+			if(!ball)
+				return;
+			if(ball.owner.classname == "player")
+				PlayerScore_Add(ball.owner, SP_KEEPAWAY_SCORE, cvar("g_keepaway_pointamt"));
+		}while(ball);
+	}
+}
+
+float KeepAway_HandleFrags(entity attacker, entity targ, float f)
+{	
+	if(f <= 0)
+		return f;
+	
+	if(attacker == targ)
+	{
+		return f;
+	}
+
+	if(targ.kaballcarried) // get amount of times killing carrier
+		PlayerScore_Add(attacker, SP_KEEPAWAY_CARRIERKILLS, 1);
+	
+	if(g_keepaway_win_mode == 1)
+		if(attacker.kaballcarried) // get kills as carrier
+			PlayerScore_Add(attacker, SP_KEEPAWAY_SCORE, cvar("g_keepaway_pointamt"));
+			
+	return f;
+}
+
+void ka_init()
+{
+	if(!g_keepaway)
+		return;
+		
+	precache_sound("keepaway/pickedup.wav");
+	precache_sound("keepaway/dropped.wav");
+	
+	entity e;
+	e = spawn();
+	e.think = keepawayball_spawn;
+	e.nextthink = time;
+}
Index: data/qcsrc/server/progs.src
===================================================================
--- data/qcsrc/server/progs.src	(revision 7552)
+++ data/qcsrc/server/progs.src	(working copy)
@@ -123,6 +123,7 @@
 domination.qc
 mode_onslaught.qc
 nexball.qc
+keepaway.qc
 g_hook.qc
 
 t_swamp.qc
Index: data/qcsrc/server/scores_rules.qc
===================================================================
--- data/qcsrc/server/scores_rules.qc	(revision 7552)
+++ data/qcsrc/server/scores_rules.qc	(working copy)
@@ -185,3 +185,18 @@
 	ScoreInfo_SetLabel_PlayerScore(SP_NEXBALL_FAULTS, "faults", SFL_SORT_PRIO_SECONDARY | SFL_LOWER_IS_BETTER);
 	ScoreRules_basics_end();
 }
+
+// Keep Away stuff
+#define SP_KEEPAWAY_PICKUPS 4
+#define SP_KEEPAWAY_CARRIERKILLS 5
+#define SP_KEEPAWAY_DROPS 6
+#define SP_KEEPAWAY_SCORE 7
+void ScoreRules_keepaway()
+{
+	ScoreRules_basics(0, SFL_SORT_PRIO_PRIMARY, 0, FALSE);
+	ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_SCORE, 		 "score", 	 SFL_SORT_PRIO_PRIMARY);
+	ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_PICKUPS,      "pickups",  0);
+	ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_CARRIERKILLS, "bckills",  0);
+	ScoreInfo_SetLabel_PlayerScore(SP_KEEPAWAY_DROPS,        "drops",    SFL_LOWER_IS_BETTER);
+	ScoreRules_basics_end();
+}
Index: data/qcsrc/server/sv_main.qc
===================================================================
--- data/qcsrc/server/sv_main.qc	(revision 7552)
+++ data/qcsrc/server/sv_main.qc	(working copy)
@@ -129,6 +129,7 @@
 =============
 */
 void RuneMatchGivePoints();
+void KeepAway_Score();
 float RedirectionThink();
 entity SelectSpawnPoint (float anypoint);
 void StartFrame (void)
@@ -222,6 +223,7 @@
 	AuditTeams();
 
 	RuneMatchGivePoints();
+	KeepAway_Score();
 	bot_serverframe();
 
 	if(cvar("spawn_debugview"))
Index: data/qcsrc/server/teamplay.qc
===================================================================
--- data/qcsrc/server/teamplay.qc	(revision 7552)
+++ data/qcsrc/server/teamplay.qc	(working copy)
@@ -70,6 +70,7 @@
 void runematch_init();
 void tdm_init();
 void nb_init();
+void ka_init();
 void entcs_init();
 
 void LogTeamchange(entity pl)
@@ -99,6 +100,7 @@
 	cvar_set("g_race", ftos(g_race));
 	cvar_set("g_nexball", ftos(g_nexball));
 	cvar_set("g_cts", ftos(g_cts));
+	cvar_set("g_keepaway", ftos(g_keepaway));
 }
 
 void ReadGameCvars()
@@ -124,6 +126,7 @@
 		found += (g_race = (!found && (prev != GAME_RACE) && cvar("g_race")));
 		found += (g_nexball = (!found && (prev != GAME_NEXBALL) && cvar("g_nexball")));
 		found += (g_cts = (!found && (prev != GAME_CTS) && cvar("g_cts")));
+		found += (g_keepaway = (!found && (prev != GAME_KEEPAWAY) && cvar("g_keepaway")));
 
 		if(found)
 			break;
@@ -351,6 +354,17 @@
 		ActivateTeamplay();
 		nb_init();
 	}
+	
+	if(g_keepaway)
+	{
+		game = GAME_KEEPAWAY;
+		gamemode_name = "Keep Away";
+		g_keepaway_win_mode = cvar("g_keepaway_win_mode");
+		fraglimit_override = cvar("g_keepaway_pointlimit");
+		leadlimit_override = cvar("g_keepaway_pointleadlimit");
+		ka_init();
+		ScoreRules_keepaway();
+	}
 
 	if(teams_matter)
 		entcs_init();
Index: data/qcsrc/server/waypointsprites.qc
===================================================================
--- data/qcsrc/server/waypointsprites.qc	(revision 7552)
+++ data/qcsrc/server/waypointsprites.qc	(working copy)
@@ -211,7 +211,7 @@
 
 	sendflags = sendflags & 0x7F;
 	
-	if(g_nexball)
+	if(g_nexball || g_keepaway)
 		sendflags &~= 0x80;
 	else if(self.max_health || (self.pain_finished && (time < self.pain_finished + 0.25)))
 		sendflags |= 0x80;
