r2996 - in branches/nexuiz-2.0/data: . gfx maps models models/onslaught models/sprites qcsrc/common qcsrc/menu qcsrc/server scripts textures textures/evil1_metals

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Thu Nov 29 02:56:25 EST 2007


Author: div0
Date: 2007-11-29 02:56:24 -0500 (Thu, 29 Nov 2007)
New Revision: 2996

Added:
   branches/nexuiz-2.0/data/gfx/font_user0.tga
   branches/nexuiz-2.0/data/gfx/font_user0.width
   branches/nexuiz-2.0/data/maps/aggressor.mapinfo
   branches/nexuiz-2.0/data/maps/aneurysm.mapinfo
   branches/nexuiz-2.0/data/maps/basement.mapinfo
   branches/nexuiz-2.0/data/maps/basementctf.mapinfo
   branches/nexuiz-2.0/data/maps/bleach.mapinfo
   branches/nexuiz-2.0/data/maps/bloodprison.mapinfo
   branches/nexuiz-2.0/data/maps/bluesky.mapinfo
   branches/nexuiz-2.0/data/maps/darkzone.mapinfo
   branches/nexuiz-2.0/data/maps/dieselpower.mapinfo
   branches/nexuiz-2.0/data/maps/dismal.mapinfo
   branches/nexuiz-2.0/data/maps/downer.mapinfo
   branches/nexuiz-2.0/data/maps/evilspace.mapinfo
   branches/nexuiz-2.0/data/maps/farewell.mapinfo
   branches/nexuiz-2.0/data/maps/final_rage.mapinfo
   branches/nexuiz-2.0/data/maps/reslimed.mapinfo
   branches/nexuiz-2.0/data/maps/ruiner.mapinfo
   branches/nexuiz-2.0/data/maps/runningman.mapinfo
   branches/nexuiz-2.0/data/maps/runningman_1on1remix.mapinfo
   branches/nexuiz-2.0/data/maps/runningmanctf.mapinfo
   branches/nexuiz-2.0/data/maps/silvercity.mapinfo
   branches/nexuiz-2.0/data/maps/skyway.mapinfo
   branches/nexuiz-2.0/data/maps/slimepit.mapinfo
   branches/nexuiz-2.0/data/maps/soylent.mapinfo
   branches/nexuiz-2.0/data/maps/starship.mapinfo
   branches/nexuiz-2.0/data/maps/stormkeep.mapinfo
   branches/nexuiz-2.0/data/maps/strength.mapinfo
   branches/nexuiz-2.0/data/maps/toxic.mapinfo
   branches/nexuiz-2.0/data/maps/warfare.mapinfo
   branches/nexuiz-2.0/data/models/onslaught/
   branches/nexuiz-2.0/data/models/onslaught/pad.dpm
   branches/nexuiz-2.0/data/models/onslaught/reactor.dpm
   branches/nexuiz-2.0/data/models/onslaught/shield.dpm
   branches/nexuiz-2.0/data/models/sprites/defend.sp2
   branches/nexuiz-2.0/data/models/sprites/defend.tga
   branches/nexuiz-2.0/data/models/sprites/destroy.sp2
   branches/nexuiz-2.0/data/models/sprites/destroy.tga
   branches/nexuiz-2.0/data/models/sprites/push.sp2
   branches/nexuiz-2.0/data/models/sprites/push.tga
   branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc
   branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qh
   branches/nexuiz-2.0/data/qcsrc/server/assault.qc
   branches/nexuiz-2.0/data/textures/core.tga
   branches/nexuiz-2.0/data/textures/core_gloss.tga
   branches/nexuiz-2.0/data/textures/core_glow.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_cln_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_cln_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty2_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty2_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_rusty_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_rusty_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cln_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cln_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cmbo_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cmbo_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty2_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty2_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_rusty_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_rusty_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst2_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst2_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst3_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst3_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst4_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst4_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst5_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst5_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1b_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1b_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2b_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2b_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2c_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2c_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2d_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2d_gloss.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2e_bump.tga
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2e_gloss.tga
   branches/nexuiz-2.0/data/textures/pad.tga
   branches/nexuiz-2.0/data/textures/pad_gloss.tga
   branches/nexuiz-2.0/data/textures/pad_glow.tga
   branches/nexuiz-2.0/data/textures/pad_shirt.tga
   branches/nexuiz-2.0/data/textures/reactor.jpg
   branches/nexuiz-2.0/data/textures/reactor.tga
   branches/nexuiz-2.0/data/textures/reactor_glow.tga
   branches/nexuiz-2.0/data/textures/reactor_shirt.tga
   branches/nexuiz-2.0/data/textures/shield.tga
   branches/nexuiz-2.0/data/textures/shield_gloss.tga
   branches/nexuiz-2.0/data/textures/shield_glow.tga
   branches/nexuiz-2.0/data/textures/shield_norm.tga
Removed:
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2c_bump.jpg
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2c_gloss.jpg
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2d_bump.jpg
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2d_gloss.jpg
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2e_bump.jpg
   branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2e_gloss.jpg
Modified:
   branches/nexuiz-2.0/data/default.cfg
   branches/nexuiz-2.0/data/effectinfo.txt
   branches/nexuiz-2.0/data/game_reset.cfg
   branches/nexuiz-2.0/data/high.cfg
   branches/nexuiz-2.0/data/low.cfg
   branches/nexuiz-2.0/data/med.cfg
   branches/nexuiz-2.0/data/normal.cfg
   branches/nexuiz-2.0/data/omg.cfg
   branches/nexuiz-2.0/data/qcsrc/common/campaign_setup.qc
   branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc
   branches/nexuiz-2.0/data/qcsrc/common/util.qc
   branches/nexuiz-2.0/data/qcsrc/common/util.qh
   branches/nexuiz-2.0/data/qcsrc/menu/gamecommand.qc
   branches/nexuiz-2.0/data/qcsrc/menu/msys.qc
   branches/nexuiz-2.0/data/qcsrc/server/bots.qc
   branches/nexuiz-2.0/data/qcsrc/server/campaign.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc
   branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
   branches/nexuiz-2.0/data/qcsrc/server/constants.qh
   branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
   branches/nexuiz-2.0/data/qcsrc/server/defs.qh
   branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
   branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc
   branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
   branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc
   branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc
   branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
   branches/nexuiz-2.0/data/qcsrc/server/mode_onslaught.qc
   branches/nexuiz-2.0/data/qcsrc/server/progs.src
   branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc
   branches/nexuiz-2.0/data/qcsrc/server/t_items.qc
   branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_rocketlauncher.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc
   branches/nexuiz-2.0/data/scripts/final_rage.shader
   branches/nexuiz-2.0/data/ultimate.cfg
   branches/nexuiz-2.0/data/ultra.cfg
Log:
trunk->branch merge:
- worldspawn() fixes for precaching
- tuned speed rune
- improved evil1_metals
- Onslaught and Assault models/sprites (these game modes still need testing, but Assault should be in known working state now)
- no more flashblend in *.cfg
- optional mapinfo system (needs testing; compile qcsrc/server with -DMAPINFO to use it)


Modified: branches/nexuiz-2.0/data/default.cfg
===================================================================
--- branches/nexuiz-2.0/data/default.cfg	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/default.cfg	2007-11-29 07:56:24 UTC (rev 2996)
@@ -69,6 +69,7 @@
 freelook 1
 sensitivity 6
 seta scmenu_mouse_speed 1
+set scmenu_directmenu ""
 v_gamma 1.125000
 viewsize 110
 bgmvolume 1
@@ -144,6 +145,7 @@
 cl_movement_maxairspeed $sv_maxairspeed
 cl_movement_maxspeed $sv_maxspeed
 cl_movement_stepheight $sv_stepheight
+cl_movement_track_canjump 0 // till DP bug gets fixed
 
 seta cl_playerdetailreduction 0 // the higher, the less detailed
 
@@ -206,6 +208,8 @@
 set g_minstagib_ammo_start 10	// starting ammo
 set g_minstagib_ammo_drop 5	// how much ammo you'll get for weapons or cells
 set g_minstagib_invis_alpha 0.1 // set -1 for complete invisibility
+set g_minstagib_speed_jumpheight 1.8
+set g_minstagib_speed_moverate 1.25
 set g_rocketarena 0
 set g_vampire 0
 set g_laserguided_missile 0
@@ -294,6 +298,9 @@
 set g_changeteam_banned			0	// not allowed to change team
 set g_changeteam_fragtransfer		0	// % of frags you get to keep when you change teams (rounded down)
 
+// dm
+set g_dm 1 // actually, this is a dummy cvar just to make the menu happy
+
 // ctf
 set g_ctf				0
 set g_ctf_flag_returntime		30
@@ -352,10 +359,10 @@
 set g_balance_rune_speed_atkrate				0.66
 set g_balance_curse_slow_atkrate				1.5
 set g_balance_rune_speed_combo_atkrate			1.2
-set g_balance_rune_speed_moverate			1.33
+set g_balance_rune_speed_moverate			1.25
 set g_balance_curse_slow_moverate			0.8
 set g_balance_rune_speed_combo_moverate			0.9
-set g_balance_rune_speed_jumpheight			1.8
+set g_balance_rune_speed_jumpheight			1.4
 set g_balance_curse_slow_jumpheight			1.0
 set g_balance_rune_speed_combo_jumpheight		1.0
 
@@ -397,6 +404,9 @@
 // onslaught
 set g_onslaught 0
 
+// assault
+set g_assault 0
+
 // server game balance settings
 set g_balance_armor_regen 0
 set g_balance_armor_rot 0.1
@@ -740,10 +750,10 @@
 alias adminmsg             "sv_cmd adminmsg $*"
 alias teamstatus           "sv_cmd teamstatus"
 alias printstats           "sv_cmd printstats" // print status on demand
-alias g_maplist_add        "qc_cmd rpn /maps/$1.mapcfg fexists_assert /g_maplist g_maplist /'$1' union def"
-alias g_maplist_remove     "qc_cmd rpn /g_maplist g_maplist /'$1' difference def"
-alias g_maplist_putfirst   "qc_cmd rpn /maps/$1.mapcfg fexists_assert /g_maplist /'$1' g_maplist union def"
-alias g_maplist_shufflenow "qc_cmd rpn /g_maplist g_maplist shuffle def"
+alias g_maplist_add        "qc_cmd maplist add $*"
+alias g_maplist_remove     "qc_cmd maplist remove $*"
+alias g_maplist_putfirst   "qc_cmd maplist remove $* ; qc_cmd maplist add $*"
+alias g_maplist_shufflenow "qc_cmd maplist shuffle"
 
 // key hunt
 set g_keyhunt 0
@@ -779,3 +789,11 @@
 alias unban "sv_cmd unban $*"     // usage: unban 3 (number from bans)
 
 r_labelsprites_scale 0.40625 // labels sprites get displayed at 0.5x from 640x480 to 1280x1024, and at 1x from 1600x1200 onwards
+
+// settemp subsystem. Do not touch. Usage: settemp variable value; next map resets it.
+set settemp_list 0
+set settemp_var _settemp_x
+alias settemp "settemp_list \"1 $1 $settemp_var $settemp_list\"; set $settemp_var \"${$1}\"; settemp_var ${settemp_var}x; $1 \"$2\""
+alias settemp_restore "_settemp_restore_${settemp_list asis}"
+alias _settemp_restore_0 "set settemp_var _settemp_x; set settemp_list 0"
+alias _settemp_restore_1 "$1 \"${$2}\"; _settemp_restore_${3- asis}"

Modified: branches/nexuiz-2.0/data/effectinfo.txt
===================================================================
--- branches/nexuiz-2.0/data/effectinfo.txt	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/effectinfo.txt	2007-11-29 07:56:24 UTC (rev 2996)
@@ -17,9 +17,9 @@
 color 0x63F2EA 0x63f2EA
 size 20 20
 alpha 128 128 128
-lightradius 200
-lightradiusfade 200
-lightcolor 0.4 0.9 0.9
+lightradius 100
+lightradiusfade 100
+lightcolor 1 2 2
 // cloud of particles which expand rapidly and then slow to form a ball
 effect TE_WIZSPIKE
 count 100
@@ -53,8 +53,8 @@
 alpha 256 256 0
 originjitter 16 16 16
 lightradius 200
-lightradiusfade 1000
-lightcolor 4 0.2 0.2
+lightradiusfade 500
+lightcolor 8 0.4 0.4
 // flare effect
 effect TE_KNIGHTSPIKE
 countabsolute 1
@@ -85,6 +85,9 @@
 size 5 5
 alpha 256 256 0
 originjitter 6 6 6
+//lightradius 30
+//lightradiusfade 90
+//lightcolor 1 1 1
 // dust/smoke drifting away from the impact
 effect TE_SPIKE
 count 8
@@ -129,8 +132,8 @@
 alpha 256 256 0
 originjitter 34 34 34
 lightradius 400
-lightradiusfade 200
-lightcolor 2 2.5 3
+lightradiusfade 300
+lightcolor 4 5 6
 // flare effect
 effect TE_SPIKEQUAD
 countabsolute 1
@@ -138,7 +141,7 @@
 tex 38 38
 color 0x80C0FF 0x80C0FF
 size 48 48
-alpha 256 256 128
+alpha 128 128 64
 // large sparks
 effect TE_SPIKEQUAD
 count 20
@@ -263,6 +266,9 @@
 size 3 3
 alpha 256 256 0
 originjitter 6 6 6
+//lightradius 30
+//lightradiusfade 90
+//lightcolor 1 1 1
 // dust/smoke drifting away from the impact
 effect TE_GUNSHOT
 count 4
@@ -354,9 +360,9 @@
 size 8 8
 alpha 256 256 0
 originjitter 12 12 12
-//lightradius 100
-//lightradiusfade 300
-//lightcolor 0.5 0.5 0.5
+//lightradius 30
+//lightradiusfade 60
+//lightcolor 1.6 0.2 2
 // purple flare effect
 effect TE_GUNSHOTQUAD
 countabsolute 1
@@ -386,9 +392,9 @@
 size 48 48
 alpha 256 256 0
 originjitter 40 40 40
-lightradius 350
-lightradiusfade 700
-lightcolor 4 2 0.5
+lightradius 250
+lightradiusfade 400
+lightcolor 8 4 1
 // flare effect
 effect TE_EXPLOSION
 countabsolute 1
@@ -620,9 +626,9 @@
 size 24 24
 alpha 256 256 0
 originjitter 16 16 16
-lightradius 200
-lightradiusfade 400
-lightcolor 1 1 1
+lightradius 100
+lightradiusfade 300
+lightcolor 4 6 8
 // flare effect
 effect TE_PLASMABURN
 countabsolute 1
@@ -760,9 +766,9 @@
 size 72 72
 alpha 256 256 0
 originjitter 40 40 40
-lightradius 500
-lightradiusfade 500
-lightcolor 4 2 0.5
+lightradius 400
+lightradiusfade 400
+lightcolor 8 4 1
 // flare effect
 effect TE_TEI_BIGEXPLOSION
 countabsolute 1
@@ -823,9 +829,9 @@
 size 32 32
 alpha 256 256 0
 originjitter 20 20 20
-lightradius 200
-lightradiusfade 600
-lightcolor 2.4 4.8 8
+lightradius 250
+lightradiusfade 250
+lightcolor 4 4 10
 // flare effect
 effect TE_TEI_PLASMAHIT
 countabsolute 1
@@ -867,9 +873,9 @@
 tex 0 8
 size 3 3
 alpha 32 32 32
-lightradius 200
+lightradius 150
 lighttime 0
-lightcolor 3.0 1.5 0.5
+lightcolor 6 3 1
 // fire
 effect TR_ROCKET
 notunderwater
@@ -983,9 +989,9 @@
 size 4 4
 alpha 256 256 1024
 velocityjitter 16 16 16
-lightradius 200
+lightradius 90
 lighttime 0
-lightcolor 0.75 1.5 3.0
+lightcolor 1.5 3 6
 velocitymultiplier -0.1
 
 // quake effect

Modified: branches/nexuiz-2.0/data/game_reset.cfg
===================================================================
--- branches/nexuiz-2.0/data/game_reset.cfg	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/game_reset.cfg	2007-11-29 07:56:24 UTC (rev 2996)
@@ -3,6 +3,8 @@
 // won't stick around when the user starts a new dm map.
 
 // clean up campaign stuff
+settemp_restore
+
 alias _mutator_reset_0 ""
 alias _mutator_reset_1 "exec mutator_reset.cfg"
 _mutator_reset_$g_campaign
@@ -15,8 +17,8 @@
 set g_arena 0
 set g_campaign 0
 set g_keyhunt 0
+set g_assault 0
 set g_onslaught 0
-set teamplay 0
 set gamecfg 0
 
 set g_respawn_mapsettings_delay 0

Added: branches/nexuiz-2.0/data/gfx/font_user0.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/gfx/font_user0.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/gfx/font_user0.width
===================================================================
--- branches/nexuiz-2.0/data/gfx/font_user0.width	                        (rev 0)
+++ branches/nexuiz-2.0/data/gfx/font_user0.width	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,17 @@
+extraspacing 0.1
+0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000
+0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000
+0.28125 0.37500 0.43750 0.68750 0.56250 0.81250 0.71875 0.25000 0.37500 0.37500 0.43750 0.68750 0.31250 0.34375 0.31250 0.31250
+0.56250 0.56250 0.56250 0.56250 0.56250 0.56250 0.56250 0.56250 0.56250 0.56250 0.31250 0.31250 0.68750 0.68750 0.68750 0.46875
+0.81250 0.62500 0.62500 0.59375 0.68750 0.56250 0.56250 0.65625 0.68750 0.31250 0.37500 0.65625 0.53125 0.81250 0.68750 0.68750
+0.59375 0.68750 0.62500 0.59375 0.56250 0.65625 0.62500 0.90625 0.62500 0.59375 0.59375 0.37500 0.31250 0.37500 0.68750 0.40625
+0.40625 0.56250 0.59375 0.46875 0.59375 0.56250 0.37500 0.59375 0.59375 0.28125 0.31250 0.56250 0.28125 0.84375 0.59375 0.56250
+0.59375 0.59375 0.40625 0.46875 0.37500 0.59375 0.53125 0.75000 0.53125 0.53125 0.46875 0.59375 0.31250 0.59375 0.68750 0.90000
+0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000
+0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000 0.90000
+0.28125 0.37500 0.43750 0.59375 0.56250 0.81250 0.71875 0.25000 0.37500 0.40625 0.43750 0.68750 0.37500 0.34375 0.31250 0.43750
+0.56250 0.56250 0.56250 0.56250 0.56250 0.56250 0.56250 0.56250 0.56250 0.56250 0.31250 0.37500 0.68750 0.68750 0.68750 0.46875
+0.81250 0.68750 0.62500 0.59375 0.68750 0.59375 0.59375 0.65625 0.68750 0.34375 0.43750 0.68750 0.53125 0.81250 0.68750 0.68750
+0.59375 0.68750 0.62500 0.59375 0.62500 0.65625 0.68750 0.93750 0.71875 0.65625 0.62500 0.37500 0.31250 0.40625 0.68750 0.43750
+0.40625 0.56250 0.59375 0.46875 0.59375 0.56250 0.43750 0.59375 0.59375 0.34375 0.46875 0.59375 0.34375 0.84375 0.59375 0.56250
+0.62500 0.59375 0.43750 0.46875 0.43750 0.59375 0.56250 0.75000 0.59375 0.56250 0.46875 0.59375 0.31250 0.59375 0.68750 0.90000

Modified: branches/nexuiz-2.0/data/high.cfg
===================================================================
--- branches/nexuiz-2.0/data/high.cfg	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/high.cfg	2007-11-29 07:56:24 UTC (rev 2996)
@@ -7,7 +7,6 @@
 gl_texture_anisotropy 16
 r_bloom 1
 r_coronas 1
-gl_flashblend 0
 r_glsl_deluxemapping 1
 r_glsl_offsetmapping 0
 r_glsl_offsetmapping_reliefmapping 0

Modified: branches/nexuiz-2.0/data/low.cfg
===================================================================
--- branches/nexuiz-2.0/data/low.cfg	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/low.cfg	2007-11-29 07:56:24 UTC (rev 2996)
@@ -7,7 +7,6 @@
 gl_texture_anisotropy 1
 r_bloom 0
 r_coronas 1
-gl_flashblend 0
 r_glsl_deluxemapping 0
 r_glsl_offsetmapping 0
 r_glsl_offsetmapping_reliefmapping 0

Added: branches/nexuiz-2.0/data/maps/aggressor.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/aggressor.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/aggressor.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Aggressor
+description Small map with brutal fast vertical action
+author Kevin "Tyrann" Shanahan, Paul Evers
+_diameter 2554.305176
+_spawnpoints 7
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/aneurysm.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/aneurysm.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/aneurysm.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Aneurysm
+description A multiple arena map with complex flow
+author Paul Evers
+_diameter 3652.639648
+_spawnpoints 8
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/basement.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/basement.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/basement.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Basement
+description A small map designed for fast constant gameplay
+author Garth Hendy
+_diameter 1966.839355
+_spawnpoints 5
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/basementctf.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/basementctf.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/basementctf.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,7 @@
+title Basement CTF
+description Remake of basement, "The Basement" for CTF
+author Clinton "Kaziganthe" Freeman
+_diameter 3282.301514
+_spawnpoints 15
+has weapons
+type ctf 300 20

Added: branches/nexuiz-2.0/data/maps/bleach.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/bleach.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/bleach.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,12 @@
+title Bleach
+description A large multiple arena map
+author Paul Evers
+_diameter 5181.482910
+_spawnpoints 14
+has weapons
+type dm 30 20
+type tdm 50 20 2
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type kh 1000 20 3

Added: branches/nexuiz-2.0/data/maps/bloodprison.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/bloodprison.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/bloodprison.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,9 @@
+title Blood Prison
+description Small and very fast Tourney Map
+author Paul Evers
+_diameter 4409.023926
+_spawnpoints 8
+has weapons
+type dm 30 20
+type tdm 50 20 2
+type lms 9 20

Added: branches/nexuiz-2.0/data/maps/bluesky.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/bluesky.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/bluesky.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,9 @@
+title Blue Sky
+description Small and fun map with a mighty jump
+author Strahlemann
+_diameter 6058.424805
+_spawnpoints 8
+has weapons
+type dm 30 20
+type tdm 50 20 2
+type lms 9 20

Added: branches/nexuiz-2.0/data/maps/darkzone.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/darkzone.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/darkzone.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Q1DM6 Remake
+description The Dark Zone returns
+author Maik Merten
+_diameter 3713.385986
+_spawnpoints 6
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/dieselpower.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/dieselpower.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/dieselpower.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,12 @@
+title Diesel Power
+description A large multiple arena map
+author Paul Evers
+_diameter 5221.383789
+_spawnpoints 13
+has weapons
+type dm 30 20
+type tdm 50 20 2
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type kh 1000 20 3

Added: branches/nexuiz-2.0/data/maps/dismal.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/dismal.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/dismal.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,12 @@
+title Dismal
+description Small space map
+author HReaper
+_diameter 4258.493652
+_spawnpoints 20
+has weapons
+type dm 30 20
+type tdm 50 20 2
+type dom 200 20
+type ctf 300 20
+type rune 200 20
+type lms 9 20

Added: branches/nexuiz-2.0/data/maps/downer.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/downer.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/downer.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Downer
+description A multilevel map
+author Eric Sambach, Maik Merten
+_diameter 2466.622070
+_spawnpoints 5
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/evilspace.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/evilspace.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/evilspace.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,9 @@
+title [evilspace]
+description A dark space map
+author Yves Allaire
+_diameter 3612.476074
+_spawnpoints 9
+has weapons
+type dm 30 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/farewell.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/farewell.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/farewell.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Farewell
+description Small and very fast Tourney Map
+author Tymo aka Henning Janssen
+author_email tymo at gmx.de
+author_www http://home.arcor.de/dwalinn/
+_diameter 3425.280029
+_spawnpoints 9
+has weapons
+type dm 30 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/final_rage.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/final_rage.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/final_rage.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Final rage
+description Small map with brutal fast vertical action
+author Munyul Verminard and tZork
+_diameter 3148.711426
+_spawnpoints 13
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/reslimed.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/reslimed.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/reslimed.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Slimepit Revisited
+description An industrial arena with deadly slime
+author Paul Evers, Mattrew Rye, Garth Hendy, Maik Merten
+_diameter 4519.555664
+_spawnpoints 10
+has weapons
+type dm 30 20
+type tdm 50 20 2
+type dom 200 20
+type rune 200 20
+type lms 9 20

Added: branches/nexuiz-2.0/data/maps/ruiner.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/ruiner.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/ruiner.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title RUINER
+description Small rusty map
+author Strahlemann
+_diameter 3795.349365
+_spawnpoints 9
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/runningman.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/runningman.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/runningman.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Running Man
+description Small DM-Level, best suited for 2 players
+author Paul Evers
+_diameter 3314.800781
+_spawnpoints 10
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/runningman_1on1remix.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/runningman_1on1remix.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/runningman_1on1remix.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,12 @@
+title Running Man (1on1)
+description DM-Level especially designed for 1on1 Matches
+author Paul Evers
+_diameter 3826.595459
+_spawnpoints 10
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20
+type kh 1000 20 3

Added: branches/nexuiz-2.0/data/maps/runningmanctf.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/runningmanctf.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/runningmanctf.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,13 @@
+title Running Man CTF
+description Medium-sized CTF-Map
+author Paul Evers
+_diameter 5930.995117
+_spawnpoints 16
+has weapons
+type dm 30 20
+type tdm 50 20 2
+type dom 200 20
+type ctf 300 20
+type rune 200 20
+type lms 9 20
+type kh 1000 20 3

Added: branches/nexuiz-2.0/data/maps/silvercity.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/silvercity.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/silvercity.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,13 @@
+title Silver City
+description A very large very open map
+author Forest Hale, Garth Hendy
+_diameter 6067.411133
+_spawnpoints 34
+has weapons
+type dm 30 20
+type tdm 50 20 2
+type dom 200 20
+type ctf 300 20
+type rune 200 20
+type lms 9 20
+type kh 1000 20 3

Added: branches/nexuiz-2.0/data/maps/skyway.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/skyway.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/skyway.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Skyway
+description Vertical arena
+author Mattrew Rye, Garth Hendy
+_diameter 3072.279541
+_spawnpoints 12
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/slimepit.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/slimepit.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/slimepit.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title The Slime Pit
+description An industrial arena
+author Mattrew Rye, Garth Hendy, Maik Merten
+_diameter 3227.077881
+_spawnpoints 7
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/soylent.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/soylent.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/soylent.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Soylent Space
+description Medium sized vertical level
+author Paul Evers
+_diameter 3869.519775
+_spawnpoints 6
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/starship.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/starship.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/starship.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,12 @@
+title Starship
+description A sprawling complex
+author Chris Matz
+_diameter 3048.152832
+_spawnpoints 27
+has weapons
+type dm 30 20
+type dom 200 20
+type ctf 300 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/stormkeep.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/stormkeep.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/stormkeep.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Stormkeep
+description A large slow paced medieval complex
+author William Libert, Maik Merten, Paul Evers
+_diameter 3965.079590
+_spawnpoints 8
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/strength.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/strength.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/strength.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Strength
+description Medium sized industrial arena with a lot vertical action under the hot desert sun
+author Strahlemann
+_diameter 3377.715088
+_spawnpoints 15
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/toxic.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/toxic.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/toxic.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Toxic
+description Fast competitive map
+author morfar
+_diameter 3458.378906
+_spawnpoints 10
+has weapons
+type dm 30 20
+type dom 200 20
+type rune 200 20
+type lms 9 20
+type arena 10 20

Added: branches/nexuiz-2.0/data/maps/warfare.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/warfare.mapinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/warfare.mapinfo	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,11 @@
+title Stabilized Warfare: Resurrection
+description Medium sized map with a central area
+author Tymo
+author_email tymo at gmx.de
+author_www http://home.arcor.de/dwalinn/
+_diameter 2806.050537
+_spawnpoints 8
+has weapons
+type dm 30 20
+type lms 9 20
+type arena 10 20

Modified: branches/nexuiz-2.0/data/med.cfg
===================================================================
--- branches/nexuiz-2.0/data/med.cfg	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/med.cfg	2007-11-29 07:56:24 UTC (rev 2996)
@@ -7,7 +7,6 @@
 gl_texture_anisotropy 1
 r_bloom 0
 r_coronas 1
-gl_flashblend 0
 r_glsl_deluxemapping 0
 r_glsl_offsetmapping 0
 r_glsl_offsetmapping_reliefmapping 0

Added: branches/nexuiz-2.0/data/models/onslaught/pad.dpm
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/models/onslaught/pad.dpm
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/models/onslaught/reactor.dpm
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/models/onslaught/reactor.dpm
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/models/onslaught/shield.dpm
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/models/onslaught/shield.dpm
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/models/sprites/defend.sp2
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/models/sprites/defend.sp2
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/models/sprites/defend.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/models/sprites/defend.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/models/sprites/destroy.sp2
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/models/sprites/destroy.sp2
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/models/sprites/destroy.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/models/sprites/destroy.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/models/sprites/push.sp2
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/models/sprites/push.sp2
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/models/sprites/push.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/models/sprites/push.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: branches/nexuiz-2.0/data/normal.cfg
===================================================================
--- branches/nexuiz-2.0/data/normal.cfg	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/normal.cfg	2007-11-29 07:56:24 UTC (rev 2996)
@@ -7,7 +7,6 @@
 gl_texture_anisotropy 1
 r_bloom 0
 r_coronas 1
-gl_flashblend 0
 r_glsl_deluxemapping 1
 r_glsl_offsetmapping 0
 r_glsl_offsetmapping_reliefmapping 0

Modified: branches/nexuiz-2.0/data/omg.cfg
===================================================================
--- branches/nexuiz-2.0/data/omg.cfg	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/omg.cfg	2007-11-29 07:56:24 UTC (rev 2996)
@@ -2,12 +2,11 @@
 cl_nogibs 0
 cl_particles_quality 0.20
 cl_particles_snow 0
-gl_picmip 10
+gl_picmip 1337
 r_picmipworld 1
 gl_texture_anisotropy 1
 r_bloom 0
 r_coronas 1
-gl_flashblend 0
 r_glsl_deluxemapping 0
 r_glsl_offsetmapping 0
 r_glsl_offsetmapping_reliefmapping 0

Modified: branches/nexuiz-2.0/data/qcsrc/common/campaign_setup.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/campaign_setup.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/common/campaign_setup.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -11,9 +11,14 @@
 		localcmd("\n");
 	localcmd(campaign_mutators[n]);
 		localcmd("\n");
+#ifdef MAPINFO
+	MapInfo_SwitchGameType(MapInfo_Type_FromString(campaign_gametype[n]));
+	MapInfo_LoadMap(campaign_mapname[n]);
+#else
 	localcmd("exec maps/"); // can't use strcat here in current fteqcc
 		localcmd(campaign_gametype[n]);
 		localcmd("_");
 		localcmd(campaign_mapname[n]);
 		localcmd(".mapcfg\n");
+#endif
 }

Modified: branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -46,6 +46,8 @@
 float GameCommand_Generic(string command)
 {
 	float argc;
+	float i, j, f, n;
+	string s, s2;
 	argc = tokenize(command);
 	if(argv(0) == "help")
 	{
@@ -62,18 +64,107 @@
 		print("    s shuffle -------------------------> s   : randomly arrange elements\n");
 		print("    Set operations operate on 'such''strings' like g_maplist.\n");
 		print("    Unknown tokens insert their cvar value.\n");
+		print("  maplist add map\n");
+		print("  maplist remove map\n");
+		print("  maplist shuffle\n");
 		return TRUE;
 	}
 	
-	if(argv(0) == "rpn")
+	if(argv(0) == "maplist")
 	{
+		if(argv(1) == "add" && argc == 3)
+		{
+#ifdef MAPINFO
+			f = fopen(strcat("maps/", argv(2), ".bsp"), FILE_READ);
+			if(f != -1)
+				fclose(f);
+			else {
+				print("maplist: ERROR: ", argv(2), " does not exist!\n");
+				return TRUE;
+			}
+			if(cvar_string("g_maplist") == "")
+				cvar_set("g_maplist", argv(2));
+			else
+				cvar_set("g_maplist", strcat(argv(2), " ", cvar_string("g_maplist")));
+#else
+			f = fopen(strcat("maps/", argv(2), ".mapcfg"), FILE_READ);
+			if(f != -1)
+				fclose(f);
+			else {
+				print("maplist: ERROR: ", argv(2), " does not exist!\n");
+				return TRUE;
+			}
+			cvar_set("g_maplist", strcat("'", argv(2), "'", cvar_string("g_maplist")));
+#endif
+			return TRUE;
+		}
+		else if(argv(1) == "remove" && argc == 3)
+		{
+			s = argv(2);
+#ifdef MAPINFO
+			n = tokenizebyseparator(cvar_string("g_maplist"), " ");
+#else
+			n = tokenize(cvar_string("g_maplist"));
+#endif
+			s2 = "";
+			for(i = 0; i < n; ++i)
+				if(argv(i) != s)
+				{
+#ifdef MAPINFO
+					s2 = strcat(s2, " ", argv(i));
+#else
+					s2 = strcat(s2, "'", argv(i), "'");
+#endif
+				}
+#ifdef MAPINFO
+			s2 = substring(s2, 1, strlen(s2) - 1);
+#endif
+			cvar_set("g_maplist", s2);
+			return TRUE;
+		}
+		else if(argv(1) == "shuffle" && argc == 2)
+		{
+			s = cvar_string("g_maplist");
+#ifdef MAPINFO
+			for(i = 1; i < (n = tokenizebyseparator(s, " ")); ++i)
+#else
+			for(i = 1; i < (n = tokenize(s)); ++i)
+#endif
+			{
+				// swap i-th item at a random position from 0 to i
+				// proof for even distribution:
+				//   n = 1: obvious
+				//   n -> n+1:
+				//     item n+1 gets at any position with chance 1/(n+1)
+				//     all others will get their 1/n chance reduced by factor n/(n+1)
+				//     to be on place n+1, their chance will be 1/(n+1)
+				//     1/n * n/(n+1) = 1/(n+1)
+				//     q.e.d.
+				f = ceil(random() * (i + 1)) - 1; // 0 to i
+				if(f == i)
+					continue; // no change
+
+				s2 = "";
+				for(j = 0; j < n; ++j)
+#ifdef MAPINFO
+					s2 = strcat(s2, " ", argv((j == i) ? f : (j == f) ? i : j));
+				s = substring(s2, 1, strlen(s2) - 1);
+#else
+					s2 = strcat(s2, "'", argv((j == i) ? f : (j == f) ? i : j), "'");
+				s = s2;
+#endif
+			}
+			cvar_set("g_maplist", s);
+			return TRUE;
+		}
+	}
+	else if(argv(0) == "rpn")
+	{
 		if(argc >= 2)
 		{
 			float rpnpos;
 			string rpncmd;
-			string s, s2;
-			float f, f2;
-			float i, j;
+			float f2;
 			rpn_sp = 0;
 			rpn_error = FALSE;
 			for(rpnpos = 1; rpnpos < argc; ++rpnpos)

Added: branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,600 @@
+// HUGE SET - stored in a string
+string HugeSetOfIntegers_empty()
+{
+	return "";
+}
+float HugeSetOfIntegers_get(string pArr, float i)
+{
+	return stof(substring(pArr, i * 4, 4));
+}
+float HugeSetOfIntegers_length(string pArr)
+{
+	return strlen(pArr) / 4;
+}
+string HugeSetOfIntegers_concat(string a1, string a2)
+{
+	return strcat(a1, a2);
+}
+string HugeSetOfIntegers_insert(string a1, float n, string a2)
+	// special concat function to build up large lists in less time by binary concatenation
+{
+	string s;
+	s = strcat("    ", ftos(n));
+	return strcat(a1, substring(s, strlen(s) - 4, 4), a2);
+}
+
+// generic string stuff
+float startsWith(string haystack, string needle)
+{
+	return substring(haystack, 0, strlen(needle)) == needle;
+}
+string extractRestOfLine(string haystack, string needle)
+{
+	if(startsWith(haystack, needle))
+		return substring(haystack, strlen(needle), strlen(haystack) - strlen(needle));
+	return string_null;
+}
+string car(string s)
+{
+	float o;
+	o = strstrofs(s, " ", 0);
+	if(o < 0)
+		return s;
+	return substring(s, 0, o);
+}
+string cdr(string s)
+{
+	float o;
+	o = strstrofs(s, " ", 0);
+	if(o < 0)
+		return string_null;
+	return substring(s, o + 1, strlen(s) - (o + 1));
+}
+
+// GLOB HANDLING (for all BSP files)
+float _MapInfo_globopen;
+float _MapInfo_globcount; 
+float _MapInfo_globhandle;
+string _MapInfo_GlobItem(float i)
+{
+	string s;
+	s = search_getfilename(_MapInfo_globhandle, i);
+	return substring(s, 5, strlen(s) - 9); // without maps/ and .bsp
+}
+
+void MapInfo_Enumerate()
+{
+	if(_MapInfo_globopen)
+		search_end(_MapInfo_globhandle);
+	_MapInfo_globhandle = search_begin("maps/*.bsp", TRUE, TRUE);
+	_MapInfo_globcount = search_getsize(_MapInfo_globhandle);
+	_MapInfo_globopen = 1;
+}
+
+// filter the info by game type mask (updates MapInfo_count)
+string _MapInfo_filtered;
+string MapInfo_FilterGametype_Recursive(float pGametype, float pFeatures, float pBegin, float pEnd, float pAbortOnGenerate)
+{
+	float m, valid;
+	string l, r;
+
+	if(pBegin == pEnd)
+		return HugeSetOfIntegers_empty();
+
+	m = floor((pBegin + pEnd) / 2);
+
+	l = MapInfo_FilterGametype_Recursive(pGametype, pFeatures, pBegin, m, pAbortOnGenerate);
+	if not(l)
+		return string_null; // BAIL OUT
+	if(MapInfo_Get_ByName(_MapInfo_GlobItem(m), 1, 0) == 2) // if we generated one... BAIL OUT and let the caller continue in the next frame.
+		if(pAbortOnGenerate)
+			return string_null; // BAIL OUT
+	valid = (((MapInfo_Map_supportedGametypes & pGametype) != 0) && ((MapInfo_Map_supportedFeatures & pFeatures) == pFeatures));
+	r = MapInfo_FilterGametype_Recursive(pGametype, pFeatures, m + 1, pEnd, pAbortOnGenerate);
+	if not(r)
+		return string_null; // BAIL OUT
+
+	if(valid)
+		return HugeSetOfIntegers_insert(l, m, r);
+	else
+		return HugeSetOfIntegers_concat(l, r);
+}
+float MapInfo_FilterGametype(float pGametype, float pFeatures, float pAbortOnGenerate)
+{
+	if(_MapInfo_filtered)
+		strunzone(_MapInfo_filtered);
+	_MapInfo_filtered = MapInfo_FilterGametype_Recursive(pGametype, pFeatures, 0, _MapInfo_globcount, pAbortOnGenerate);
+	if not(_MapInfo_filtered)
+	{
+		dprint("Autogenerated a .mapinfo, doing the rest later.\n");
+		return 0;
+	}
+	_MapInfo_filtered = strzone(_MapInfo_filtered);
+	MapInfo_count = HugeSetOfIntegers_length(_MapInfo_filtered);
+	//print("Filter ", ftos(pGametype), "/", ftos(pFeatures), " has ", ftos(MapInfo_count), "\n");
+	// TODO clear cache
+	return 1;
+}
+
+// load info about the i-th map into the MapInfo_Map_* globals
+string MapInfo_BSPName_ByID(float i)
+{
+	return _MapInfo_GlobItem(HugeSetOfIntegers_get(_MapInfo_filtered, i));
+}
+
+string unquote(string s)
+{
+	float i, j, l;
+	l = strlen(s);
+	j = -1;
+	for(i = 0; i < l; ++i)
+	{
+		string ch;
+		ch = substring(s, i, 1);
+		if(ch != " ") if(ch != "\"")
+		{
+			for(j = strlen(s) - i - 1; j > 0; --j)
+			{
+				ch = substring(s, i+j, 1);
+				if(ch != " ") if(ch != "\"")
+					return substring(s, i, j+1);
+			}
+			return substring(s, i, 1);
+		}
+	}
+	return "";
+}
+
+float MapInfo_Get_ByID(float i)
+{
+	// TODO check cache
+	if(MapInfo_Get_ByName(MapInfo_BSPName_ByID(i), 0, 0))
+	{
+		// TODO save in cache
+		return 1;
+	}
+	return 0;
+}
+
+float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp
+{
+	string fn;
+	float fh;
+	string s, k, v;
+	vector o;
+	float i;
+	float inWorldspawn;
+	float r;
+	float twoBaseModes;
+
+	vector mapMins, mapMaxs;
+
+	r = 1;
+	fn = strcat("maps/", pFilename, ".ent");
+	fh = fopen(fn, FILE_READ);
+	if(fh < 0)
+	{
+		r = 2;
+		fn = strcat("maps/", pFilename, ".bsp");
+		fh = fopen(fn, FILE_READ);
+	}
+	if(fh < 0)
+		return 0;
+	print("Analyzing ", fn, " to generate initial mapinfo; please edit that file later\n");
+
+	inWorldspawn = 2;
+	MapInfo_Map_supportedGametypes = 0;
+
+	for(;;)
+	{
+		if not((s = fgets(fh)))
+			break;
+		if(inWorldspawn == 1)
+			if(startsWith(s, "}"))
+				inWorldspawn = 0;
+		k = unquote(car(s));
+		v = unquote(cdr(s));
+		if(inWorldspawn)
+		{
+			if(k == "classname" && v == "worldspawn")
+				inWorldspawn = 1;
+			else if(k == "author")
+				MapInfo_Map_author = v;
+			else if(k == "message")
+			{
+				i = strstrofs(v, " by ", 0);
+				if(MapInfo_Map_author == "He-Who-Must-Not-Be-Named" && i >= 0)
+				{
+					MapInfo_Map_title = substring(v, 0, i);
+					MapInfo_Map_author = substring(v, i + 4, strlen(v) - (i + 4));
+				}
+				else
+					MapInfo_Map_title = v;
+			}
+		}
+		else
+		{
+			if(k == "origin")
+			{
+				o = stov(strcat("'", v, "'"));
+				mapMins_x = min(mapMins_x, o_x);
+				mapMins_y = min(mapMins_y, o_y);
+				mapMins_z = min(mapMins_z, o_z);
+				mapMaxs_x = max(mapMaxs_x, o_x);
+				mapMaxs_y = max(mapMaxs_y, o_y);
+				mapMaxs_z = max(mapMaxs_z, o_z);
+			}
+			else if(k == "classname")
+			{
+				if(v == "dom_controlpoint")
+					MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_DOMINATION;
+				else if(v == "item_flag_team2")
+					MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_CTF;
+				else if(v == "team_CTF_blueflag")
+					MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_CTF;
+				else if(v == "runematch_spawn_point")
+					MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_RUNEMATCH;
+				else if(v == "target_assault_roundend")
+					MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_ASSAULT;
+				else if(v == "onslaught_generator")
+					MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_ONSLAUGHT;
+				else if(v == "info_player_team1")
+					++MapInfo_Map_spawnpoints;
+				else if(v == "info_player_team2")
+					++MapInfo_Map_spawnpoints;
+				else if(v == "info_player_start")
+					++MapInfo_Map_spawnpoints;
+				else if(v == "info_player_deathmatch")
+					++MapInfo_Map_spawnpoints;
+				else if(v == "weapon_nex")
+					{ }
+				else if(v == "weapon_railgun")
+					{ }
+				else if(startsWith(v, "weapon_"))
+					MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_WEAPONS;
+			}
+		}
+	}
+	if(inWorldspawn)
+	{
+		print(fn, " ended still in worldspawn, BUG\n");
+		return 0;
+	}
+	MapInfo_Map_diameter = vlen(mapMaxs - mapMins);
+
+	twoBaseModes = MapInfo_Map_supportedGametypes & (MAPINFO_TYPE_CTF | MAPINFO_TYPE_ASSAULT);
+	if(twoBaseModes && (MapInfo_Map_supportedGametypes == twoBaseModes))
+	{
+		// we have a CTF-only or Assault-only map. Don't add other modes then,
+		// as the map is too symmetric for them.
+	}
+	else
+	{
+		MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_DEATHMATCH;      // DM always works
+		MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_LMS;             // LMS always works
+
+		if(MapInfo_Map_spawnpoints >= 8  && MapInfo_Map_diameter > 4096)
+			MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_TEAM_DEATHMATCH;
+		if(                MapInfo_Map_diameter < 4096)
+			MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_ARENA;
+		if(MapInfo_Map_spawnpoints >= 12 && MapInfo_Map_diameter > 5120)
+			MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_KEYHUNT;
+	}
+
+	fclose(fh);
+	return r;
+}
+
+void _MapInfo_Map_Reset()
+{
+	MapInfo_Map_title = "Untitled1";
+	MapInfo_Map_description = "Bleh.";
+	MapInfo_Map_author = "He-Who-Must-Not-Be-Named";
+	MapInfo_Map_supportedGametypes = 0;
+	MapInfo_Map_supportedFeatures = 0;
+	MapInfo_Map_diameter = 0;
+	MapInfo_Map_spawnpoints = 0;
+}
+
+void _MapInfo_Map_ApplyGametype(string s, float pWantedType, float pThisType)
+{
+	MapInfo_Map_supportedGametypes |= pThisType;
+	if(!(pThisType & pWantedType))
+		return;
+	
+	cvar_set("fraglimit", car(s));
+	s = cdr(s);
+
+	cvar_set("timelimit", car(s));
+	s = cdr(s);
+
+	if(pWantedType == MAPINFO_TYPE_TEAM_DEATHMATCH)
+	{
+		cvar_set("g_tdm_teams", car(s));
+		s = cdr(s);
+	}
+
+	if(pWantedType == MAPINFO_TYPE_KEYHUNT)
+	{
+		cvar_set("g_keyhunt_teams", car(s));
+		s = cdr(s);
+	}
+}
+
+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 == "all")   return MAPINFO_TYPE_ALL;
+	else                  return 0;
+}
+
+// load info about a map by name into the MapInfo_Map_* globals
+float MapInfo_Get_ByName(string pFilename, float pAllowGenerate, float pGametypeToSet)
+{
+	string fn;
+	string s, t;
+	float fh;
+	float r, f;
+
+	r = 1;
+
+	MapInfo_Map_bspname = pFilename;
+
+	// default all generic fields so they have "good" values in case something fails
+	fn = strcat("maps/", pFilename, ".mapinfo");
+	fh = fopen(fn, FILE_READ);
+	if(fh < 0)
+	{
+		if(!pAllowGenerate)
+			return 0;
+		_MapInfo_Map_Reset();
+		r = _MapInfo_Generate(pFilename);
+		if(!r)
+			return 0;
+		fh = fopen(fn, FILE_WRITE);
+		fputs(fh, strcat("title ", MapInfo_Map_title, "\n"));
+		fputs(fh, strcat("description ", MapInfo_Map_description, "\n"));
+		fputs(fh, strcat("author ", MapInfo_Map_author, "\n"));
+		fputs(fh, strcat("_diameter ", ftos(MapInfo_Map_diameter), "\n"));
+		fputs(fh, strcat("_spawnpoints ", ftos(MapInfo_Map_spawnpoints), "\n"));
+		if(MapInfo_Map_supportedFeatures & MAPINFO_FEATURE_WEAPONS)       fputs(fh, "has weapons\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH)      fputs(fh, "type dm 30 20\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_TEAM_DEATHMATCH) fputs(fh, "type tdm 50 20 2\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DOMINATION)      fputs(fh, "type dom 200 20\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_CTF)             fputs(fh, "type ctf 300 20\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_RUNEMATCH)       fputs(fh, "type rune 200 20\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_LMS)             fputs(fh, "type lms 9 20\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_ARENA)           fputs(fh, "type arena 10 20\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_KEYHUNT)         fputs(fh, "type kh 1000 20 3\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_ASSAULT)         fputs(fh, "type as 20\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_ONSLAUGHT)       fputs(fh, "type ons 20\n");
+		fclose(fh);
+		r = 2;
+		// return r;
+		fh = fopen(fn, FILE_READ);
+		if(fh < 0)
+			error("... but I just wrote it!");
+	}
+
+	_MapInfo_Map_Reset();
+	for(;;)
+	{
+		if not((s = fgets(fh)))
+			break;
+		t = car(s); s = cdr(s);
+		if     (t == "title")
+			MapInfo_Map_title = s;
+		else if(t == "description")
+			MapInfo_Map_description = s;
+		else if(t == "author")
+			MapInfo_Map_author = s;
+		else if(t == "_diameter")
+			MapInfo_Map_diameter = stof(s);
+		else if(t == "_spawnpoints")
+			MapInfo_Map_spawnpoints = stof(s);
+		else if(t == "has")
+		{
+			t = car(s); s = cdr(s);
+			if     (t == "weapons") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_WEAPONS;
+			else
+				dprint("Map ", pFilename, " supports unknown feature ", t, ", ignored\n");
+		}
+		else if(t == "type")
+		{
+			t = car(s); s = cdr(s);
+			f = MapInfo_Type_FromString(t);
+			if(f)
+				_MapInfo_Map_ApplyGametype (s, pGametypeToSet, f);
+			else
+				dprint("Map ", pFilename, " supports unknown game type ", t, ", ignored\n");
+		}
+		else if(t == "settemp_for_type")
+		{
+			t = car(s); s = cdr(s);
+			if((f = MapInfo_Type_FromString(t)))
+			{
+				if(f & pGametypeToSet)
+				{
+					t = car(s); s = cdr(s);
+					if(strstrofs(t, "\"", 0) >= 0)
+						print("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+					else if(strstrofs(t, "\\", 0) >= 0)
+						print("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+					else if(strstrofs(t, ";", 0) >= 0)
+						print("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+					else if(strstrofs(s, "\"", 0) >= 0)
+						print("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+					else if(strstrofs(s, "\\", 0) >= 0)
+						print("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+					else if(strstrofs(s, ";", 0) >= 0)
+						print("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+					else
+					{
+						dprint("Applying temporary setting ", t, " := ", s, "\n");
+						localcmd(strcat("\nsettemp ", t, " \"", s, "\"\n"));
+					}
+				}
+			}
+			else
+			{
+				dprint("Map ", pFilename, " has a setting for unknown game type ", t, ", ignored\n");
+			}
+		}
+		else
+			dprint("Map ", pFilename, " provides unknown info item ", t, ", ignored\n");
+	}
+	fclose(fh);
+	if(pGametypeToSet)
+		if(!(MapInfo_Map_supportedGametypes & pGametypeToSet))
+			error("Can't select the requested game type. Bailing out.");
+	if(MapInfo_Map_supportedGametypes != 0)
+		return r;
+	dprint("Map ", pFilename, " supports no game types, ignored\n");
+	return 0;
+}
+
+string _MapInfo_FindName_match;
+float MapInfo_FindName(string s)
+{
+	// if there is exactly one map of prefix s, return it
+	// if not, return the null string
+	// note that DP sorts glob results... so I can use a binary search
+	float l, r, m, cmp;
+	l = 0;
+	r = MapInfo_count;
+	// invariants: r is behind s, l-1 is equal or before
+	while(l != r)
+	{
+		m = floor((l + r) / 2);
+		_MapInfo_FindName_match = _MapInfo_GlobItem(HugeSetOfIntegers_get(_MapInfo_filtered, m));
+		cmp = strcasecmp(_MapInfo_FindName_match, s);
+		if(cmp == 0)
+			return m; // found and good
+		if(cmp < 0)
+			l = m + 1; // l-1 is before s
+		else
+			r = m; // behind s
+	}
+	_MapInfo_FindName_match = _MapInfo_GlobItem(HugeSetOfIntegers_get(_MapInfo_filtered, l));
+	// r == l, so: l is behind s, l-1 is before
+	// SO: if there is any, l is the one with the right prefix
+	//     and l+1 may be one too
+	if(l == MapInfo_count)
+	{
+		_MapInfo_FindName_match = string_null;
+		return -1; // no _MapInfo_FindName_match, behind last item
+	}
+	if(!startsWith(_MapInfo_FindName_match, s))
+	{
+		_MapInfo_FindName_match = string_null;
+		return -1; // wrong prefix
+	}
+	if(l == MapInfo_count - 1)
+		return l; // last one, nothing can follow => unique
+	if(startsWith(_MapInfo_GlobItem(HugeSetOfIntegers_get(_MapInfo_filtered, l + 1)), s))
+	{
+		_MapInfo_FindName_match = string_null;
+		return -1; // ambigous _MapInfo_FindName_match
+	}
+	return l;
+}
+
+string MapInfo_FixName(string s)
+{
+	MapInfo_FindName(s);
+	return _MapInfo_FindName_match;
+}
+
+float MapInfo_CurrentFeatures()
+{
+	float req;
+	req = 0;
+	if(!(cvar("g_instagib") || cvar("g_minstagib") || cvar("g_nixnex") || cvar("g_rocketarena")))
+		req |= MAPINFO_FEATURE_WEAPONS;
+	return req;
+}
+
+float MapInfo_CurrentGametype()
+{
+	if(cvar("g_domination"))
+		return MAPINFO_TYPE_DOMINATION;
+	else if(cvar("g_ctf"))
+		return MAPINFO_TYPE_CTF;
+	else if(cvar("g_runematch"))
+		return MAPINFO_TYPE_RUNEMATCH;
+	else if(cvar("g_tdm"))
+		return MAPINFO_TYPE_TEAM_DEATHMATCH;
+	else if(cvar("g_assault"))
+		return MAPINFO_TYPE_ASSAULT;
+	else if(cvar("g_lms"))
+		return MAPINFO_TYPE_LMS;
+	else if(cvar("g_arena"))
+		return MAPINFO_TYPE_ARENA;
+	else if(cvar("g_keyhunt"))
+		return MAPINFO_TYPE_KEYHUNT;
+	else if(cvar("g_onslaught"))
+		return MAPINFO_TYPE_ONSLAUGHT;
+	else
+		return MAPINFO_TYPE_DEATHMATCH;
+}
+
+float MapInfo_CheckMap(string s) // returns 0 if the map can't be played with the current settings, 1 otherwise
+{
+	if(!MapInfo_Get_ByName(s, 1, 0))
+		return 0;
+	if((MapInfo_Map_supportedGametypes & MapInfo_CurrentGametype()) == 0)
+		return 0;
+	if((MapInfo_Map_supportedFeatures & MapInfo_CurrentFeatures()) != MapInfo_CurrentFeatures())
+		return 0;
+	return 1;
+}
+
+void MapInfo_SwitchGameType(float t)
+{
+	cvar_set("gamecfg",      "0");
+	cvar_set("g_dm",         (t == MAPINFO_TYPE_DEATHMATCH)      ? "0" : "1");
+	cvar_set("g_tdm",        (t == MAPINFO_TYPE_TEAM_DEATHMATCH) ? "0" : "1");
+	cvar_set("g_domination", (t == MAPINFO_TYPE_DOMINATION)      ? "0" : "1");
+	cvar_set("g_ctf",        (t == MAPINFO_TYPE_CTF)             ? "0" : "1");
+	cvar_set("g_runematch",  (t == MAPINFO_TYPE_RUNEMATCH)       ? "0" : "1");
+	cvar_set("g_lms",        (t == MAPINFO_TYPE_LMS)             ? "0" : "1");
+	cvar_set("g_arena",      (t == MAPINFO_TYPE_ARENA)           ? "0" : "1");
+	cvar_set("g_keyhunt",    (t == MAPINFO_TYPE_KEYHUNT)         ? "0" : "1");
+	cvar_set("g_assault",    (t == MAPINFO_TYPE_ASSAULT)         ? "0" : "1");
+	cvar_set("g_onslaught",  (t == MAPINFO_TYPE_ONSLAUGHT)       ? "0" : "1");
+}
+
+void MapInfo_LoadMap(string s)
+{
+	if(!MapInfo_CheckMap(s))
+	{
+		print("EMERGENCY: can't play the selected map in the given game mode. Falling back to deathmatch.\n");
+		MapInfo_SwitchGameType(MAPINFO_TYPE_DEATHMATCH);
+	}
+	MapInfo_Get_ByName(s, 1, MapInfo_CurrentGametype());
+	localcmd(strcat("\nchangelevel ", s, "\n"));
+}
+
+string MapInfo_ListAllowedMaps()
+{
+	string out;
+	float i;
+
+	// to make absolutely sure:
+	MapInfo_Enumerate();
+	MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0);
+
+	out = "";
+	for(i = 0; i < MapInfo_count; ++i)
+		out = strcat(out, " ", _MapInfo_GlobItem(HugeSetOfIntegers_get(_MapInfo_filtered, i)));
+	return substring(out, 1, strlen(out) - 1);
+}

Added: branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qh	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qh	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,56 @@
+float MAPINFO_TYPE_DEATHMATCH		= 1;
+float MAPINFO_TYPE_TEAM_DEATHMATCH	= 2;
+float MAPINFO_TYPE_DOMINATION		= 4;
+float MAPINFO_TYPE_CTF				= 8;
+float MAPINFO_TYPE_RUNEMATCH		= 16;
+float MAPINFO_TYPE_LMS				= 32;
+float MAPINFO_TYPE_ARENA			= 64;
+float MAPINFO_TYPE_KEYHUNT			= 128;
+float MAPINFO_TYPE_ASSAULT			= 256;
+float MAPINFO_TYPE_ONSLAUGHT		= 512;
+float MAPINFO_TYPE_ALL              = 65535; // this has to include all above bits
+
+float MAPINFO_FEATURE_WEAPONS       = 1; // not defined for minstagib-only maps
+
+float MapInfo_count;
+
+// info about a map that MapInfo loads
+string MapInfo_Map_bspname;
+string MapInfo_Map_title;
+string MapInfo_Map_description;
+string MapInfo_Map_author;
+float MapInfo_Map_supportedGametypes;
+float MapInfo_Map_supportedFeatures;
+float MapInfo_Map_diameter;
+float MapInfo_Map_spawnpoints;
+
+// load MapInfo_count; generate mapinfo for maps that miss them, and clear the
+// cache; you need to call MapInfo_FilterGametype afterwards!
+void MapInfo_Enumerate();
+
+// filter the info by game type mask (updates MapInfo_count)
+float MapInfo_FilterGametype(float gametype, float features, float pAbortOnGenerate); // 1 on success, 0 on temporary failure (call it again next frame then)
+float MapInfo_CurrentFeatures(); // retrieves currently required features from cvars
+float MapInfo_CurrentGametype(); // retrieves current gametype from cvars
+
+// load info about the i-th map into the MapInfo_Map_* globals
+float MapInfo_Get_ByID(float i); // 1 on success, 0 on failure
+string MapInfo_BSPName_ByID(float i);
+
+// load info about a map by name into the MapInfo_Map_* globals
+float MapInfo_Get_ByName(string s, float allowGenerate, float gametypeToSet); // 1 on success, 0 on failure, 2 if it autogenerated a mapinfo file
+
+// look for a map by a prefix, returns the actual map name on success, string_null on failure or ambigous match
+float MapInfo_FindName(string s);
+string MapInfo_FixName(string s);
+
+// play a map
+float MapInfo_CheckMap(string s); // returns 0 if the map can't be played with the current settings
+void MapInfo_LoadMap(string s);
+
+// list all maps for the current game type
+string MapInfo_ListAllowedMaps();
+
+// gets a gametype from a string
+float MapInfo_Type_FromString(string t);
+void MapInfo_SwitchGameType(float t);

Modified: branches/nexuiz-2.0/data/qcsrc/common/util.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/util.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/common/util.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -137,3 +137,81 @@
 		return bound(a, b, c);
 	return bound(c, b, a);
 }
+
+// converts a number to a string with the indicated number of decimals
+// works for up to 10 decimals!
+string ftos_decimals(float number, float decimals)
+{
+	string result;
+	string tmp;
+	float len;
+
+	// if negative, cut off the sign first
+	if(number < 0)
+		return strcat("-", ftos_decimals(-number, decimals));
+	// it now is always positive!
+
+	// 3.516 -> 352
+	number = floor(number * pow(10, decimals) + 0.5);
+
+	// 352 -> "352"
+	result = ftos(number);
+	len = strlen(result);
+	// does it have a decimal point (should not happen)? If there is one, it is always at len-7)
+		// if ftos had fucked it up, which should never happen: "34278.000000"
+	if(len >= 7)
+		if(substring(result, len - 7, 1) == ".")
+		{
+			dprint("ftos(integer) has comma? Can't be. Affected result: ", result, "\n");
+			result = substring(result, 0, len - 7);
+			len -= 7;
+		}
+		// "34278"
+	if(decimals == 0)
+		return result; // don't insert a point for zero decimals
+	// is it too short? If yes, insert leading zeroes
+	if(len <= decimals)
+	{
+		result = strcat(substring("0000000000", 0, decimals - len + 1), result);
+		len = decimals + 1;
+	}
+	// and now... INSERT THE POINT!
+	tmp = substring(result, len - decimals, decimals);
+	result = strcat(substring(result, 0, len - decimals), ".", tmp);
+	return result;
+}
+
+float time;
+vector colormapPaletteColor(float c, float isPants)
+{
+	switch(c)
+	{
+		case  0: return '0.733 0.733 0.733';
+		case  1: return '0.451 0.341 0.122';
+		case  2: return '0.000 0.733 0.733';
+		case  3: return '0.000 1.000 0.000';
+		case  4: return '1.000 0.000 0.000';
+		case  5: return '0.000 0.502 1.000';
+		case  6: return '0.812 0.561 0.169';
+		case  7: return '0.718 0.529 0.420';
+		case  8: return '0.765 0.545 0.667';
+		case  9: return '1.000 0.000 1.000';
+		case 10: return '0.639 0.529 0.482';
+		case 11: return '0.310 0.388 0.341';
+		case 12: return '1.000 1.000 0.000';
+		case 13: return '0.000 0.000 1.000';
+		case 14: return '1.000 0.502 0.000';
+		case 15:
+			if(isPants)
+				return
+					  '1 0 0' * (0.502 + 0.498 * sin(time / 2.7182818285 + 0.0000000000))
+					+ '0 1 0' * (0.502 + 0.498 * sin(time / 2.7182818285 + 2.0943951024))
+					+ '0 0 1' * (0.502 + 0.498 * sin(time / 2.7182818285 + 4.1887902048));
+			else
+				return
+					  '1 0 0' * (0.502 + 0.498 * sin(time / 3.1415926536 + 5.2359877560))
+					+ '0 1 0' * (0.502 + 0.498 * sin(time / 3.1415926536 + 3.1415926536))
+					+ '0 0 1' * (0.502 + 0.498 * sin(time / 3.1415926536 + 1.0471975512));
+		default: return '0.000 0.000 0.000';
+	}
+}

Modified: branches/nexuiz-2.0/data/qcsrc/common/util.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/util.qh	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/common/util.qh	2007-11-29 07:56:24 UTC (rev 2996)
@@ -26,3 +26,9 @@
 void depthfirst(entity start, .entity up, .entity downleft, .entity right, void(entity, entity) funcPre, void(entity, entity) funcPost, entity pass);
 
 float median(float a, float b, float c);
+
+// converts a number to a string with the indicated number of decimals
+// works for up to 10 decimals!
+string ftos_decimals(float number, float decimals);
+
+vector colormapPaletteColor(float c, float isPants);

Modified: branches/nexuiz-2.0/data/qcsrc/menu/gamecommand.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/gamecommand.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/menu/gamecommand.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -37,11 +37,8 @@
 	if(argv(0) == "directmenu") if(argc == 2)
 	{
 		entity newitem;
-		newitem = findstring(null_entity, name, argv(1));
-		if(newitem)
-			Menu_ActiveWindow = newitem;
-		else
-			print(argv(1), " not found.\n");
+		cvar_set("scmenu_directmenu", argv(1));
+		m_display();
 		return;
 	}
 

Modified: branches/nexuiz-2.0/data/qcsrc/menu/msys.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/msys.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/menu/msys.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -136,17 +136,22 @@
 float K_MOUSE1		=	512;
 float K_MOUSE2		=	513;
 float K_MOUSE3		=	514;
-float K_MOUSE4		=	515;
-float K_MOUSE5		=	516;
-float K_MOUSE6		=	517;
-float K_MOUSE7		=	518;
-float K_MOUSE8		=	519;
-float K_MOUSE9		=	520;
-float K_MOUSE10		=	521;
+float K_MWHEELUP	=	515;
+float K_MWHEELDOWN	=	516;
+float K_MOUSE4		=	517;
+float K_MOUSE5		=	518;
+float K_MOUSE6		=	519;
+float K_MOUSE7		=	520;
+float K_MOUSE8		=	521;
+float K_MOUSE9		=	522;
+float K_MOUSE10		=	523;
+float K_MOUSE11		=	524;
+float K_MOUSE12		=	525;
+float K_MOUSE13		=	526;
+float K_MOUSE14		=	527;
+float K_MOUSE15		=	528;
+float K_MOUSE16		=	529;
 
-float K_MWHEELDOWN	=	K_MOUSE4;
-float K_MWHEELUP	=	K_MOUSE5;
-
 ///////////////////////////
 // key dest constants
 

Added: branches/nexuiz-2.0/data/qcsrc/server/assault.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/assault.qc	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/server/assault.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -0,0 +1,447 @@
+//=============================================================================
+
+/*QUAKED info_player_attacker (1 0 0) (-16 -16 -24) (16 16 45) INITIAL
+Normal attacker spawning location for Nexuiz Asssault
+-------- KEYS --------
+angle : direction in which player will look when spawning in the game. Does not apply to bots.
+target : this should point to a target_objective to decide when this spawning point is active.
+nobots : when set to 1, bots will never use this spawn point to respawn in the game.
+nohumans : when set to 1, human players will never use this spawn point to respawn in the game.
+notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
+notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
+notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
+-------- SPAWNFLAGS --------
+INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
+void info_player_attacker() {
+	info_player_deathmatch();
+	self.team = COLOR_TEAM1; // red, gets swapped every round
+}
+
+//=============================================================================
+
+/*QUAKED info_player_defender (0 1 0) (-16 -16 -24) (16 16 45) INITIAL
+Normal defender spawning location for Nexuiz Asssault
+-------- KEYS --------
+angle : direction in which player will look when spawning in the game. Does not apply to bots.
+target : this should point to a target_objective to decide when this spawning point is active.
+nobots : when set to 1, bots will never use this spawn point to respawn in the game.
+nohumans : when set to 1, human players will never use this spawn point to respawn in the game.
+notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
+notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
+notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
+-------- SPAWNFLAGS --------
+INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
+void info_player_defender() {
+	info_player_deathmatch();
+	self.team = COLOR_TEAM2; // blue, gets swapped every round
+}
+
+// reset this objective. Used when spawning an objective
+// and when a new round starts
+void assault_objective_reset() {
+	self.health = ASSAULT_VALUE_INACTIVE;
+}
+
+void assault_objective_use() {
+	// activate objective
+	self.health = 100; 
+	self.nextthink = time + 0.1;
+}
+
+void assault_objective_think() {
+	local entity oldself;	
+	if(self.health < 0) {
+		//self.effects = 0;
+		local entity ent;
+		ent = find(world, targetname, self.target);
+		while(ent) {
+			oldself = self;
+			self = ent;
+			self.use();
+			self = oldself;
+			ent = find(ent, targetname, self.target);
+			
+		}
+	} else {
+		//self.effects = EF_STARDUST;
+		self.nextthink = time + 0.1;
+	}
+	
+}
+//=============================================================================
+
+/*QUAKED target_objective (0 .5 0) (-8 -8 -8) (8 8 8)
+Objective controller for Nexuiz Assault. When active it has 100 health. If it falls below 0 then
+it'll trigger the next targeted entity (usually the next objective or target_assault_roundend etc.)
+-------- KEYS --------
+targetname : point to e.g. next objective*/
+void target_objective() {
+	self.classname = "target_objective";
+	self.think = assault_objective_think;
+	self.use = assault_objective_use;
+	assault_objective_reset();
+}
+
+float assault_objective_decrease_customizeforclient() {
+	if(!self.spawnflags)
+		return FALSE;
+
+	if(self.cnt == 0) {
+		if(other.team == assault_attacker_team)
+			if(self.spawnflags == 1)
+				setmodel(self, "models/sprites/push.sp2");
+			else
+				setmodel(self, "models/sprites/destroy.sp2");
+		else
+			setmodel(self, "models/sprites/defend.sp2");
+	} else {
+		return FALSE;
+	}
+	return TRUE;
+}
+
+
+void assault_objective_decrease_think() {
+
+	local entity objective;
+	local float found;
+	found = 0;
+	objective = find(world, targetname, self.target);
+	while(objective && found == 0) {
+		if(objective.classname == "target_objective") {
+			found = 1;
+			if(objective.health < ASSAULT_VALUE_INACTIVE) { // targeted objective is active
+				if(self.cnt == 1 && self.max_health >= ASSAULT_VALUE_INACTIVE) { 
+					// decrease was fired already, but objective did recover (round reset)
+					self.cnt = 0;
+				}
+			} else { // objective isn't active
+				self.cnt = 1;
+			}
+			self.max_health = objective.health; // save current objective status for next think
+		}
+	}
+
+	if(!self.spawnflags) {
+		local entity ent;
+		ent = find(world, target, self.targetname);
+		if(ent) {
+			if(ent.classname == "func_assault_destructible")
+				self.spawnflags = 2;
+			else
+				self.spawnflags = 1;
+		}
+	}
+
+	self.nextthink = time + 0.2;
+}
+
+
+// decrease the health of targeted objectives
+void assault_objective_decrease_use() {
+
+	if(self.cnt > 0)
+		return;
+
+	if(activator.team != assault_attacker_team)
+		return;
+
+	local entity ent;
+	ent = find(world, targetname, self.target);
+	while(ent) {
+		if(ent.health > 0 && ent.health < ASSAULT_VALUE_INACTIVE)
+			ent.health = ent.health - self.dmg;
+		ent = find(ent, targetname, self.target);
+	}
+
+	self.cnt = 1;
+}
+
+//=============================================================================
+
+/*QUAKED target_objective_decrease (0 .5 0) (-8 -8 -8) (8 8 8)
+When triggered decreases health of the targeted target_objective.
+-------- KEYS --------
+targetname : point to a target_objective entity*/
+void target_objective_decrease() {
+
+	self.classname = "target_objective_decrease";
+
+	precache_model("models/sprites/defend.sp2");
+	precache_model("models/sprites/destroy.sp2");
+	precache_model("models/sprites/push.sp2");
+
+	if(!self.dmg) {
+		self.dmg = 101;
+	}
+	self.cnt = 0; // not used yet
+	self.use = assault_objective_decrease_use;
+	self.mdl = "models/sprites/here.sp2";
+	self.effects = EF_NODEPTHTEST;
+	self.health = ASSAULT_VALUE_INACTIVE;
+	self.max_health = ASSAULT_VALUE_INACTIVE;
+	self.think = assault_objective_decrease_think;
+	self.customizeentityforclient = assault_objective_decrease_customizeforclient;
+	self.nextthink = time;
+}
+
+
+void assault_destructible_reset() {
+	self.health = self.max_health;
+	self.model = self.mdl;
+	self.solid = SOLID_BSP;
+	self.colormod = '1 1 1';
+	self.cnt = 0; // not active
+	if(self.spawnflags)
+		self.use();
+}
+
+void assault_destructible_use() {
+	self.cnt = 1; // mark active
+	self.takedamage = DAMAGE_YES;
+}
+
+void assault_destructible_destroy() {
+	local entity oldself;
+	
+	self.model = "";
+	self.takedamage = DAMAGE_NO;
+	self.solid = SOLID_NOT;
+	local entity ent;
+	ent = find(world, targetname, self.target);
+	while(ent) {
+		oldself = self;
+		self = ent;
+		self.use();
+		self = oldself;
+		ent = find(ent, targetname, self.target);
+	}
+}
+
+void assault_destructible_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) {
+
+	if(self.cnt > 0 && assault_attacker_team == attacker.team) {
+		self.health = self.health - damage;
+		if(self.health / self.max_health < 0.25)
+			self.colormod = '1 0 0';
+		else if(self.health / self.max_health < 0.375)
+			self.colormod = '1 0.25 0';
+		else if(self.health / self.max_health < 0.50)
+			self.colormod = '1 0.5 0';
+		else if(self.health / self.max_health < 0.625)
+			self.colormod = '1 0.75 0';
+		else if(self.health / self.max_health < 0.75)
+			self.colormod = '1 1 0';
+		else
+			self.colormod = '1 1 1';
+	}
+
+	if(self.health < 0) {
+		activator = attacker;
+		assault_destructible_destroy();
+	}
+}
+
+// destructible walls that can be used to trigger target_objective_decrease
+void func_assault_destructible() {
+	if(!self.health)
+		self.health = 100;
+
+	self.max_health = self.health;
+	
+	self.cnt = 0; // not yet activated
+
+	self.classname = "func_assault_destructible";
+	self.mdl = self.model;
+	setmodel(self, self.mdl);
+
+	self.solid = SOLID_BSP;
+	self.use = assault_destructible_use;
+	self.event_damage = assault_destructible_damage;
+
+}
+
+void assault_wall_think() {
+	local entity ent;
+	local float notvisible;
+	notvisible = 0;
+	ent = find(world, targetname, self.target);
+	while(ent) {
+		if(ent.classname == "target_objective" && ent.health < 0)
+			notvisible = 1;
+		ent = find(ent, targetname, self.target);
+	}
+
+	if(notvisible) {
+		self.model = "";
+		self.solid = SOLID_NOT;
+	} else {
+		self.model = self.mdl;
+		self.solid = SOLID_BSP;
+	}
+
+	self.nextthink = time + 0.2;
+}
+
+void func_assault_wall() {
+	self.classname = "func_assault_wall";
+	self.mdl = self.model;
+	setmodel(self, self.mdl);
+	self.solid = SOLID_BSP;
+	self.think = assault_wall_think;
+	self.nextthink = time;
+}
+
+
+void target_assault_roundend_reset() {
+	self.cnt = self.cnt + 1; // up round counter
+	self.winning = 0; // up round 
+}
+
+void target_assault_roundend_use() {
+	self.winning = 1; // round has been won by attackers
+}
+
+void target_assault_roundend() {
+	if(!self.health)
+		self.health = 300; // 5 minutes
+
+	cvar_set("timelimit", ftos(self.health/60));
+	self.winning = 0; // round not yet won by attackers
+	self.classname = "target_assault_roundend";
+	self.use = target_assault_roundend_use;
+	self.cnt = 0; // first round
+}
+
+void assault_roundstart_use() {
+	local entity ent;
+	local entity oldself;
+	ent = find(world, targetname, self.target);
+	while(ent) {
+		oldself = self;
+		self = ent;
+		self.use();
+		self = oldself;
+		ent = find(ent, targetname, self.target);
+	}
+}
+
+void target_assault_roundstart() {
+	assault_attacker_team = COLOR_TEAM1;
+	self.classname = "target_assault_roundstart";
+	self.use = assault_roundstart_use;
+	self.think = assault_roundstart_use;
+	self.nextthink = time + 0.1;
+}
+
+// trigger new round
+// reset objectives, toggle spawnpoints, reset triggers, ...
+void assault_new_round() {
+	
+	// up round counter
+	self.winning = self.winning + 1;
+	// set end time for next round
+	self.cnt = time + self.health;
+
+	// swap spawn point teams
+	local entity ent;
+	local entity oldself;
+
+	// reward attackers for winning the round
+	ent = find(world, classname, "player");
+	while(ent) {
+		if(ent.team == assault_attacker_team) {
+			UpdateFrags(ent, 10);
+		}
+		ent = find(ent, classname, "player");
+	}
+
+	// swap attacker/defender roles
+	if(assault_attacker_team == COLOR_TEAM1) {
+		assault_attacker_team = COLOR_TEAM2;
+	} else {
+		assault_attacker_team = COLOR_TEAM1;
+	}
+
+	ent = find(world, classname, "info_player_deathmatch");
+	while (ent)
+	{
+		oldself = self;
+		self = ent;
+		if(self.team == COLOR_TEAM1) {
+			self.team = COLOR_TEAM2;
+		} else {
+			self.team = COLOR_TEAM1;
+		}
+		self = oldself;
+
+		ent = find(ent, classname, "info_player_deathmatch");
+	} 
+
+	// reset all objectives
+	ent = find(world, classname, "target_objective");
+	while (ent)
+	{
+		oldself = self;
+		self = ent;
+		assault_objective_reset();
+		self = oldself;
+
+		ent = find(ent, classname, "target_objective");
+	} 
+
+	// reset round end triggers
+	ent = find(world, classname, "target_assault_roundend");
+	while (ent)
+	{
+		oldself = self;
+		self = ent;
+		target_assault_roundend_reset();
+		self = oldself;
+
+		ent = find(ent, classname, "target_assault_roundend");
+	}
+
+	// reset all target_object_decrease
+	ent = find(world, classname, "target_objective_decrease");
+	while (ent)
+	{
+		ent.cnt = 0;
+		ent = find(ent, classname, "target_objective_decrease");
+	} 
+
+	// reset all func_assault_destructible
+	ent = find(world, classname, "func_assault_destructible");
+	while (ent)
+	{
+		oldself = self;
+		self = ent;
+		assault_destructible_reset();
+		self = oldself;
+		ent = find(ent, classname, "func_assault_destructible");
+	}
+
+	ent = find(world, classname, "target_assault_roundstart");
+	while (ent)
+	{
+		oldself = self;
+		self = ent;
+		self.use();
+		self = oldself;
+		ent = find(ent, classname, "target_assault_roundstart");
+	}
+
+	// actually restart round... how to do that?
+	ent = find(world, classname, "player");
+	while(ent) {
+		oldself = self;
+		self = ent;
+		PutClientInServer();
+		self = oldself;
+		ent = find(ent, classname, "player");
+	}
+
+
+}
+
+

Modified: branches/nexuiz-2.0/data/qcsrc/server/bots.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/bots.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/bots.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -2149,7 +2149,7 @@
 
 	FOR_EACH_REALCLIENT(head)
 	{
-		if(head.classname == "player" || cvar("g_lms") || cvar("g_arena"))
+		if(head.classname == "player" || g_lms || g_arena)
 			++activerealplayers;
 		++realplayers;
 	}

Modified: branches/nexuiz-2.0/data/qcsrc/server/campaign.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/campaign.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/campaign.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -49,8 +49,12 @@
 	// now some sanity checks
 	string thismapname, wantedmapname;
 	thismapname = GetMapname();
+#ifdef MAPINFO
+	wantedmapname = campaign_mapname[0];
+#else
 	wantedmapname = campaign_gametype[0];
 	wantedmapname = strcat(wantedmapname, "_", campaign_mapname[0]);
+#endif
 	if(wantedmapname != thismapname)
 		return CampaignBailout(strcat("wrong map: ", wantedmapname, " != ", thismapname));
 	cvar_set("fraglimit", ftos(campaign_fraglimit[0]));

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -24,7 +24,23 @@
 	{
 		nextspot = spot.chain;
 		// count team mismatches as bad spots
-		if (spot.team == teamcheck)
+
+		local float spotactive;
+		spotactive = 1;
+
+		// filter out spots for assault
+		if(spot.target != "") {
+			local entity ent;
+			ent = find(world, targetname, spot.target);
+			while(ent) {
+				if(ent.classname == "target_objective")
+					if(ent.health < 0 || ent.health >= ASSAULT_VALUE_INACTIVE)
+						spotactive = 0;
+				ent = find(ent, targetname, spot.target);
+			}
+		}
+
+		if (spot.team == teamcheck && spotactive > 0)
 		{
 			pcount = 0;
 			player = playerlist;
@@ -125,7 +141,7 @@
 
 	teamcheck = 0;
 
-	if(!anypoint && cvar("g_ctf") )
+	if(!anypoint && (g_ctf || g_assault))
 		teamcheck = self.team;
 
 	// get the list of players
@@ -297,7 +313,7 @@
 
 	DistributeFragsAmongTeam(self, self.team, 1);
 
-	if(self.frags <= 0 && self.frags > -666 && cvar("g_lms") && self.killcount != -666)
+	if(self.frags <= 0 && self.frags > -666 && g_lms && self.killcount != -666)
 		bprint ("^4", self.netname, "^4 has no more lives left\n");
 	else if(self.killcount != -666)
 		bprint ("^4", self.netname, "^4 is spectating now\n");
@@ -356,7 +372,7 @@
 	self.oldvelocity = self.velocity;
 	self.customizeentityforclient = Client_customizeentityforclient;
 
-	if(cvar("g_arena"))
+	if(g_arena)
 	{
 		if(self.frags != -2)
 		{
@@ -368,7 +384,7 @@
 			Spawnqueue_Remove(self);
 		}
 	}
-	else if(!cvar("g_lms"))
+	else if(!g_lms)
 		self.frags = -666;
 }
 
@@ -394,10 +410,10 @@
 	}
 
 	// player is dead and becomes observer
-	if(cvar("g_lms") && self.frags < 1)
+	if(g_lms && self.frags < 1)
 		self.classname = "observer";
 
-	if(cvar("g_arena"))
+	if(g_arena)
 	if(!self.spawned)
 		self.classname = "observer";
 
@@ -506,7 +522,7 @@
 		// don't reset back to last position, even if new position is stuck in solid
 		self.oldorigin = self.origin;
 
-		if(cvar("g_arena"))
+		if(g_arena)
 		{
 			Spawnqueue_Remove(self);
 			Spawnqueue_Mark(self);
@@ -521,8 +537,8 @@
 
 		if(self.killcount == -666) {
 			self.killcount = 0;
-			if(!cvar("g_arena"))
-			if(!cvar("g_lms"))
+			if(!g_arena)
+			if(!g_lms)
 				self.frags = 0;
 		}
 
@@ -548,6 +564,13 @@
 		if (cvar("g_spawnsound"))
 			sound (self, CHAN_AUTO, "misc/spawn.wav", 1, ATTN_NORM);
 
+		if(g_assault) {
+			if(self.team == assault_attacker_team)
+				centerprint(self, "You are attacking!\n");
+			else
+				centerprint(self, "You are defending!\n");
+		}
+
 	} else if(self.classname == "observer") {
 		PutObserverInServer ();
 	}
@@ -605,9 +628,14 @@
 	stuffcmd(e, "cl_movement_edgefriction 1\n");
 
 	// notify about available teams
-	CheckAllowedTeams(e);
-	t = 0; if(c1 >= 0) t |= 1; if(c2 >= 0) t |= 2; if(c3 >= 0) t |= 4; if(c4 >= 0) t |= 8;
-	stuffcmd(e, strcat("set _teams_available ", ftos(t), "\n"));
+	if(teamplay)
+	{
+		CheckAllowedTeams(e);
+		t = 0; if(c1 >= 0) t |= 1; if(c2 >= 0) t |= 2; if(c3 >= 0) t |= 4; if(c4 >= 0) t |= 8;
+		stuffcmd(e, strcat("set _teams_available ", ftos(t), "\n"));
+	}
+	else
+		stuffcmd(e, "set _teams_available 0\n");
 }
 
 /*
@@ -649,7 +677,7 @@
 
 	//JoinBestTeam(self, FALSE);
 
-	if((cvar("sv_spectate") == 1 && !cvar("g_lms")) || cvar("g_campaign")) {
+	if((cvar("sv_spectate") == 1 && !g_lms) || cvar("g_campaign")) {
 		self.classname = "observer";
 	} else {
 		self.classname = "player";
@@ -674,7 +702,7 @@
 	bprint ("^4",self.netname);
 	bprint ("^4 connected");
 
-	if(cvar("g_domination") || cvar("g_ctf"))
+	if(cvar("g_domination") || g_ctf)
 	{
 		bprint(" and joined the ");
 		bprint(ColoredTeamName(self.team));
@@ -725,7 +753,7 @@
 	else
 		stuffcmd(self, "set teamplay 0\n");
 
-	if(cvar("g_lms"))
+	if(g_lms)
 	{
 		self.frags = cvar("fraglimit");
 		// no fraglimit was set, so player gets 999 lives
@@ -738,7 +766,7 @@
 			self.frags = -666;
 		}
 	}
-	else if(cvar("g_arena"))
+	else if(g_arena)
 	{
 		self.classname = "observer";
 		Spawnqueue_Insert(self);
@@ -799,7 +827,7 @@
 		if(self.weaponentity.lasertarget)
 			remove(self.weaponentity.lasertarget);
 
-	if(cvar("g_arena"))
+	if(g_arena)
 	{
 		Spawnqueue_Unmark(self);
 		Spawnqueue_Remove(self);
@@ -916,7 +944,7 @@
 
 void player_powerups (void)
 {
-	if (cvar("g_minstagib"))
+	if (g_minstagib)
 	{
 		self.effects = EF_FULLBRIGHT;
 		if (self.items & IT_STRENGTH)
@@ -1004,7 +1032,7 @@
 	// first damage in the frame, leaving the player vulnerable to the
 	// remaining hits in the same frame)
 	if (self.flags & FL_ONGROUND)
-	if (cvar("g_midair"))
+	if (g_midair)
 		self.spawnshieldtime = max(self.spawnshieldtime, time + cvar("g_midair_shieldtime"));
 
 	if (time < self.spawnshieldtime)
@@ -1029,7 +1057,7 @@
 	limith = cvar("g_balance_health_limit");
 	limita = cvar("g_balance_armor_limit");
 
-	if (cvar("g_minstagib") || (cvar("g_lms") && !cvar("g_lms_regenerate")))
+	if (g_minstagib || (g_lms && !cvar("g_lms_regenerate")))
 		return;
 
 	max_mod = regen_mod = rot_mod = limit_mod = 1;
@@ -1266,7 +1294,7 @@
 		if(self.button7)
 			PrintWelcomeMessage(self);
 
-		if(cvar("g_lms") || !cvar("sv_spectate"))
+		if(g_lms || !cvar("sv_spectate"))
 		if((time - self.jointime) <= cvar("welcome_message_time"))
 			PrintWelcomeMessage(self);
 
@@ -1293,7 +1321,7 @@
 			float button_pressed, force_respawn;
 			player_anim();
 			button_pressed = (self.button0 || self.button2 || self.button3 || self.button6 || self.buttonuse);
-			force_respawn = (cvar("g_lms") || cvar("g_forced_respawn"));
+			force_respawn = (g_lms || cvar("g_forced_respawn"));
 			if (self.deadflag == DEAD_DYING)
 			{
 				if(force_respawn)
@@ -1320,7 +1348,7 @@
 			return;
 		}
 
-		if(cvar("g_lms") && !self.deadflag && cvar("g_lms_campcheck_interval"))
+		if(g_lms && !self.deadflag && cvar("g_lms_campcheck_interval"))
 		{
 			vector dist;
 
@@ -1431,7 +1459,7 @@
 			zoomdir = self.button4;
 			if(self.button3)
 				if(self.weapon == WEP_NEX)
-					if(!cvar("g_minstagib"))
+					if(!g_minstagib)
 						zoomdir = 1;
 
 			if(zoomdir)
@@ -1469,7 +1497,7 @@
 		player_regen();
 		player_anim();
 
-		if (cvar("g_minstagib"))
+		if (g_minstagib)
 			minstagib_ammocheck();
 
 		ctf_setstatus();

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -85,8 +85,8 @@
 		if(self.deadflag == DEAD_NO)
 		{
 			if (self.weapon != WEP_LASER
-				&& !cvar("g_minstagib") && !cvar("g_instagib")
-				&& !cvar("g_rocketarena") && !cvar("g_lms") && cvar("g_pickup_items") && !cvar("g_nixnex"))
+				&& !g_minstagib && !g_instagib
+				&& !g_rocketarena && !g_lms && cvar("g_pickup_items") && !g_nixnex)
 				W_ThrowWeapon(W_CalculateProjectileVelocity(self.velocity, v_forward * 750), '0 0 0', TRUE);
 		}
 	}

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -64,9 +64,9 @@
 		}
 	}
 
-	if(cvar("g_minstagib") && (self.items & IT_INVINCIBLE))
+	if(g_minstagib && (self.items & IT_INVINCIBLE))
 	{
-		mjumpheight = mjumpheight * cvar("g_balance_rune_speed_jumpheight");
+		mjumpheight = mjumpheight * cvar("g_minstagib_speed_jumpheight");
 	}
 
 	self.velocity_z = self.velocity_z + mjumpheight;
@@ -172,9 +172,9 @@
 		}
 	}
 
-	if(cvar("g_minstagib") && (self.items & IT_INVINCIBLE))
+	if(g_minstagib && (self.items & IT_INVINCIBLE))
 	{
-		maxspd_mod = cvar("g_balance_rune_speed_moverate");
+		maxspd_mod = cvar("g_minstagib_speed_moverate");
 	}
 
 	swampspd_mod = 1;

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -125,7 +125,7 @@
 void SpawnThrownWeapon (vector org, float w)
 {
 	if (!cvar("g_pickup_items"))
-	if (!cvar("g_minstagib"))
+	if (!g_minstagib)
 		return;
 	if (!w)
 		return;
@@ -236,11 +236,11 @@
 		self.v_angle_y = self.v_angle_y + (random() * 2 - 1) * shake;
 	}
 
-	if(cvar("g_arena"))
+	if(g_arena)
 	if(numspawned < 2)
 		return;
 
-	if (!cvar("g_minstagib"))
+	if (!g_minstagib)
 	{
 		save = bound(0, damage * cvar("g_balance_armor_blockpercent"), self.armorvalue);
 		take = bound(0, damage - save, damage);
@@ -396,7 +396,7 @@
 			//WriteAngle (MSG_ONE, 80);
 		}
 
-		if(cvar("g_arena"))
+		if(g_arena)
 			Spawnqueue_Unmark(self);
 	}
 }

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -293,11 +293,11 @@
 {
 	float numberof, id;
 	numberof = WEP_LAST - WEP_FIRST; // all but the current one
-	if(cvar("g_nixnex_with_laser"))
+	if(g_nixnex_with_laser)
 		numberof = numberof - 1;
 	id = WEP_FIRST + ceil(random() * numberof) - 1;
 
-	if(cvar("g_nixnex_with_laser")) // skip the laser if needed
+	if(g_nixnex_with_laser) // skip the laser if needed
 		id = id + 1;
 
 	if(id >= nixnex_weapon) // skip the current weapon
@@ -320,7 +320,7 @@
 void Nixnex_GiveCurrentWeapon()
 {
 	float dt;
-	if(cvar("g_nixnex"))
+	if(g_nixnex)
 	{
 		if(!nixnex_nextweapon)
 			Nixnex_ChooseNextWeapon();
@@ -375,7 +375,7 @@
 		}
 
 		self.items = self.items - (self.items & (IT_LASER | IT_SHOTGUN | IT_UZI | IT_GRENADE_LAUNCHER | IT_ELECTRO | IT_CRYLINK | IT_NEX | IT_HAGAR | IT_ROCKET_LAUNCHER));
-		if(cvar("g_nixnex_with_laser"))
+		if(g_nixnex_with_laser)
 			self.items = self.items | IT_LASER;
 		self.items = self.items | W_ItemCode(nixnex_weapon);
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -60,14 +60,14 @@
 		}
 	}
 
-	if (!cvar("g_norecoil"))
+	if (!g_norecoil)
 		self.punchangle_x = recoil * -1;
 
 	if (snd != "")
 		sound (self, CHAN_WEAPON, snd, 1, ATTN_NORM);
 
 	if (self.items & IT_STRENGTH)
-	if (!cvar("g_minstagib"))
+	if (!g_minstagib)
 		sound (self, CHAN_AUTO, "weapons/strength_fire.wav", 1, ATTN_NORM);
 };
 
@@ -79,7 +79,7 @@
 	uselaser = 0;
 
 	// list of weapons that will use the laser, and the options that enable it
-	if(self.owner.laser_on && self.owner.weapon == WEP_ROCKET_LAUNCHER && cvar("g_laserguided_missile"))
+	if(self.owner.laser_on && self.owner.weapon == WEP_ROCKET_LAUNCHER && g_laserguided_missile)
 		uselaser = 1;
 	// example
 	//if(self.owner.weapon == WEP_ELECTRO && cvar("g_laserguided_electro"))

Modified: branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -1,5 +1,5 @@
 void ReadyCount();
-float ValidateMap(string vote);
+string ValidateMap(string vote);
 void(entity e) DropFlag;
 string MapVote_Suggest(string m);
 
@@ -206,11 +206,16 @@
 					} else if(time < self.vote_next) {
 						sprint(self, strcat("^1You have to wait ^2", ftos(self.vote_next - time), "^1 seconds before you can again call a vote.\n"));
 					} else if(VoteAllowed(strcat1(argv(2)))) { // strcat seems to be necessary
-						if(!ValidateMap(vote))
-							return;
 						// remap chmap to gotomap (forces intermission)
 						if(substring(vote, 0, 6) == "chmap ")
 							vote = strcat("gotomap ", substring(vote, 6, strlen(vote) - 6));
+						if(substring(vote, 0, 8) == "gotomap ")
+						{
+							if(!(vote = ValidateMap(substring(vote, 8, strlen(vote) - 8))))
+								return;
+							vote = strcat("gotomap ", vote);
+						}
+
 						// make kick and kickban votes a bit nicer (and reject them if formatted badly)
 						if(substring(vote, 0, 5) == "kick " || substring(vote, 0, 8) == "kickban ")
 						{
@@ -289,12 +294,15 @@
 				if(dovote == "") {
 					sprint(self, "^1Your command was empty. See help for more info.\n");
 				} else if(VoteAllowed(strcat1(argv(2)))) { // strcat seems to be necessary
-					if(!ValidateMap(dovote))
-						return;
-					// remap chmap to gotomap (forces intermission)
-					if(strlen(dovote) >= 6)
-						if(substring(dovote, 0, 6) == "chmap ")
-							dovote = strcat("gotomap ", substring(dovote, 6, strlen(dovote) - 6));
+					if(substring(dovote, 0, 6) == "chmap ")
+						dovote = strcat("gotomap ", substring(dovote, 6, strlen(dovote) - 6));
+					if(substring(dovote, 0, 8) == "gotomap ")
+					{
+						if(!(dovote = ValidateMap(substring(dovote, 8, strlen(dovote) - 8))))
+							return;
+						dovote = strcat("gotomap ", dovote);
+					}
+
 					dovote_display = dovote;
 					if(substring(dovote, 0, 5) == "kick " || substring(dovote, 0, 8) == "kickban ")
 					{
@@ -375,7 +383,7 @@
 	} else if(argv(0) == "sentcvar") { // new system
 		GetCvars(1);
 	} else if(argv(0) == "spectate") {
-		if(cvar("g_lms") || cvar("g_arena"))
+		if(g_lms || g_arena)
 			return; // don't allow spectating in lms, unless player runs out of lives
 		if(self.classname == "player" && cvar("sv_spectate") == 1) {
 			if(self.flagcarried)
@@ -387,7 +395,7 @@
 			PutClientInServer();
 		}
 	} else if(argv(0) == "join") {
-		if(!cvar("g_arena"))
+		if(!g_arena)
 		if (self.classname != "player")
 		{
 			self.classname = "player";
@@ -482,40 +490,43 @@
 	}
 }
 
-float ValidateMap(string vote)
+string ValidateMap(string m)
 {
-	string ext;
-	
-	tokenize(vote);
-	if(argv(0) == "map" || argv(0) == "changelevel")
-		ext = ".bsp";
-	else if(argv(0) == "chmap")
-		ext = ".mapcfg";
-	else if(argv(0) == "gotomap")
-		ext = ".mapcfg";
-	else
-		return TRUE;
-
+#ifdef MAPINFO
+	m = MapInfo_FixName(m);
+	if(!m)
+	{
+		sprint(self, "This map is not available on this server.\n");
+		return string_null;
+	}
+#endif
 	if(!cvar("sv_vote_change_gametype"))
-		if(!IsSameGametype(argv(1)))
+		if(!IsSameGametype(m))
 		{
 			sprint(self, "This server does not allow changing the game type by map votes.\n");
-			return FALSE;
+			return string_null;
 		}
 	if(!cvar("sv_vote_override_mostrecent"))
-		if(Map_IsRecent(argv(1)))
+		if(Map_IsRecent(m))
 		{
 			sprint(self, "This server does not allow for recent maps to be played again. Please be patient for some rounds.\n");
-			return FALSE;
+			return string_null;
 		}
-
-	if(!TryFile(strcat("maps/", argv(1), ext)))
+#ifdef MAPINFO
+	if(!MapInfo_CheckMap(m))
 	{
-		sprint(self, strcat("^1Invalid mapname, \"^3", argv(1), "^1\" does not exist on this server.\n"));
-		return FALSE;
+		sprint(self, strcat("^1Invalid mapname, \"^3", m, "^1\" does not support the current game mode.\n"));
+		return string_null;
 	}
+#else
+	if(!TryFile(strcat("maps/", m, ".mapcfg")))
+	{
+		sprint(self, strcat("^1Invalid mapname, \"^3", m, "^1\" does not exist on this server.\n"));
+		return string_null;
+	}
+#endif
 
-	return TRUE;
+	return m;
 }
 
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/constants.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/constants.qh	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/constants.qh	2007-11-29 07:56:24 UTC (rev 2996)
@@ -224,3 +224,5 @@
 float COLOR_TEAM4	= 10; // pink
 
 float NUM_PLAYERSKINS_TEAMPLAY = 3;
+
+float ASSAULT_VALUE_INACTIVE = 1000;

Modified: branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -395,7 +395,7 @@
 
 void() item_flag_team1 =
 {
-	if (!cvar("g_ctf"))
+	if (!g_ctf)
 		return;
 	//if(!cvar("teamplay"))
 	//	cvar_set("teamplay", "3");
@@ -451,7 +451,7 @@
 
 void() item_flag_team2 =
 {
-	if (!cvar("g_ctf"))
+	if (!g_ctf)
 		return;
 	//if(!cvar("teamplay"))
 	//	cvar_set("teamplay", "3");
@@ -597,7 +597,7 @@
 	self.items = self.items - (self.items & IT_BLUE_FLAG_TAKEN);
 	self.items = self.items - (self.items & IT_BLUE_FLAG_LOST);
 
-	if (cvar("g_ctf")) {
+	if (g_ctf) {
 		local entity flag;
 		flag = find(world, classname, "item_flag_team1");
 		ctf_setstatus2(flag);

Modified: branches/nexuiz-2.0/data/qcsrc/server/defs.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2007-11-29 07:56:24 UTC (rev 2996)
@@ -1,5 +1,8 @@
 // Globals
 
+float g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught, g_assault, g_arena, g_lms;
+float g_cloaked, g_footsteps, g_grappling_hook, g_instagib, g_laserguided_missile, g_midair, g_minstagib, g_nixnex, g_nixnex_with_laser, g_norecoil, g_rocketarena, g_vampire;
+
 float sv_cheats;
 
 entity	activator;
@@ -324,3 +327,6 @@
 .float	attack_finished_for[WEP_LAST + 1];
 .float attack_finished_single;
 #define ATTACK_FINISHED(ent) ((ent).(attack_finished_for[(ent).weapon]))
+
+// assault game mode: Which team is attacking in this round?
+float assault_attacker_team;

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -11,7 +11,7 @@
 {
 	if(gameover) return;
 
-	if(cvar("g_arena"))
+	if(g_arena)
 		if(cvar("g_arena_roundbased"))
 			return;
 
@@ -26,11 +26,11 @@
 		if(f > 0)
 			f = RunematchHandleFrags(attacker, targ, f);
 	}
-	else if(cvar("g_keyhunt"))
+	else if(g_keyhunt)
 	{
 		f = kh_HandleFrags(attacker, targ, f);
 	}
-	else if(cvar("g_lms"))
+	else if(g_lms)
 	{
 		// count remaining lives, not frags in lms
 		targ.frags -= 1;
@@ -180,7 +180,7 @@
 				{
 					checkrules_firstblood = TRUE;
 					//sound(world, CHAN_AUTO, "announcer/firstblood.wav", 1, ATTN_NONE);
-					//if (cvar("g_minstagib"))
+					//if (g_minstagib)
 						//sound(world, CHAN_AUTO, "announce/male/mapkill1.wav", 1, ATTN_NONE);
 					bprint("^1",a, "^1 drew first blood", "\n");
 				}
@@ -369,7 +369,7 @@
 					{
 						mirrordamage = cvar("g_mirrordamage") * damage;
 						mirrorforce = cvar("g_mirrordamage") * vlen(force);
-						if(cvar("g_minstagib"))
+						if(g_minstagib)
 						{
 							if(cvar("g_friendlyfire") == 0)
 								damage = 0;
@@ -384,7 +384,7 @@
 			}
 		}
 
-		if(cvar("g_lms"))
+		if(g_lms)
 		if(targ.classname == "player")
 		if(attacker.classname == "player")
 		if(attacker != targ)
@@ -400,7 +400,7 @@
 		if(attacker)
 			attacker.hitsound += 1;
 
-		if (cvar("g_minstagib"))
+		if (g_minstagib)
 		{
 			if ((deathtype == DEATH_FALL)  ||
 				(deathtype == DEATH_DROWN) ||
@@ -440,13 +440,13 @@
 		}
 
 		// apply strength multiplier
-		if (attacker.items & IT_STRENGTH && !cvar("g_minstagib"))
+		if (attacker.items & IT_STRENGTH && !g_minstagib)
 		{
 			damage = damage * cvar("g_balance_powerup_strength_damage");
 			force = force * cvar("g_balance_powerup_strength_force");
 		}
 		// apply invincibility multiplier
-		if (targ.items & IT_INVINCIBLE && !cvar("g_minstagib"))
+		if (targ.items & IT_INVINCIBLE && !g_minstagib)
 			damage = damage * cvar("g_balance_powerup_invincible_takedamage");
 
 
@@ -499,7 +499,7 @@
 	if(targ.classname == "player" && attacker.classname == "player" && attacker != targ && attacker.health > 2)
 	{
 		// Savage: vampire mode
-		if(cvar("g_vampire") && !cvar("g_minstagib"))
+		if(g_vampire && !g_minstagib)
 		{
 			attacker.health += damage;
 		}
@@ -541,7 +541,7 @@
 	if(mirrordamage > 0 || mirrorforce > 0)
 	{
 		attacker = attacker_save;
-		if(cvar("g_minstagib"))
+		if(g_minstagib)
 			if(mirrordamage > 0)
 			{
 				// just lose extra LIVES, don't kill the player for mirror damage

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -246,7 +246,7 @@
 void GrapplingHookFrame()
 {
 	// this function has been modified for Nexuiz
-	if (self.button6 && cvar("g_grappling_hook"))
+	if (self.button6 && g_grappling_hook)
 	{
 		if (!self.hook && self.hook_time <= time && !self.button6_pressed_before)
 			FireGrapplingHook();
@@ -263,7 +263,7 @@
 	{
 		self.movetype = MOVETYPE_WALK;
 	}
-	if(self.impulse == GRAPHOOK_FIRE && self.hook_time <= time && cvar("g_grappling_hook"))
+	if(self.impulse == GRAPHOOK_FIRE && self.hook_time <= time && g_grappling_hook)
 	{
 		// fire hook
 		FireGrapplingHook();

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -2,6 +2,7 @@
 string redirection_target;
 
 string GetMapname();
+string GetGametype();
 void GotoNextMap();
 void ShuffleMaplist()
 float() DoNextMapOverride;
@@ -13,7 +14,7 @@
 		default_player_alpha = -1;
 		default_weapon_alpha = +1;
 	}
-	else if(cvar("g_cloaked"))
+	else if(g_cloaked)
 	{
 		default_player_alpha = cvar("g_balance_cloaked_alpha");
 		default_weapon_alpha = default_player_alpha;
@@ -60,10 +61,20 @@
 		cvar_set("_sv_init", "0");
 		if(cvar("g_maplist_shuffle"))
 			ShuffleMaplist();
+#ifdef MAPINFO
+		tokenizebyseparator(cvar_string("g_maplist"), " ");
+#else
 		tokenize(cvar_string("g_maplist"));
+#endif
 		if(argv(0) != GetMapname())
 		{
 			cvar_set("nextmap", argv(0));
+
+#ifdef MAPINFO
+			MapInfo_Enumerate();
+			MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0);
+#endif
+
 			if(!DoNextMapOverride())
 				GotoNextMap();
 		}
@@ -309,7 +320,11 @@
 		GameLogEcho(":logversion:2", FALSE);
 		s = strcat(cvar_string("sv_eventlog_files_counter"), ".");
 		s = strcat(s, ftos(random()));
+#ifdef MAPINFO
+		GameLogEcho(strcat(":gamestart:", GetGametype(), "_", GetMapname(), ":", s), FALSE);
+#else
 		GameLogEcho(strcat(":gamestart:", GetMapname(), ":", s), FALSE);
+#endif
 		s = ":gameinfo:mutators:LIST";
 		if(cvar("g_grappling_hook"))
 			s = strcat(s, ":grappling_hook");
@@ -349,6 +364,11 @@
 	readlevelcvars();
 
 	Ban_LoadBans();
+
+#ifdef MAPINFO
+	MapInfo_Enumerate();
+	MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 1);
+#endif
 }
 
 void light (void)
@@ -388,24 +408,34 @@
 		return "kh";
 	else if (game == GAME_ONSLAUGHT)
 		return "ons";
+	else if (game == GAME_ASSAULT)
+		return "as";
 	return "dm";
 }
 
 float IsSameGametype(string mapcfgname)
 {
+#ifdef MAPINFO
+	return TRUE; // can't change game type by map name here
+#else
 	string gt;
 	gt = GetGametype();
 	if(substring(mapcfgname, 0, strlen(gt) + 1) == strcat(gt, "_"))
 		return TRUE;
 	return FALSE;
+#endif
 }
 
 string getmapname_stored;
 string GetMapname()
 {
+#ifdef MAPINFO
+	return mapname;
+#else
 	if(getmapname_stored == "")
 		getmapname_stored = strzone(strcat(GetGametype(), "_", mapname));
 	return getmapname_stored;
+#endif
 }
 
 float Map_Count, Map_Current;
@@ -463,11 +493,14 @@
 	return TRUE;
 }
 
+#ifdef MAPINFO
+#else
 string Map_Filename(float position)
 {
 	// FIXME unused
 	return strcat("maps/", argv(position), ".mapcfg");
 }
+#endif
 
 string strwords(string s, float w)
 {
@@ -507,8 +540,12 @@
 		if(Map_IsRecent(map_next))
 			return 0;
 	}
+#ifdef MAPINFO
+	if(MapInfo_CheckMap(argv(position)))
+#else
 	filename = Map_Filename(position);
 	if(TryFile(filename))
+#endif
 	{
 		if(pass == 2)
 			return 1;
@@ -540,6 +577,12 @@
 
 void() GameResetCfg =
 {
+#ifdef MAPINFO
+	// settings persist, except...
+	if(cvar("g_campaign"))
+		localcmd("\nexec mutator_reset.cfg\n");
+	localcmd("\nsettemp_restore\n");
+#else
 	// if an exit cfg is defined by exiting map, exec it.
 	string exit_cfg;
 	exit_cfg = cvar_string("exit_cfg");
@@ -547,6 +590,7 @@
 		localcmd(strcat("exec \"", exit_cfg, "\"\n"));
 
 	localcmd("exec game_reset.cfg\n");
+#endif
 
 	Ban_SaveBans();
 };
@@ -555,7 +599,11 @@
 {
 	Map_MarkAsRecent(getmapname_stored);
 	GameResetCfg();
+#ifdef MAPINFO
+	MapInfo_LoadMap(getmapname_stored);
+#else
 	localcmd(strcat("exec \"maps/", getmapname_stored ,".mapcfg\"\n"));
+#endif
 }
 
 // return codes of map selectors:
@@ -624,13 +672,26 @@
 
 		// insert the current map there
 		newlist = "";
+#ifdef MAPINFO
 		for(j = 1; j < insertpos; ++j)                 // i == 1: no loop, will be inserted as first; however, i == 1 has been excluded above
+			newlist = strcat(newlist, " ", argv(j));
+		newlist = strcat(newlist, " ", argv(0));       // now insert the just selected map
+		for(j = insertpos; j < Map_Count; ++j)         // i == Map_Count: no loop, has just been inserted as last
+			newlist = strcat(newlist, " ", argv(j));
+		newlist = substring(newlist, 1, strlen(newlist) - 1);
+#else
+		for(j = 1; j < insertpos; ++j)                 // i == 1: no loop, will be inserted as first; however, i == 1 has been excluded above
 			newlist = strcat(newlist, "'", argv(j), "'");
 		newlist = strcat(newlist, "'", argv(0), "'");  // now insert the just selected map
 		for(j = insertpos; j < Map_Count; ++j)         // i == Map_Count: no loop, has just been inserted as last
 			newlist = strcat(newlist, "'", argv(j), "'");
+#endif
 		cvar_set("g_maplist", newlist);
+#ifdef MAPINFO
+		Map_Count = tokenizebyseparator(cvar_string("g_maplist"), " ");
+#else
 		Map_Count = tokenize(newlist);
+#endif
 
 		// NOTE: the selected map has just been inserted at (insertpos-1)th position
 		Map_Current = insertpos - 1; // this is not really valid, but this way the fallback has a chance of working
@@ -644,12 +705,22 @@
 {
 	string temp;
 	temp = cvar_string("g_maplist");
+#ifdef MAPINFO
+	Map_Count = tokenizebyseparator(cvar_string("g_maplist"), " ");
+#else
 	Map_Count = tokenize(temp);
+#endif
 	if(Map_Count == 0)
 	{
 		bprint( "Maplist is empty!  Resetting it to default map list.\n" );
+#ifdef MAPINFO
+		cvar_set("g_maplist", temp = MapInfo_ListAllowedMaps());
+		localcmd("\nmenu_cmd sync\n");
+		Map_Count = tokenizebyseparator(temp, " ");
+#else
 		cvar_set("g_maplist", temp = cvar_string("g_maplist_defaultlist"));
 		Map_Count = tokenize(temp);
+#endif
 	}
 	if(Map_Count == 0)
 		error("empty maplist, cannot select a new map");
@@ -726,7 +797,11 @@
 		return TRUE;
 	}
 	if(cvar_string("nextmap") != "")
+#ifdef MAPINFO
+		if(MapInfo_CheckMap(cvar_string("nextmap")))
+#else
 		if(TryFile(strcat("maps/", cvar_string("nextmap"), ".mapcfg")))
+#endif
 		{
 			Map_Goto_SetStr(cvar_string("nextmap"));
 			Map_Goto();
@@ -765,7 +840,12 @@
 			if(allowReset)
 			{
 				bprint( "Maplist contains no single playable map!  Resetting it to default map list.\n" );
+#ifdef MAPINFO
+				cvar_set("g_maplist", MapInfo_ListAllowedMaps());
+				localcmd("\nmenu_cmd sync\n");
+#else
 				cvar_set("g_maplist", cvar_string("g_maplist_defaultlist"));
+#endif
 			}
 			else
 			{
@@ -894,7 +974,11 @@
 		s = ":scores:";
 	else
 		s = ":status:";
+#ifdef MAPINFO
+	s = strcat(s, GetGametype(), "_", GetMapname(), ":", ftos(rint(time)));
+#else
 	s = strcat(s, GetMapname(), ":", ftos(rint(time)));
+#endif
 
 	if(to_console)
 		ServerConsoleEcho(s, FALSE);
@@ -1168,6 +1252,57 @@
 	return bound(1, lms_lowest_lives, fl);
 }
 
+// Assault winning condition: If the attackers triggered a round end (by fulfilling all objectives)
+// they win. Otherwise the defending team wins once the timelimit passes.
+void assault_new_round();
+float() WinningCondition_Assault =
+{
+	local float status;
+	status = WINNING_NO;
+
+	// as the timelimit has not yet passed just assume the defending team will win
+	if(assault_attacker_team == COLOR_TEAM1)
+	{
+		SetWinners(team, COLOR_TEAM2);
+	}
+	else
+	{
+		SetWinners(team, COLOR_TEAM1);
+	}	
+		
+	local entity ent;
+	ent = find(world, classname, "target_assault_roundend");
+	if(ent)
+	{
+		if(ent.winning)	// round end has been triggered by attacking team
+		{
+			SetWinners(team, assault_attacker_team);
+			if(assault_attacker_team == COLOR_TEAM1)
+			{
+				team1_score = team1_score + 50;
+			}
+			else
+			{
+				team2_score = team2_score + 50;
+			}
+
+			if(ent.cnt == 1) // this was the second round
+			{
+				status = WINNING_YES;
+			}
+			else
+			{
+				cvar_set("timelimit", ftos((2*time)/60));
+				assault_new_round();
+			}
+		}		
+	}
+
+	return status;
+
+}
+
+
 // LMS winning condition: game terminates if and only if there's at most one
 // one player who's living lives. Top two scores being equal cancels the time
 // limit.
@@ -1478,7 +1613,11 @@
 	float i;
 
 	result = cvar_string("g_maplist");
+#ifdef MAPINFO
+	litems = tokenizebyseparator(result, " ");
+#else
 	litems = tokenize(result);
+#endif
 
 	for(start = 0; start < litems - 1; ++start)
 	{
@@ -1488,7 +1627,18 @@
 		selected = ceil(random() * (litems - start) + start) - 1;
 
 		// shift this item to the place start
+#ifdef MAPINFO
 		for(i = 0; i < start; ++i)
+			result = strcat(result, " ", argv(i));
+		result = strcat(result, " ", argv(selected));
+		for(i = start; i < litems; ++i)
+			if(i != selected)
+				result = strcat(result, " ", argv(i));
+		result = substring(result, 1, strlen(result) - 1);
+
+		litems = tokenizebyseparator(result, " ");
+#else
+		for(i = 0; i < start; ++i)
 			result = strcat(result, "'", argv(i), "'");
 		result = strcat(result, "'", argv(selected), "'");
 		for(i = start; i < litems; ++i)
@@ -1496,6 +1646,7 @@
 				result = strcat(result, "'", argv(i), "'");
 
 		litems = tokenize(result);
+#endif
 
 		//dprint(result, "\n");
 	}
@@ -1572,11 +1723,15 @@
 	}
 
 	status = WINNING_NO;
-	if(cvar("g_lms"))
+	if(g_assault)
 	{
+		status = WinningCondition_Assault();
+	}
+	else if(g_lms)
+	{
 		status = WinningCondition_LMS();
 	}
-	else if (cvar("g_onslaught"))
+	else if (g_onslaught)
 	{
 		status = WinningCondition_Onslaught();
 	}
@@ -1584,7 +1739,7 @@
 	{
 		if(teams_matter)
 		{
-			if(cvar("g_tdm") || cvar("g_runematch") || cvar("g_ctf") || cvar("g_domination") || cvar("g_keyhunt"))
+			if(g_tdm || cvar("g_runematch") || g_ctf || cvar("g_domination") || g_keyhunt)
 				status = WinningCondition_MaxTeamSum(fraglimit);
 			//else if()
 			//	status = WinningCondition_MaxTeamMax(fraglimit);
@@ -1674,6 +1829,11 @@
 		return "Suggestions are not accepted on this server.";
 	if(mapvote_initialized)
 		return "Can't suggest - voting is already in progress!";
+#ifdef MAPINFO
+	m = MapInfo_FixName(m);
+	if(!m)
+		return "The map you suggested is not available on this server.";
+#endif
 	if(!cvar("g_maplist_votable_suggestions_change_gametype"))
 		if(!IsSameGametype(m))
 			return "This server does not allow changing the game type by map suggestions.";
@@ -1681,8 +1841,13 @@
 		if(Map_IsRecent(m))
 			return "This server does not allow for recent maps to be played again. Please be patient for some rounds.";
 
+#ifdef MAPINFO
+	if(!MapInfo_CheckMap(m))
+		return "The map you suggested does not support the current game mode.";
+#else
 	if(!TryFile(strcat("maps/", m, ".mapcfg")))
 		return "The map you suggested is not available on this server.";
+#endif
 	for(i = 0; i < mapvote_suggestion_ptr; ++i)
 		if(mapvote_suggestions[i] == m)
 			return "This map was already suggested.";
@@ -1699,7 +1864,7 @@
 		strunzone(mapvote_suggestions[i]);
 	mapvote_suggestions[i] = strzone(m);
 	GameLogEcho(strcat(":vote:suggested:", m, ":", ftos(self.playerid), ":", self.netname), TRUE);
-	return "Suggestion accepted.";
+	return strcat("Suggestion of ", m, " accepted.");
 }
 
 void MapVote_AddVotable(string nextMap, float isSuggestion)
@@ -1737,7 +1902,12 @@
 	if(mapvote_count == 0)
 	{
 		bprint( "Maplist contains no single playable map!  Resetting it to default map list.\n" );
+#ifdef MAPINFO
+		cvar_set("g_maplist", MapInfo_ListAllowedMaps());
+		localcmd("\nmenu_cmd sync\n");
+#else
 		cvar_set("g_maplist", cvar_string("g_maplist_defaultlist"));
+#endif
 		for(i = 0; i < 100 && mapvote_count < nmax; ++i)
 			MapVote_AddVotable(GetNextMap(), FALSE);
 	}
@@ -1941,7 +2111,14 @@
 }
 void MapVote_Start()
 {
-	mapvote_run = TRUE;
+	if(mapvote_run)
+		return;
+
+#ifdef MAPINFO
+	MapInfo_Enumerate();
+	if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 1))
+#endif
+		mapvote_run = TRUE;
 }
 void MapVote_Think()
 {
@@ -1975,7 +2152,11 @@
 
 string GotoMap(string m)
 {
+#ifdef MAPINFO
+	if(!MapInfo_CheckMap(m))
+#else
 	if(!TryFile(strcat("maps/", m, ".mapcfg")))
+#endif
 		return "The map you chose is not available on this server.";
 	cvar_set("nextmap", m);
 	cvar_set("timelimit", "-1");

Modified: branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -1,5 +1,19 @@
 string GotoMap(string m);
 
+void make_mapinfo_Think()
+{
+	if(MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 1))
+	{
+		print("Done rebuiling mapinfos.\n");
+		remove(self);
+	}
+	else
+	{
+		self.think = make_mapinfo_Think;
+		self.nextthink = time;
+	}
+}
+
 void GameCommand(string command)
 {
 	float argc;
@@ -11,6 +25,7 @@
 		print("  adminmsg clientnumber \"message\"\n");
 		print("  teamstatus\n");
 		print("  printstats\n");
+		print("  make_mapinfo\n");
 		GameCommand_Ban("help");
 		GameCommand_Generic("help");
 		return;
@@ -34,6 +49,16 @@
 		return;
 	}
 
+	if(argv(0) == "make_mapinfo")
+	{
+		entity e;
+		e = spawn();
+		e.classname = "make_mapinfo";
+		e.think = make_mapinfo_Think;
+		e.nextthink = time;
+		return;
+	}
+
 	if(argv(0) == "warp") if(argc == 2) if(cvar("g_campaign"))
 	{
 		CampaignLevelWarp(stof(argv(1)));

Modified: branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -709,11 +709,11 @@
 	dprint("choose a role...\n");
 	navigation_routetogoal(world);
 	self.bot_strategytime = -1;
-	if (cvar("g_ctf"))
+	if (g_ctf)
 		havocbot_chooserole_ctf();
 	else if (cvar("g_domination"))
 		havocbot_chooserole_dom();
-	else if (cvar("g_keyhunt"))
+	else if (g_keyhunt)
 		havocbot_chooserole_kh();
 	else // assume anything else is deathmatch
 		havocbot_chooserole_dm();

Modified: branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -77,47 +77,6 @@
 	}
 }
 
-// converts a number to a string with the indicated number of decimals
-// works for up to 10 decimals!
-string ftos_decimals(float number, float decimals)
-{
-	string result;
-	string tmp;
-	float len;
-
-	// if negative, cut off the sign first
-	if(number < 0)
-		return strcat("-", ftos_decimals(-number, decimals));
-	// it now is always positive!
-
-	// 3.516 -> 352
-	number = floor(number * pow(10, decimals) + 0.5);
-
-	// 352 -> "352"
-	result = ftos(number);
-	len = strlen(result);
-	// does it have a decimal point (should not happen)? If there is one, it is always at len-7)
-		// if ftos had fucked it up, which should never happen: "34278.000000"
-	if(len >= 7)
-		if(substring(result, len - 7, 1) == ".")
-		{
-			dprint("ftos(integer) has comma? Can't be. Affected result: ", result, "\n");
-			result = substring(result, 0, len - 7);
-			len -= 7;
-		}
-		// "34278"
-	// is it too short? If yes, insert leading zeroes
-	if(len <= decimals)
-	{
-		result = strcat(substring("0000000000", 0, decimals - len + 1), result);
-		len = decimals + 1;
-	}
-	// and now... INSERT THE POINT!
-	tmp = substring(result, len - decimals, decimals);
-	result = strcat(substring(result, 0, len - decimals), ".", tmp);
-	return result;
-}
-
 #define FOR_EACH_CLIENT(v) for(v = world; (v = findflags(v, flags, FL_CLIENT)) != world; )
 #define FOR_EACH_REALCLIENT(v) FOR_EACH_CLIENT(v) if(clienttype(v) == CLIENTTYPE_REAL)
 string STR_PLAYER = "player";
@@ -728,6 +687,19 @@
 
 void readlevelcvars(void)
 {
+	g_cloaked = cvar("g_cloaked");
+	g_footsteps = cvar("g_footsteps");
+	g_grappling_hook = cvar("g_grappling_hook");
+	g_instagib = cvar("g_instagib");
+	g_laserguided_missile = cvar("g_laserguided_missile");
+	g_midair = cvar("g_midair");
+	g_minstagib = cvar("g_minstagib");
+	g_nixnex = cvar("g_nixnex");
+	g_nixnex_with_laser = cvar("g_nixnex_with_laser");
+	g_norecoil = cvar("g_norecoil");
+	g_rocketarena = cvar("g_rocketarena");
+	g_vampire = cvar("g_vampire");
+
 	g_pickup_shells                    = cvar("g_pickup_shells");
 	g_pickup_shells_max                = cvar("g_pickup_shells_max");
 	g_pickup_nails                     = cvar("g_pickup_nails");
@@ -757,26 +729,26 @@
 	start_health = cvar("g_balance_health_start");
 	start_armorvalue = cvar("g_balance_armor_start");
 
-	if(cvar("g_instagib"))
+	if(g_instagib)
 	{
 		start_items = IT_NEX;
 		start_switchweapon = WEP_NEX;
 		weapon_action(start_switchweapon, WR_PRECACHE);
 		start_ammo_cells = 999;
 	}
-	else if(cvar("g_rocketarena"))
+	else if(g_rocketarena)
 	{
 		start_items = IT_ROCKET_LAUNCHER;
 		start_switchweapon = WEP_ROCKET_LAUNCHER;
 		weapon_action(start_switchweapon, WR_PRECACHE);
 		start_ammo_rockets = 999;
 	}
-	else if(cvar("g_nixnex"))
+	else if(g_nixnex)
 	{
 		start_items = 0;
 		// will be done later
 	}
-	else if(cvar("g_minstagib"))
+	else if(g_minstagib)
 	{
 		start_health = 100;
 		start_armorvalue = 0;
@@ -787,7 +759,7 @@
 	}
 	else
 	{
-		if(cvar("g_lms"))
+		if(g_lms)
 		{
 			start_ammo_shells = cvar("g_lms_start_ammo_shells");
 			start_ammo_nails = cvar("g_lms_start_ammo_nails");
@@ -808,55 +780,55 @@
 			start_ammo_cells = cvar("g_pickup_cells_max");
 		}
 
-		if (cvar("g_start_weapon_laser") || cvar("g_lms"))
+		if (cvar("g_start_weapon_laser") || g_lms)
 		{
 			start_items = start_items | IT_LASER;
 			start_switchweapon = WEP_LASER;
 			weapon_action(start_switchweapon, WR_PRECACHE);
 		}
-		if (cvar("g_start_weapon_shotgun") || cvar("g_lms"))
+		if (cvar("g_start_weapon_shotgun") || g_lms)
 		{
 			start_items = start_items | IT_SHOTGUN;
 			start_switchweapon = WEP_SHOTGUN;
 			weapon_action(start_switchweapon, WR_PRECACHE);
 		}
-		if (cvar("g_start_weapon_uzi") || cvar("g_lms"))
+		if (cvar("g_start_weapon_uzi") || g_lms)
 		{
 			start_items = start_items | IT_UZI;
 			start_switchweapon = WEP_UZI;
 			weapon_action(start_switchweapon, WR_PRECACHE);
 		}
-		if (cvar("g_start_weapon_grenadelauncher") || cvar("g_lms"))
+		if (cvar("g_start_weapon_grenadelauncher") || g_lms)
 		{
 			start_items = start_items | IT_GRENADE_LAUNCHER;
 			start_switchweapon = WEP_GRENADE_LAUNCHER;
 			weapon_action(start_switchweapon, WR_PRECACHE);
 		}
-		if (cvar("g_start_weapon_electro") || cvar("g_lms"))
+		if (cvar("g_start_weapon_electro") || g_lms)
 		{
 			start_items = start_items | IT_ELECTRO;
 			start_switchweapon = WEP_ELECTRO;
 			weapon_action(start_switchweapon, WR_PRECACHE);
 		}
-		if (cvar("g_start_weapon_crylink") || cvar("g_lms"))
+		if (cvar("g_start_weapon_crylink") || g_lms)
 		{
 			start_items = start_items | IT_CRYLINK;
 			start_switchweapon = WEP_CRYLINK;
 			weapon_action(start_switchweapon, WR_PRECACHE);
 		}
-		if (cvar("g_start_weapon_nex") || cvar("g_lms"))
+		if (cvar("g_start_weapon_nex") || g_lms)
 		{
 			start_items = start_items | IT_NEX;
 			start_switchweapon = WEP_NEX;
 			weapon_action(start_switchweapon, WR_PRECACHE);
 		}
-		if (cvar("g_start_weapon_hagar") || cvar("g_lms"))
+		if (cvar("g_start_weapon_hagar") || g_lms)
 		{
 			start_items = start_items | IT_HAGAR;
 			start_switchweapon = WEP_HAGAR;
 			weapon_action(start_switchweapon, WR_PRECACHE);
 		}
-		if (cvar("g_start_weapon_rocketlauncher") || cvar("g_lms"))
+		if (cvar("g_start_weapon_rocketlauncher") || g_lms)
 		{
 			start_items = start_items | IT_ROCKET_LAUNCHER;
 			start_switchweapon = WEP_ROCKET_LAUNCHER;

Modified: branches/nexuiz-2.0/data/qcsrc/server/mode_onslaught.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/mode_onslaught.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/mode_onslaught.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -227,7 +227,7 @@
 */
 void() onslaught_generator =
 {
-	if (!cvar("g_onslaught"))
+	if (!g_onslaught)
 	{
 		remove(self);
 		return;
@@ -409,7 +409,7 @@
 void() onslaught_controlpoint =
 {
 	local entity e;
-	if (!cvar("g_onslaught"))
+	if (!g_onslaught)
 	{
 		remove(self);
 		return;
@@ -465,7 +465,7 @@
 */
 void() onslaught_link =
 {
-	if (!cvar("g_onslaught"))
+	if (!g_onslaught)
 	{
 		remove(self);
 		return;

Modified: branches/nexuiz-2.0/data/qcsrc/server/progs.src
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/progs.src	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/progs.src	2007-11-29 07:56:24 UTC (rev 2996)
@@ -12,6 +12,8 @@
 ../common/util.qh
 ../common/util.qc
 
+../common/mapinfo.qh
+
 ipban.qh
 
 keyhunt.qh
@@ -92,4 +94,8 @@
 
 keyhunt.qc
 
+assault.qc
+
 ipban.qc
+
+../common/mapinfo.qc

Modified: branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -104,7 +104,7 @@
 			}
 
 			// play stupid sounds
-			if (cvar("g_footsteps"))
+			if (g_footsteps)
 			if (!gameover)
 			if (self.flags & FL_ONGROUND)
 			if (vlen(self.velocity) > sv_maxspeed * 0.6)

Modified: branches/nexuiz-2.0/data/qcsrc/server/t_items.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_items.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_items.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -45,7 +45,7 @@
 	pickedup = FALSE;
 	_switchweapon = FALSE;
 
-	if (cvar("g_minstagib"))
+	if (g_minstagib)
 	{
 		_switchweapon = TRUE;
 		if (self.ammo_cells)
@@ -304,7 +304,7 @@
 		itemsInMap |= itemid;
 	}
 
-	if (!(cvar("g_pickup_items") && !cvar("g_nixnex")) && !cvar("g_minstagib") &&
+	if (!(cvar("g_pickup_items") && !g_nixnex) && !g_minstagib &&
 			itemid != IT_STRENGTH && itemid != IT_INVINCIBLE && itemid != IT_HEALTH)
 	{
 		startitem_failed = TRUE;
@@ -312,7 +312,7 @@
 		return;
 	}
 
-	if (cvar("g_minstagib"))
+	if (g_minstagib)
 	{
 		// don't remove dropped items and powerups
 		if (self.classname != "droppedweapon" &&
@@ -324,14 +324,14 @@
 		}
 	}
 
-	if(cvar("g_lms") && (self.classname != "droppedweapon"))
+	if(g_lms && (self.classname != "droppedweapon"))
 	{
 		startitem_failed = TRUE;
 		remove(self);
 		return;
 	}
 
-	if(cvar("g_instagib") || cvar("g_rocketarena"))
+	if(g_instagib || g_rocketarena)
 	{
 		startitem_failed = TRUE;
 		remove(self);
@@ -534,7 +534,7 @@
 void weapon_nex (void)
 {
 	float nextime;
-	if (cvar("g_minstagib"))
+	if (g_minstagib)
 	{
 		minstagib_items(IT_CELLS);
 		self.think = minst_remove_item;
@@ -564,7 +564,7 @@
 
 void weapon_rocketlauncher (void)
 {
-	if (cvar("g_minstagib"))
+	if (g_minstagib)
 	{
 		minstagib_items(IT_CELLS);
 		self.think = minst_remove_item;
@@ -638,10 +638,10 @@
 	if(!cvar("g_powerup_superhealth"))
 		return;
 
-	if(cvar("g_arena") && !cvar("g_arena_powerups"))
+	if(g_arena && !cvar("g_arena_powerups"))
 		return;
 
-	if(cvar("g_minstagib")) {
+	if(g_minstagib) {
 		minstagib_items(IT_NAILS);
 	} else {
 		if(!self.max_health)
@@ -656,10 +656,10 @@
 	if(!cvar("g_powerup_strength"))
 		return;
 
-	if(cvar("g_arena") && !cvar("g_arena_powerups"))
+	if(g_arena && !cvar("g_arena_powerups"))
 		return;
 
-	if(cvar("g_minstagib")) {
+	if(g_minstagib) {
 		minstagib_items(IT_STRENGTH);
 	} else {
 		precache_sound("weapons/strength_fire.wav");
@@ -672,10 +672,10 @@
 	if(!cvar("g_powerup_shield"))
 		return;
 
-	if(cvar("g_arena") && !cvar("g_arena_powerups"))
+	if(g_arena && !cvar("g_arena_powerups"))
 		return;
 
-	if(cvar("g_minstagib")) {
+	if(g_minstagib) {
 		minstagib_items(IT_INVINCIBLE);
 	} else {
 		self.invincible_finished = 30;
@@ -687,7 +687,7 @@
 //void item_slowmo (void) {self.slowmo_finished = 30;StartItem ("models/items/g_slowmo.md3", "misc/powerup.wav", 120, "Slow Motion", IT_SLOWMO, FL_POWERUP, generic_pickupevalfunc, 10000);}
 
 void item_minst_cells (void) {
-	if (cvar("g_minstagib"))
+	if (g_minstagib)
 	{
 		minst_no_auto_cells = 1;
 		minstagib_items(IT_CELLS);

Modified: branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -6,6 +6,7 @@
 float GAME_LMS			= 6;
 float GAME_ARENA		= 7;
 float GAME_KEYHUNT		= 8;
+float GAME_ASSAULT		= 9;
 float GAME_ONSLAUGHT	= 10;
 
 // client counts for each team
@@ -13,8 +14,6 @@
 // # of bots on those teams
 float cb1, cb2, cb3, cb4;
 
-float g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught;
-
 float audit_teams_time;
 
 float() IsTeamBalanceForced = {
@@ -97,6 +96,7 @@
 
 void ResetGameCvars()
 {
+	cvar_set("g_dm", "0");
 	cvar_set("g_tdm", "0");
 	cvar_set("g_domination", "0");
 	cvar_set("g_ctf", "0");
@@ -104,6 +104,7 @@
 	cvar_set("g_lms", "0");
 	cvar_set("g_arena", "0");
 	cvar_set("g_keyhunt", "0");
+	cvar_set("g_assault", "0");
 	cvar_set("g_onslaught", "0");
 	cvar_set("teamplay", "0");
 }
@@ -125,7 +126,7 @@
 
 	VoteReset();
 
-	game = cvar ("gamecfg");	// load game options
+	game = cvar("gamecfg");	// load game options
 
 	// game cvars get reset before map changes
 	// then map's cfg sets them as desired
@@ -162,10 +163,11 @@
 		gamemode_name = "Capture the Flag";
 		teams_matter = 1;
 	}
-	else if((game == GAME_RUNEMATCH || cvar("g_runematch")) && !cvar("g_minstagib"))
+	else if(game == GAME_RUNEMATCH || cvar("g_runematch"))
 	{
 		game = GAME_RUNEMATCH;
 		cvar_set("g_runematch", "1");
+		cvar_set("g_minstagib", "0");
 
 		if(cvar("deathmatch_force_teamplay"))
 			ActivateTeamplay();
@@ -203,6 +205,15 @@
 
 		fraglimit_override = cvar("fraglimit_override");
 	}
+	else if(game == GAME_ASSAULT || cvar("g_assault"))
+	{
+		ResetGameCvars();
+		game = GAME_ASSAULT;
+		gamemode_name = "Assault";
+		ActivateTeamplay();
+		teams_matter = 1;
+		cvar_set("g_assault", "1");
+	}
 	else if(game == GAME_LMS || cvar("g_lms"))
 	{
 		ResetGameCvars();
@@ -253,6 +264,7 @@
 	{
 		// we can only assume...
 		ResetGameCvars();
+		cvar_set("g_dm", "1");
 		gamemode_name = "Deathmatch";
 		teams_matter = 0;
 	}
@@ -289,17 +301,17 @@
 		kh_init();
 
 	// those mutators rule each other out
-	if(cvar("g_minstagib"))
+	if(g_minstagib)
 	{
 		cvar_set("g_instagib", "0");
 		cvar_set("g_rocketarena", "0");
 	}
-	if(cvar("g_instagib"))
+	if(g_instagib)
 	{
 		cvar_set("g_minstagib", "0");
 		cvar_set("g_rocketarena", "0");
 	}
-	if(cvar("g_rocketarena"))
+	if(g_rocketarena)
 	{
 		cvar_set("g_instagib", "0");
 		cvar_set("g_minstagib", "0");
@@ -312,9 +324,12 @@
 
 	g_domination = cvar("g_domination");
 	g_ctf = cvar("g_ctf");
+	g_lms = cvar("g_lms");
 	g_tdm = cvar("g_tdm");
 	g_keyhunt = cvar("g_keyhunt");
 	g_onslaught = cvar("g_onslaught");
+	g_assault = cvar("g_assault");
+	g_arena = cvar("g_arena");
 }
 
 string GetClientVersionMessage(float v) {
@@ -356,43 +371,43 @@
 
 	if(self.classname == "observer")
 	{
-		if(cvar("g_lms") && self.frags <= 0 && self.frags > -666)
+		if(g_lms && self.frags <= 0 && self.frags > -666)
 			return centerprint(self, strcat(NEWLINES, "^1You have no more lives left\nwait for next round\n\n\n^7press attack to spectate other players"));
-		else if(cvar("g_lms") && self.frags == -666)
+		else if(g_lms && self.frags == -666)
 			return centerprint(self, strcat(NEWLINES, "^1Match has already begun\nwait for next round\n\n\n^7press attack to spectate other players"));
 	}
 	else if(self.classname == "spectator")
 	{
-		if ((cvar("g_lms") && self.frags < 1) || cvar("g_arena"))
+		if ((g_lms && self.frags < 1) || g_arena)
 			return centerprint(self, strcat(NEWLINES, "spectating ", self.enemy.netname, "\n\n\n^7press attack for next player\npress attack2 for free fly mode"));
 		else
 			return centerprint(self, strcat(NEWLINES, "spectating ", self.enemy.netname, "\n\n\n^7press jump to play\n^7press attack for next player\npress attack2 for free fly mode"));
 	}
 
 
-	if(cvar("g_minstagib"))
+	if(g_minstagib)
 		mutator = "^2Minstagib ^1";
-	else if(cvar("g_instagib"))
+	else if(g_instagib)
 		mutator = "^2Instagib ^1";
-	else if(cvar("g_rocketarena"))
+	else if(g_rocketarena)
 		mutator = "^2Rocketarena ^1";
-	else if(cvar("g_nixnex"))
+	else if(g_nixnex)
 		mutator = "^2No Items Nexuiz ^1";
 
-	if(cvar("g_midair")) {
+	if(g_midair) {
 		// to protect against unheedingly made changes
 		if (modifications) {
 			modifications = strcat(modifications, ", ");
 		}
 		modifications = "midair";
 	}
-	if(cvar("g_vampire")) {
+	if(g_vampire) {
 		if (modifications) {
 			modifications = strcat(modifications, ", ");
 		}
 		modifications = strcat(modifications, "vampire");
 	}
-	if(cvar("g_laserguided_missile")) {
+	if(g_laserguided_missile) {
 		if (modifications) {
 			modifications = strcat(modifications, ", ");
 		}
@@ -409,7 +424,7 @@
 		s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
 
 	if((self.classname == "observer" || self.classname == "spectator") && self.version == cvar("gameversion")) {
-		if(!cvar("g_arena"))
+		if(!g_arena)
 			s = strcat(s,"^7\n\n\npress jump to play\npress attack to spectate other players\n\n");
 		else if(player_count < 2 && arena_roundbased)
 		{
@@ -427,7 +442,7 @@
 
 	s = strzone(s);
 
-	if (cvar("g_grappling_hook"))
+	if (g_grappling_hook)
 		s = strcat(s, "\n\n^8grappling hook is enabled, press 'e' to use it\n");
 
 	if (cvar_string("_mutatormsg") != "") {
@@ -544,6 +559,11 @@
 		teament_name = "ctf_team";
 	else if(g_tdm)
 		teament_name = "tdm_team";
+	else if(g_assault)
+	{
+		c1 = c2 = 0; // Assault always has 2 teams
+		return;
+	}
 	else
 	{
 		// cover anything else by treating it like tdm with no teams spawned
@@ -808,7 +828,7 @@
 	// find out what teams are available
 	CheckAllowedTeams(pl);
 
-	if(cvar("g_domination"))
+	if(g_domination)
 	{
 		if(cvar("g_domination_default_teams") < 3)
 			c3 = 999999999;
@@ -907,26 +927,6 @@
 	else if(dcolor == COLOR_TEAM4 - 1)
 		dteam = 4;
 
-	// remap invalid teams in dom & ctf
-	/*
-	if(cvar("g_ctf") && dteam == 3)
-		dteam = 2;
-	else if(cvar("g_ctf") && dteam == 4)
-		dteam = 1;
-	else if((cvar("g_domination") && cvar("g_domination_default_teams") < 3) || (cvar("g_tdm") && cvar("g_tdm_teams") < 3))
-	{
-		if(dteam == 3)
-			dteam = 2;
-		else if(dteam == 4)
-			dteam = 1;
-	}
-	else if((cvar("g_domination") && cvar("g_domination_default_teams") < 4) || (cvar("g_tdm") && cvar("g_tdm_teams") < 4))
-	{
-		if(dteam == 4)
-			dteam = 1;
-	}
-	*/
-
 	CheckAllowedTeams(self);
 
 	if(dteam == 1 && c1 < 0) dteam = 4;
@@ -1322,6 +1322,10 @@
 
 	tdm_spawnteam("Red", COLOR_TEAM1-1);
 	tdm_spawnteam("Blue", COLOR_TEAM2-1);
+	if(numteams >= 3)
+		tdm_spawnteam("Yellow", COLOR_TEAM3-1);
+	if(numteams >= 4)
+		tdm_spawnteam("Pink", COLOR_TEAM4-1);
 };
 
 void() tdm_delayedinit =

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -5,7 +5,7 @@
 	W_SetupShot (self, '5 14 -8', TRUE, 5, "weapons/nexfire.wav");
 
 	// assure that nexdamage is high enough in minstagib
-	if (cvar("g_minstagib"))
+	if (g_minstagib)
 		FireRailgunBullet (w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, 1000, 800, IT_NEX);
 	else
 		FireRailgunBullet (w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, cvar("g_balance_nex_damage"), cvar("g_balance_nex_force"), IT_NEX);
@@ -31,9 +31,9 @@
 	// play a sound
 	PointSound (trace_endpos, "weapons/neximpact.wav", 1, ATTN_NORM);
 
-	if (cvar("g_use_ammunition") && !cvar("g_instagib"))
+	if (cvar("g_use_ammunition") && !g_instagib)
 	{
-		if (cvar("g_minstagib"))
+		if (g_minstagib)
 			self.ammo_cells = self.ammo_cells - 1;
 		else
 			self.ammo_cells = self.ammo_cells - cvar("g_balance_nex_ammo");
@@ -143,7 +143,7 @@
 	{
 		if (self.button0)
 		{
-			if(cvar("g_minstagib"))
+			if(g_minstagib)
 			{
 				if (weapon_prepareattack(0, cvar("g_balance_minstagib_nex_refire")))
 				{
@@ -162,7 +162,7 @@
 		}
 		else if (self.button3)
 		{
-			if (cvar("g_minstagib"))
+			if (g_minstagib)
 			{
 				if (self.jump_interval <= time)
 				{
@@ -185,7 +185,7 @@
 		weapon_setup(WEP_NEX, "nex", IT_CELLS);
 	else if (req == WR_CHECKAMMO1)
 	{
-		if (cvar("g_minstagib"))
+		if (g_minstagib)
 			return self.ammo_cells >= 1;
 		else
 			return self.ammo_cells >= cvar("g_balance_nex_ammo");

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_rocketlauncher.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_rocketlauncher.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_rocketlauncher.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -27,7 +27,7 @@
 			ATTACK_FINISHED(self.owner) = time;
 			self.owner.switchweapon = w_getbestweapon(self.owner);
 		}
-		if(cvar("g_laserguided_missile"))
+		if(g_laserguided_missile)
 			ATTACK_FINISHED(self.owner) = time + cvar("g_balance_rocketlauncher_refire");
 	}
 	remove (self);
@@ -97,7 +97,7 @@
 		return;
 	}
 
-	if(cvar("g_laserguided_missile"))
+	if(g_laserguided_missile)
 	{
 		// accelerate
 		makevectors(self.angles_x * '-1 0 0' + self.angles_y * '0 1 0');
@@ -117,7 +117,7 @@
 	// laser guided, or remote detonation
 	if (self.owner.weapon == WEP_ROCKET_LAUNCHER)
 	{
-		if(cvar("g_laserguided_missile"))
+		if(g_laserguided_missile)
 		{
 			if(!self.owner.button0)
 				self.ltime = -1; // indicate that the player has let go of the button
@@ -201,7 +201,7 @@
 	local entity missile;
 	local entity flash, flash2;
 
-	if (cvar("g_use_ammunition") && !cvar("g_rocketarena"))
+	if (cvar("g_use_ammunition") && !g_rocketarena)
 		self.ammo_rockets = self.ammo_rockets - cvar("g_balance_rocketlauncher_ammo");
 
 	W_SetupShot (self, '8 3 -8', FALSE, 5, "weapons/rocket_fire.wav");
@@ -225,7 +225,7 @@
 	setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
 
 	setorigin (missile, w_shotorg);
-	if(cvar("g_laserguided_missile") && self.laser_on)
+	if(g_laserguided_missile && self.laser_on)
 		missile.velocity = w_shotdir * cvar("g_balance_rocketlauncher_laserguided_speedstart");
 	else
 		missile.velocity = w_shotdir * cvar("g_balance_rocketlauncher_speedstart");
@@ -378,7 +378,7 @@
 			sound (self, CHAN_BODY, "weapons/rocket_det.wav", 0.5, ATTN_NORM);
 		}
 		if (self.button3)
-		if(cvar("g_laserguided_missile"))
+		if(g_laserguided_missile)
 		if(self.exteriorweaponentity.attack_finished_single < time)
 		{
 			self.exteriorweaponentity.attack_finished_single = time + 0.4;
@@ -397,7 +397,7 @@
 		precache_sound ("weapons/rocket_fire.wav");
 		precache_sound ("weapons/rocket_fly.wav");
 		precache_sound ("weapons/rocket_impact.wav");
-		if (cvar("g_laserguided_missile"))
+		if (g_laserguided_missile)
 			precache_model ("models/laser_dot.mdl"); // rocket launcher
 	}
 	else if (req == WR_SETUP)

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc	2007-11-29 07:56:24 UTC (rev 2996)
@@ -11,7 +11,7 @@
 			self.ammo_nails = self.ammo_nails - cvar("g_balance_uzi_sustained_ammo");
 	}
 	W_SetupShot (self, '11 5.5 -8', TRUE, 0, "weapons/uzi_fire.wav");
-	if (!cvar("g_norecoil"))
+	if (!g_norecoil)
 	{
 		self.punchangle_x = random () - 0.5;
 		self.punchangle_y = random () - 0.5;

Modified: branches/nexuiz-2.0/data/scripts/final_rage.shader
===================================================================
--- branches/nexuiz-2.0/data/scripts/final_rage.shader	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/scripts/final_rage.shader	2007-11-29 07:56:24 UTC (rev 2996)
@@ -6,7 +6,7 @@
 	cull disable
 	q3map_surfacelight 1000
 	{
-		map textures/final_rage/lava1.tga
+		map textures/final_rage/lava.tga
 	}
 }
 

Added: branches/nexuiz-2.0/data/textures/core.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/core.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/core_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/core_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/core_glow.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/core_glow.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_cln_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_cln_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_cln_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_cln_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty2_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty2_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty2_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty2_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_drty_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_rusty_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_rusty_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_rusty_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl2_rusty_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cln_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cln_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cln_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cln_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cmbo_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cmbo_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cmbo_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_cmbo_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty2_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty2_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty2_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty2_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_drty_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_rusty_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_rusty_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_rusty_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/doormtl_rusty_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst2_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst2_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst2_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst2_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst3_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst3_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst3_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst3_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst4_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst4_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst4_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst4_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst5_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst5_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst5_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/mtl_rst5_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1b_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1b_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1b_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal1b_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2b_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2b_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2b_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2b_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2c_bump.jpg
===================================================================
(Binary files differ)

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2c_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2c_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2c_gloss.jpg
===================================================================
(Binary files differ)

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2c_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2c_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2d_bump.jpg
===================================================================
(Binary files differ)

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2d_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2d_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2d_gloss.jpg
===================================================================
(Binary files differ)

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2d_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2d_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2e_bump.jpg
===================================================================
(Binary files differ)

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2e_bump.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2e_bump.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Deleted: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2e_gloss.jpg
===================================================================
(Binary files differ)

Added: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2e_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/evil1_metals/rmetal2e_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/pad.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/pad.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/pad_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/pad_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/pad_glow.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/pad_glow.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/pad_shirt.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/pad_shirt.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/reactor.jpg
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/reactor.jpg
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/reactor.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/reactor.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/reactor_glow.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/reactor_glow.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/reactor_shirt.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/reactor_shirt.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/shield.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/shield.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/shield_gloss.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/shield_gloss.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/shield_glow.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/shield_glow.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/nexuiz-2.0/data/textures/shield_norm.tga
===================================================================
(Binary files differ)


Property changes on: branches/nexuiz-2.0/data/textures/shield_norm.tga
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: branches/nexuiz-2.0/data/ultimate.cfg
===================================================================
--- branches/nexuiz-2.0/data/ultimate.cfg	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/ultimate.cfg	2007-11-29 07:56:24 UTC (rev 2996)
@@ -7,7 +7,6 @@
 gl_texture_anisotropy 16
 r_bloom 1
 r_coronas 1
-gl_flashblend 0
 r_glsl_deluxemapping 1
 r_glsl_offsetmapping 1
 r_glsl_offsetmapping_reliefmapping 1

Modified: branches/nexuiz-2.0/data/ultra.cfg
===================================================================
--- branches/nexuiz-2.0/data/ultra.cfg	2007-11-29 07:45:44 UTC (rev 2995)
+++ branches/nexuiz-2.0/data/ultra.cfg	2007-11-29 07:56:24 UTC (rev 2996)
@@ -7,7 +7,6 @@
 gl_texture_anisotropy 16
 r_bloom 1
 r_coronas 1
-gl_flashblend 0
 r_glsl_deluxemapping 1
 r_glsl_offsetmapping 1
 r_glsl_offsetmapping_reliefmapping 0




More information about the nexuiz-commits mailing list