r5203 - in branches/nexuiz-2.0: . Docs Docs/server data data/maps data/qcsrc/common data/qcsrc/menu/nexuiz data/qcsrc/server data/scripts misc misc/ttf2conchars

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Fri Dec 12 18:12:19 EST 2008


Author: div0
Date: 2008-12-12 18:12:17 -0500 (Fri, 12 Dec 2008)
New Revision: 5203

Added:
   branches/nexuiz-2.0/data/maps/bloodprisonctf.ent
   branches/nexuiz-2.0/data/update-cvarcount.sh
   branches/nexuiz-2.0/misc/dependencies.pl
   branches/nexuiz-2.0/misc/jpeg-if-not-alpha.sh
Modified:
   branches/nexuiz-2.0/.patchsets
   branches/nexuiz-2.0/Docs/eventlog.txt
   branches/nexuiz-2.0/Docs/server/server.cfg
   branches/nexuiz-2.0/data/ctfscoring-div0.cfg
   branches/nexuiz-2.0/data/defaultNexuiz.cfg
   branches/nexuiz-2.0/data/effectinfo.txt
   branches/nexuiz-2.0/data/maps/basementctf.bsp
   branches/nexuiz-2.0/data/maps/basementctf.map
   branches/nexuiz-2.0/data/maps/bloodprisonctf.map
   branches/nexuiz-2.0/data/maps/dismal.ent
   branches/nexuiz-2.0/data/maps/runningmanctf.ent
   branches/nexuiz-2.0/data/maps/runningmanctf.map
   branches/nexuiz-2.0/data/maps/silvercity.ent
   branches/nexuiz-2.0/data/maps/starship.ent
   branches/nexuiz-2.0/data/qcsrc/common/items.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/nexuiz/dialog_settings_effects.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qh
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/weaponslist.c
   branches/nexuiz-2.0/data/qcsrc/server/arena.qc
   branches/nexuiz-2.0/data/qcsrc/server/assault.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.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/extensions.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_triggers.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/ipban.qc
   branches/nexuiz-2.0/data/qcsrc/server/ipban.qh
   branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
   branches/nexuiz-2.0/data/qcsrc/server/t_items.qc
   branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc
   branches/nexuiz-2.0/data/qcsrc/server/t_teleporters.qc
   branches/nexuiz-2.0/data/qcsrc/server/vote.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_hook.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_seeker.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc
   branches/nexuiz-2.0/data/scripts/common.shader
   branches/nexuiz-2.0/data/scripts/entities.def
   branches/nexuiz-2.0/data/weapons.cfg
   branches/nexuiz-2.0/data/weaponsPro.cfg
   branches/nexuiz-2.0/misc/bsptool.pl
   branches/nexuiz-2.0/misc/ttf2conchars/ttf2conchars.c
Log:
support "cnt" field in items as probability weight for teamed items; works like for spawns
seeker: separate out flac effect
bsptool: -ljpg = externalize lightmaps, save as jpg
use stretchfactor 0.6 for teleport; reduce teleporter spam by only playing one effect every 0.2 seconds
dependencies.pl: lists dependencies of a map pack (helps identifying unused files)
make lasers work better with wrong particle effect names
add "sv_cmd find"; fix doors with DOOR_DONT_LINK
hook: apply the hook bomb damage over time (FIXME check if this may cause too much server load)
switch to ctfscoring-div0 (from the forum poll)
also switch CTF win mode to 0
separate respawn times for weapons and ammo now; ENFORCE config file version matching the QC code
fteqcc now supports more than 8 macro args - use them
get rid of the stupid (-) operator, use the more readable &~= (so QC newbies can guess what it means too)
added a simple way to sync ban lists online via a http server. CGI scripts for that not written yet.
new command: "records", listing all records on this server
cache replies of some cmd commands that take long
added sv_cmd suggestmap.. admins wanna have fun too :P
world.music, world.noise: Disabled this code because it simply does not work (e.g. ignores bgmvolume, overlaps with "cd loop" controlled tracks).


Modified: branches/nexuiz-2.0/.patchsets
===================================================================
--- branches/nexuiz-2.0/.patchsets	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/.patchsets	2008-12-12 23:12:17 UTC (rev 5203)
@@ -1,2 +1,2 @@
 master = svn://svn.icculus.org/nexuiz/trunk
-revisions_applied = 1-5130
+revisions_applied = 1-5202

Modified: branches/nexuiz-2.0/Docs/eventlog.txt
===================================================================
--- branches/nexuiz-2.0/Docs/eventlog.txt	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/Docs/eventlog.txt	2008-12-12 23:12:17 UTC (rev 5203)
@@ -14,7 +14,7 @@
 log format:
 ______________
 
-   :logversion:2
+   :logversion:3
    :gamestart:<gametype>_<mapname>:<matchid>
    :gameinfo:mutators:LIST:mutator1:mutator2:...
 
@@ -93,15 +93,20 @@
          T = player is typing (console, menu or chat)
    
    and weapon IDs are:
-         1 = Shotgun
-         2 = Uzi
+         1 = Laser
+		 2 = Shotgun
+		 3 = Uzi
          4 = Mortar
-         8 = Electro
-        16 = Crylink
-        32 = Nex
-        64 = Hagar
-       128 = Rocket Launcher
-      4096 = Laser
+         5 = Electro
+         6 = Crylink
+         7 = Nex
+         8 = Hagar
+         9 = Rocket Launcher
+        10 = Port-O-Launch
+        11 = MinstaNex
+        12 = Grappling Hook
+        13 = Heavy Laser Assault Cannon
+        14 = T.A.G. Seeker
 
    runes/curses are stored as a bit mask with the following values:
          1 = Strength
@@ -116,7 +121,7 @@
     131072 = Empathy
 
 death type:
-   either a weapon ID (see above), or one of:
+   either a weapon ID ORed with weapon death flags, or one of:
      10000 = fallen to death
      10001 = telefragged
      10002 = drowned
@@ -130,6 +135,15 @@
      10010 = auto team change
      10011 = camping protection
 	 10012 = player became too fast (should never happen)
+	 10013 = health rot
+	 10014 = mirror damage
+	 10015 = g_touchexplode
+	 10100 = turret
 
+   weapon death flags are:
+       256 = secondary fire
+	   512 = splash damage
+	  1024 = bounced projectile
+
 There will be a log analyzer parsing this file format soon. Note that weapon
 IDs are below 10000.

Modified: branches/nexuiz-2.0/Docs/server/server.cfg
===================================================================
--- branches/nexuiz-2.0/Docs/server/server.cfg	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/Docs/server/server.cfg	2008-12-12 23:12:17 UTC (rev 5203)
@@ -32,8 +32,8 @@
 //g_keyhunt_point_limit -1     // frag/point limit for KH
 //g_lms_lives_override -1      // lives for LMS
 
-//g_ctf_win_mode 2             // CTF win mode: 0 = caps only, 1 = caps + points as tie breaker, 2 = points only
-//g_ctf_ignore_frags 0         // set to 1 to ignore kills except for FC kills
+//g_ctf_win_mode 0             // CTF win mode: 0 = caps only, 1 = caps + points as tie breaker, 2 = points only
+//g_ctf_ignore_frags 1         // set to 1 to ignore kills except for FC kills
 
 // TEAMS for key hunt (change this to 2, 3, 4 to set a fixed keyhunt style)
 //g_keyhunt_teams_override -1  // teams for KH

Modified: branches/nexuiz-2.0/data/ctfscoring-div0.cfg
===================================================================
--- branches/nexuiz-2.0/data/ctfscoring-div0.cfg	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/ctfscoring-div0.cfg	2008-12-12 23:12:17 UTC (rev 5203)
@@ -1,21 +1,22 @@
 // Scoring from the democratic poll at http://www.alientrap.org/forum/viewtopic.php?p=49529#49529
+// based on ctfscoring-z, but adjusted to be less harsh
 
 set g_ctf_flagscore_pickup_base                  -3
 set g_ctf_flagscore_pickup_dropped_early          2
 set g_ctf_flagscore_pickup_dropped_late           2
 set g_ctf_flagscore_capture                      28
-set g_ctf_flagscore_kill                          3
+set g_ctf_flagscore_kill                          2
 set g_ctf_flagpenalty_drop                        2
 set g_ctf_flagpenalty_suicidedrop                 2
 set g_ctf_flagpenalty_returned                    1
 set g_ctf_flagscore_return                        5
 set g_ctf_flagscore_return_rogue                 10
-set g_ctf_flagscore_return_by_killer              5
+set g_ctf_flagscore_return_by_killer              6
 set g_ctf_flagscore_return_rogue_by_killer       10
 
 // succeeded capture (pickup capture)            25 (0 for enemy)
 // failed capture (pickup kill drop return)      -6 (8 for enemy)
-// failed (shot into void) (pickup kill drop)    -4 (3 for enemy)
+// failed (shot into void) (pickup kill drop)    -5 (3 for enemy)
 // capture retry (kill drop pickup)               0 (3 for enemy)
 // suicide, then retake (suicidedrop pickup)      0 (0 for enemy)
 
@@ -23,11 +24,11 @@
 set g_ctf_personalscore_pickup_dropped_early          2
 set g_ctf_personalscore_pickup_dropped_late           2
 set g_ctf_personalscore_capture                      28
-set g_ctf_personalscore_kill                          3
+set g_ctf_personalscore_kill                          2
 set g_ctf_personalpenalty_drop                        2
 set g_ctf_personalpenalty_suicidedrop                 2
 set g_ctf_personalpenalty_returned                    1
 set g_ctf_personalscore_return                        5
 set g_ctf_personalscore_return_rogue                 10
-set g_ctf_personalscore_return_by_killer              5
+set g_ctf_personalscore_return_by_killer              6
 set g_ctf_personalscore_return_rogue_by_killer       10

Modified: branches/nexuiz-2.0/data/defaultNexuiz.cfg
===================================================================
--- branches/nexuiz-2.0/data/defaultNexuiz.cfg	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/defaultNexuiz.cfg	2008-12-12 23:12:17 UTC (rev 5203)
@@ -15,6 +15,9 @@
 // later, it's overridden by config.cfg, version ranges are defined in config_update.cfg
 seta g_configversion 0
 
+// default.cfg versioning (update using update-cvarcount.sh; run that every time after adding a new cvar)
+set cvar_check_default 3e222928f6156061e54639483d8961f0
+
 // Nexuiz version (formatted for machines)
 // used to determine if a client version is compatible
 // this doesn't have to be bumped with every release
@@ -332,7 +335,7 @@
 seta g_keyhunt_point_limit -1
 seta g_race_laps_limit -1
 
-seta g_ctf_win_mode 2 // 0: captures only, 1: captures, then points, 2: points only
+seta g_ctf_win_mode 0 // 0: captures only, 1: captures, then points, 2: points only
 seta g_ctf_ignore_frags 0 // 1: regular frags give no points
 
 // 50% of the spawns shall be far away from any players
@@ -399,7 +402,7 @@
 set g_ctf_shield_min_negscore 20 // shield the player from the flag if he's got -20 points or less
 set g_ctf_shield_force 100 // push force of the shield
                                                
-exec ctfscoring-nex242.cfg
+exec ctfscoring-div0.cfg
 
 // runematch
 set g_runematch						0
@@ -1221,3 +1224,11 @@
 set g_touchexplode_damage 10
 set g_touchexplode_edgedamage 0
 set g_touchexplode_force 150
+
+sbar_miniscoreboard_size 0 // this mode is broken in current csqc
+
+set g_ban_sync_uri "" // sync using this ban list provider (empty string to disable)
+set g_ban_sync_interval 5 // sync every 5 minutes
+set g_ban_sync_trusted_servers "" // request ban lists from these nexuiz servers (do not include your own server there, or unbanning may fail)
+
+alias records "cmd records"

Modified: branches/nexuiz-2.0/data/effectinfo.txt
===================================================================
--- branches/nexuiz-2.0/data/effectinfo.txt	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/effectinfo.txt	2008-12-12 23:12:17 UTC (rev 5203)
@@ -781,6 +781,7 @@
 velocityjitter 1000 1000 1500
 velocitymultiplier 0.5
 airfriction 2
+stretchfactor 0.6
 
 
 
@@ -3028,3 +3029,91 @@
 airfriction 12
 originjitter 1 1 1
 velocityjitter 50 50 50
+
+effect flac_explode
+countabsolute 1
+type decal
+tex 8 16
+size 18 28
+alpha 256 256 0
+originjitter 40 40 40
+lightradius 150
+lightradiusfade 400
+lightcolor 8 4 1
+// fire effect which make bright dot inside
+effect flac_explode
+notunderwater
+count 6
+type smoke
+tex 48 55
+color 0xffe955 0xff5a00
+size 6 16
+sizeincrease 5
+alpha 128 256 456
+bounce 1.5
+airfriction 8
+liquidfriction 8
+originjitter 8 8 8
+velocityjitter 156 156 156
+// fire effect which expands then slows
+effect flac_explode
+notunderwater
+count 12
+type static
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 10 16
+sizeincrease 15
+alpha 128 256 456
+bounce 1.5
+airfriction 12
+liquidfriction 8
+originjitter 8 8 8
+velocityjitter 256 256 256
+
+// smoke
+effect flac_explode
+type alphastatic
+notunderwater
+tex 0 8
+count 10
+size 10 20
+sizeincrease 20
+alpha 500 600 556
+velocityjitter 244 244 244
+airfriction 5
+color 0x000000 0x111111
+bounce 2
+
+// underwater bubbles
+effect flac_explode
+underwater
+count 16
+type bubble
+tex 62 62
+color 0x404040 0x808080
+size 1 2
+alpha 128 256 64
+gravity -0.125
+bounce 1.5
+liquidfriction 0.25
+originjitter 16 16 16
+velocityjitter 96 96 96
+// bouncing sparks
+effect flac_explode
+notunderwater
+count 8
+type spark
+color 0x903010 0xFFD030
+size 2 2
+tex 40 40
+alpha 256 256 384
+gravity 1
+airfriction 0.2
+bounce 1.5
+liquidfriction 0.8
+velocityoffset 0 0 80
+velocityjitter 256 256 256
+
+
+

Modified: branches/nexuiz-2.0/data/maps/basementctf.bsp
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/basementctf.map
===================================================================
--- branches/nexuiz-2.0/data/maps/basementctf.map	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/maps/basementctf.map	2008-12-12 23:12:17 UTC (rev 5203)
@@ -17038,7 +17038,6 @@
 // entity 57
 {
 "origin" "-2576 -656 280"
-"model" "models/ctf/flag_blue.md3"
 "classname" "item_flag_team2"
 }
 // entity 58
@@ -17086,7 +17085,6 @@
 // entity 65
 {
 "origin" "16 272 280"
-"model" "models/ctf/flag_red.md3"
 "classname" "item_flag_team1"
 }
 // entity 66

Copied: branches/nexuiz-2.0/data/maps/bloodprisonctf.ent (from rev 5202, trunk/data/maps/bloodprisonctf.ent)
===================================================================
--- branches/nexuiz-2.0/data/maps/bloodprisonctf.ent	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/bloodprisonctf.ent	2008-12-12 23:12:17 UTC (rev 5203)
@@ -0,0 +1,903 @@
+{
+"gridsize" "76.800003 76.800003 153.600006"
+"_keeplights" "1"
+"message" "Blood Prison CTF"
+"_lightmapscale" "0.25"
+"classname" "worldspawn"
+}
+{
+"origin" "3436.800049 2304.000000 259.200012"
+"classname" "item_armor25"
+}
+{
+"origin" "4147.200195 2764.800049 422.400024"
+"classname" "weapon_grenadelauncher"
+}
+{
+"origin" "5472.000000 1382.400024 -38.400002"
+"classname" "weapon_rocketlauncher"
+}
+{
+"targetname" "blueteleport"
+"angle" "0"
+"origin" "3801.600098 1920.000122 460.800018"
+"classname" "misc_teleporter_dest"
+}
+{
+"origin" "4838.400391 1152.000000 249.600006"
+"classname" "item_armor25"
+}
+{
+"origin" "3763.200195 921.600037 268.800018"
+"classname" "weapon_electro"
+}
+{
+"origin" "3801.600098 1689.600098 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "3801.600098 1632.000122 422.400024"
+"classname" "item_health1"
+}
+{
+"origin" "3801.600098 1574.400024 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "3801.600098 1516.800049 422.400024"
+"classname" "item_health1"
+}
+{
+"origin" "3801.600098 1459.200073 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "3801.600098 1401.600098 422.400024"
+"classname" "item_health1"
+}
+{
+"origin" "3801.600098 1286.400024 422.400024"
+"classname" "weapon_uzi"
+}
+{
+"angle" "180"
+"origin" "3974.400146 2649.600098 422.400024"
+"classname" "item_health25"
+}
+{
+"angle" "180"
+"origin" "3974.400146 2726.400146 422.400024"
+"classname" "item_health25"
+}
+{
+"angle" "90"
+"origin" "5030.400391 1728.000122 -38.400002"
+"classname" "item_rockets"
+}
+{
+"angle" "90"
+"origin" "5107.200195 1728.000122 -38.400002"
+"classname" "item_rockets"
+}
+{
+"angle" "90"
+"origin" "5184.000000 1728.000122 -38.400002"
+"classname" "item_cells"
+}
+{
+"angle" "360"
+"origin" "5472.000000 1632.000122 249.600006"
+"classname" "item_health25"
+}
+{
+"angle" "180"
+"origin" "5280.000000 1132.800049 249.600006"
+"classname" "item_health25"
+}
+{
+"origin" "4339.200195 1267.200073 249.600006"
+"classname" "weapon_hagar"
+}
+{
+"origin" "4377.600098 1920.000122 403.200012"
+"classname" "weapon_crylink"
+}
+{
+"angle" "180"
+"origin" "3763.200195 2457.600098 268.800018"
+"classname" "item_bullets"
+}
+{
+"angle" "180"
+"origin" "3763.200195 2400.000000 268.800018"
+"classname" "item_shells"
+}
+{
+"origin" "4771.200195 2601.600098 422.400024"
+"classname" "item_cells"
+}
+{
+"angle" "45"
+"origin" "4828.800293 2544.000000 422.400024"
+"classname" "item_rockets"
+}
+{
+"angle" "180"
+"origin" "4137.600098 1920.000122 19.200001"
+"classname" "item_health25"
+}
+{
+"angle" "270"
+"origin" "4588.800293 1632.000122 -57.600002"
+"classname" "item_health25"
+}
+{
+"angle" "180"
+"origin" "4531.200195 2131.200195 422.400024"
+"classname" "item_shells"
+}
+{
+"angle" "270"
+"origin" "3974.400146 979.200012 249.600006"
+"classname" "item_cells"
+}
+{
+"angle" "270"
+"origin" "3532.800049 979.200012 268.800018"
+"classname" "item_rockets"
+}
+{
+"origin" "4588.800293 2630.400146 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "4646.400391 2572.800049 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "4704.000000 2515.200195 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "4761.600098 2457.600098 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "4819.200195 2400.000000 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "5462.400391 1123.200073 268.800018"
+"angle" "90"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "4569.600098 2131.200195 422.400024"
+"angle" "270"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "3974.400146 2688.000000 432.000031"
+"angle" "0"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "3801.600098 1920.000122 441.600006"
+"angle" "270"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "3801.600098 1152.000000 268.800018"
+"angle" "270"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "4262.400391 1190.400024 259.200012"
+"angle" "45"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "4550.400391 1593.600098 -48.000000"
+"angle" "45"
+"classname" "info_player_deathmatch"
+}
+{
+"model" "*1"
+"target" "redjump"
+"classname" "trigger_push"
+}
+{
+"_color" "0.7 0.75 1"
+"light" "200"
+"origin" "4147.200195 2457.600098 595.200012"
+"classname" "light"
+}
+{
+"origin" "3801.600098 2352.000000 364.800018"
+"light" "100"
+"_color" "0.7 0.75 1"
+"classname" "light"
+}
+{
+"_color" "0.75 0.75 1.000000"
+"light" "50"
+"origin" "3571.200195 2275.200195 278.400024"
+"classname" "light"
+}
+{
+"origin" "3571.200195 1920.000122 153.600006"
+"light" "50"
+"_color" "1 1 0.9"
+"classname" "light"
+}
+{
+"origin" "4147.200195 1689.600098 336.000000"
+"light" "100"
+"_color" "0.7 0.75 1"
+"classname" "light"
+}
+{
+"_color" "0.75 0.75 1"
+"light" "50"
+"origin" "4147.200195 1920.000122 86.400002"
+"classname" "light"
+}
+{
+"origin" "4675.200195 1689.600098 28.800001"
+"light" "80"
+"_color" "0.75 0.75 1"
+"classname" "light"
+}
+{
+"_color" "0.75 0.75 1"
+"light" "50"
+"origin" "5107.200195 1651.200073 28.800001"
+"classname" "light"
+}
+{
+"origin" "5385.600098 1382.400024 9.600000"
+"light" "50"
+"_color" "0.75 0.75 1"
+"classname" "light"
+}
+{
+"origin" "5136.000000 1468.800049 528.000000"
+"light" "300"
+"_color" "0.75 0.75 1"
+"classname" "light"
+}
+{
+"_color" "0.7 0.75 1"
+"light" "100"
+"origin" "4368.000000 1296.000000 336.000000"
+"classname" "light"
+}
+{
+"origin" "4771.200195 1161.600098 336.000000"
+"light" "40"
+"_color" "0.7 0.75 1"
+"classname" "light"
+}
+{
+"origin" "4713.600098 2534.400146 480.000031"
+"light" "40"
+"_color" "0.7 0.75 1"
+"classname" "light"
+}
+{
+"_color" "0.7 0.75 1"
+"light" "40"
+"origin" "4492.800293 2649.600098 480.000031"
+"classname" "light"
+}
+{
+"origin" "4800.000000 2265.600098 480.000031"
+"light" "40"
+"_color" "0.7 0.75 1"
+"classname" "light"
+}
+{
+"_color" "0.7 0.75 1"
+"light" "80"
+"origin" "4147.200195 1920.000122 441.600006"
+"classname" "light"
+}
+{
+"_color" "1 1 0.9"
+"light" "50"
+"origin" "3571.200195 1708.800049 182.400009"
+"classname" "light"
+}
+{
+"origin" "3763.200195 1017.600037 364.800018"
+"light" "80"
+"_color" "0.7 0.75 1"
+"classname" "light"
+}
+{
+"origin" "4147.200195 2140.800049 384.000000"
+"light" "80"
+"_color" "0.7 0.75 1"
+"classname" "light"
+}
+{
+"_color" "0.7 0.75 1"
+"light" "80"
+"origin" "3561.600098 1036.800049 364.800018"
+"classname" "light"
+}
+{
+"origin" "3571.200195 1478.400024 259.200012"
+"light" "50"
+"_color" "0.7 0.75 1"
+"classname" "light"
+}
+{
+"origin" "5299.200195 1574.400024 28.800001"
+"light" "50"
+"_color" "0.75 0.75 1"
+"classname" "light"
+}
+{
+"_color" "0.7 0.75 1"
+"light" "150"
+"origin" "5001.600098 1737.600098 432.000031"
+"classname" "light"
+}
+{
+"origin" "4492.800293 1401.600098 393.600006"
+"light" "100"
+"_color" "0.7 0.75 1"
+"classname" "light"
+}
+{
+"_color" "0.75 0.75 1"
+"light" "35"
+"origin" "3801.600098 1920.000122 144.000000"
+"classname" "light"
+}
+{
+"origin" "4377.600098 1920.000122 441.600006"
+"light" "30"
+"_color" "0.7 0.75 1"
+"classname" "light"
+}
+{
+"origin" "2841.600098 2918.400146 268.800018"
+"classname" "weapon_electro"
+}
+{
+"origin" "2803.200195 2150.400146 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "2803.200195 2208.000000 422.400024"
+"classname" "item_health1"
+}
+{
+"origin" "2803.200195 2265.600098 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "2803.200195 2323.200195 422.400024"
+"classname" "item_health1"
+}
+{
+"origin" "2803.200195 2380.800049 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "2803.200195 2438.400146 422.400024"
+"classname" "item_health1"
+}
+{
+"origin" "2803.200195 2553.600098 422.400024"
+"classname" "weapon_uzi"
+}
+{
+"angle" "180"
+"origin" "2630.400146 1190.400024 422.400024"
+"classname" "item_health25"
+}
+{
+"angle" "180"
+"origin" "2630.400146 1113.600098 422.400024"
+"classname" "item_health25"
+}
+{
+"angle" "90"
+"origin" "1574.400024 2112.000000 -38.400002"
+"classname" "item_rockets"
+}
+{
+"angle" "90"
+"origin" "1497.600098 2112.000000 -38.400002"
+"classname" "item_rockets"
+}
+{
+"angle" "90"
+"origin" "1420.800049 2112.000000 -38.400002"
+"classname" "item_cells"
+}
+{
+"angle" "360"
+"origin" "1132.800049 2208.000000 249.600006"
+"classname" "item_health25"
+}
+{
+"angle" "180"
+"origin" "1324.800049 2707.200195 249.600006"
+"classname" "item_health25"
+}
+{
+"origin" "2265.600098 2572.800049 249.600006"
+"classname" "weapon_hagar"
+}
+{
+"origin" "2227.200195 1920.000122 403.200012"
+"classname" "weapon_crylink"
+}
+{
+"angle" "180"
+"origin" "2841.600098 1382.400024 268.800018"
+"classname" "item_bullets"
+}
+{
+"angle" "180"
+"origin" "2841.600098 1440.000000 268.800018"
+"classname" "item_shells"
+}
+{
+"origin" "1833.600098 1238.400024 422.400024"
+"classname" "item_cells"
+}
+{
+"angle" "45"
+"origin" "1776.000122 1296.000000 422.400024"
+"classname" "item_rockets"
+}
+{
+"angle" "180"
+"origin" "2457.600098 1920.000122 19.200001"
+"classname" "item_health25"
+}
+{
+"angle" "270"
+"origin" "2016.000122 2208.000000 -57.600002"
+"classname" "item_health25"
+}
+{
+"angle" "180"
+"origin" "2073.600098 1708.800049 422.400024"
+"classname" "item_shells"
+}
+{
+"angle" "270"
+"origin" "2630.400146 2860.800049 249.600006"
+"classname" "item_cells"
+}
+{
+"angle" "270"
+"origin" "3072.000000 2860.800049 268.800018"
+"classname" "item_rockets"
+}
+{
+"origin" "2016.000122 1209.600098 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "1958.400024 1267.200073 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "1900.800049 1324.800049 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "1843.200073 1382.400024 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "1785.600098 1440.000000 422.400024"
+"classname" "item_armor1"
+}
+{
+"origin" "3168.000244 1536.000000 259.200012"
+"classname" "item_armor25"
+}
+{
+"origin" "2457.600098 1075.200073 422.400024"
+"classname" "weapon_grenadelauncher"
+}
+{
+"origin" "1132.800049 2457.600098 -38.400002"
+"classname" "weapon_rocketlauncher"
+}
+{
+"targetname" "redteleport"
+"angle" "180"
+"origin" "2803.200195 1920.000122 460.800018"
+"classname" "misc_teleporter_dest"
+}
+{
+"origin" "1766.400024 2688.000000 249.600006"
+"classname" "item_armor25"
+}
+{
+"origin" "1142.400024 2716.800049 268.800018"
+"angle" "270"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "2035.200073 1708.800049 422.400024"
+"angle" "90"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "2630.400146 1152.000000 432.000031"
+"angle" "180"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "2803.200195 1920.000122 441.600006"
+"angle" "90"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "3571.200195 2227.200195 38.400002"
+"angle" "270"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "2342.400146 2649.600098 259.200012"
+"angle" "225"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "2054.400146 2246.400146 -48.000000"
+"angle" "225"
+"classname" "info_player_deathmatch"
+}
+{
+"_color" "1 0.75 0.75"
+"light" "200"
+"origin" "2457.600098 1382.400024 595.200012"
+"classname" "light"
+}
+{
+"origin" "2803.200195 1488.000000 364.800018"
+"light" "100"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"_color" "1 0.75 0.75"
+"light" "50"
+"origin" "3033.600098 1564.800049 278.400024"
+"classname" "light"
+}
+{
+"origin" "3033.600098 1920.000122 153.600006"
+"light" "50"
+"_color" "1 1 0.9"
+"classname" "light"
+}
+{
+"origin" "2457.600098 2150.400146 336.000000"
+"light" "100"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"_color" "1 0.75 0.75"
+"light" "50"
+"origin" "2457.600098 1920.000122 86.400002"
+"classname" "light"
+}
+{
+"origin" "1929.600098 2150.400146 28.800001"
+"light" "80"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"_color" "1 0.75 0.75"
+"light" "50"
+"origin" "1497.600098 2188.800049 28.800001"
+"classname" "light"
+}
+{
+"origin" "1219.200073 2457.600098 9.600000"
+"light" "50"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"origin" "1468.800049 2371.200195 528.000000"
+"light" "300"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"_color" "1 0.75 0.75"
+"light" "100"
+"origin" "2236.800049 2544.000000 336.000000"
+"classname" "light"
+}
+{
+"origin" "1833.600098 2678.400146 336.000000"
+"light" "40"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"origin" "1891.200073 1305.600098 480.000031"
+"light" "40"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"_color" "1 0.75 0.75"
+"light" "40"
+"origin" "2112.000000 1190.400024 480.000031"
+"classname" "light"
+}
+{
+"origin" "1804.800049 1574.400024 480.000031"
+"light" "40"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"_color" "1 0.75 0.75"
+"light" "80"
+"origin" "2457.600098 1920.000122 441.600006"
+"classname" "light"
+}
+{
+"_color" "1 1 0.9"
+"light" "50"
+"origin" "3033.600098 2131.200195 182.400009"
+"classname" "light"
+}
+{
+"origin" "2841.600098 2822.400146 364.800018"
+"light" "80"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"origin" "2457.600098 1699.200073 384.000000"
+"light" "80"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"_color" "1 0.75 0.75"
+"light" "80"
+"origin" "3043.200195 2803.200195 364.800018"
+"classname" "light"
+}
+{
+"origin" "3033.600098 2361.600098 259.200012"
+"light" "50"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"origin" "1305.600098 2265.600098 28.800001"
+"light" "50"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"_color" "1 0.75 0.75"
+"light" "150"
+"origin" "1603.200073 2102.400146 432.000031"
+"classname" "light"
+}
+{
+"origin" "2112.000000 2438.400146 393.600006"
+"light" "100"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"_color" "1 .75 .75"
+"light" "35"
+"origin" "3033.600098 1920.000122 451.200012"
+"classname" "light"
+}
+{
+"origin" "2227.200195 1920.000122 441.600006"
+"light" "30"
+"_color" "1 0.75 0.75"
+"classname" "light"
+}
+{
+"origin" "3302.400146 1920.000122 19.200001"
+"classname" "item_health100"
+}
+{
+"model" "*2"
+"target" "bluejump"
+"classname" "trigger_push"
+}
+{
+"origin" "1392.000000 2457.600098 374.400024"
+"targetname" "redjump"
+"classname" "target_position"
+}
+{
+"origin" "5232.000000 1382.400024 374.400024"
+"targetname" "bluejump"
+"classname" "target_position"
+}
+{
+"model" "*3"
+"target" "redteleport"
+"classname" "trigger_teleport"
+}
+{
+"model" "*4"
+"target" "blueteleport"
+"classname" "trigger_teleport"
+}
+{
+"origin" "5078.400391 1382.400024 -86.400002"
+"classname" "item_flag_team2"
+}
+{
+"origin" "1516.800049 2457.600098 -76.800003"
+"classname" "item_flag_team1"
+}
+{
+"origin" "1152.000000 2275.200195 259.200012"
+"classname" "info_player_team1"
+}
+{
+"origin" "1516.800049 2208.000000 -48.000000"
+"classname" "info_player_team1"
+}
+{
+"origin" "1161.600098 2611.200195 259.200012"
+"classname" "info_player_team1"
+}
+{
+"origin" "1171.200073 2323.200195 -48.000000"
+"classname" "info_player_team1"
+}
+{
+"origin" "1440.000000 2217.600098 259.200012"
+"classname" "info_player_team1"
+}
+{
+"origin" "1180.800049 2544.000000 -48.000000"
+"classname" "info_player_team1"
+}
+{
+"angle" "180"
+"origin" "5443.200195 1555.200073 259.200012"
+"classname" "info_player_team2"
+}
+{
+"angle" "180"
+"origin" "5078.400391 1622.400024 -48.000000"
+"classname" "info_player_team2"
+}
+{
+"angle" "180"
+"origin" "5433.600098 1219.200073 259.200012"
+"classname" "info_player_team2"
+}
+{
+"angle" "180"
+"origin" "5424.000000 1507.200073 -48.000000"
+"classname" "info_player_team2"
+}
+{
+"angle" "180"
+"origin" "5155.200195 1612.800049 259.200012"
+"classname" "info_player_team2"
+}
+{
+"angle" "180"
+"origin" "5414.400391 1286.400024 -48.000000"
+"classname" "info_player_team2"
+}
+{
+"_color" "1 0.75 0.75"
+"light" "35"
+"origin" "2803.200195 1920.000122 144.000000"
+"classname" "light"
+}
+{
+"origin" "2803.200195 2688.000000 268.800018"
+"angle" "90"
+"classname" "info_player_deathmatch"
+}
+{
+"origin" "3033.600098 1612.800049 38.400002"
+"angle" "90"
+"classname" "info_player_deathmatch"
+}
+{
+"_color" "1 1 1.000000"
+"light" "35"
+"origin" "3302.400146 1920.000122 451.200012"
+"classname" "light"
+}
+{
+"_color" "0.75 0.75 1"
+"light" "35"
+"origin" "3571.200195 1920.000122 451.200012"
+"classname" "light"
+}
+{
+"origin" "3379.200195 1536.000000 288.000000"
+"classname" "item_cells"
+}
+{
+"origin" "2966.400146 1920.000122 403.200012"
+"classname" "item_bullets"
+}
+{
+"origin" "3628.800049 1920.000122 403.200012"
+"classname" "item_bullets"
+}
+{
+"origin" "5280.000000 1372.800049 -57.600002"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "3801.600098 1814.400024 403.200012"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "3571.200195 1920.000122 9.600000"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "3801.600098 1008.000061 259.200012"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "4800.000000 2140.800049 403.200012"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "3897.600098 2294.400146 249.600006"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "4540.800293 1334.400024 249.600006"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "1324.800049 2467.200195 -57.600002"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "2803.200195 2025.600098 403.200012"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "3033.600098 1920.000122 9.600000"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "2803.200195 2832.000000 259.200012"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "2064.000000 2505.600098 249.600006"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "2707.200195 1545.600098 249.600006"
+"classname" "dom_controlpoint"
+}
+{
+"origin" "1804.800049 1699.200073 403.200012"
+"classname" "dom_controlpoint"
+}

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf.map
===================================================================
--- branches/nexuiz-2.0/data/maps/bloodprisonctf.map	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/maps/bloodprisonctf.map	2008-12-12 23:12:17 UTC (rev 5203)
@@ -26734,13 +26734,11 @@
 // entity 218
 {
 "classname" "item_flag_team2"
-"model" "models/ctf/flag_blue.md3"
 "origin" "4232 1152 -72"
 }
 // entity 219
 {
 "classname" "item_flag_team1"
-"model" "models/ctf/flag_red.md3"
 "origin" "1264 2048 -64"
 }
 // entity 220

Modified: branches/nexuiz-2.0/data/maps/dismal.ent
===================================================================
--- branches/nexuiz-2.0/data/maps/dismal.ent	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/maps/dismal.ent	2008-12-12 23:12:17 UTC (rev 5203)
@@ -317,12 +317,10 @@
 "origin" "-100 450 10"
 }
 {
-"model" "models/ctf/flag_red.md3"
 "origin" "3260 -670 8"
 "classname" "item_flag_team1"
 }
 {
-"model" "models/ctf/flag_blue.md3"
 "origin" "-520 -120 8"
 "classname" "item_flag_team2"
 }

Modified: branches/nexuiz-2.0/data/maps/runningmanctf.ent
===================================================================
--- branches/nexuiz-2.0/data/maps/runningmanctf.ent	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/maps/runningmanctf.ent	2008-12-12 23:12:17 UTC (rev 5203)
@@ -588,12 +588,10 @@
 "origin" "-632 1224 -240"
 }
 {
-"model" "models/ctf/flag_blue.md3"
 "origin" "784 768 320"
 "classname" "item_flag_team2"
 }
 {
-"model" "models/ctf/flag_red.md3"
 "origin" "-896 2448 312"
 "classname" "item_flag_team1"
 }

Modified: branches/nexuiz-2.0/data/maps/runningmanctf.map
===================================================================
--- branches/nexuiz-2.0/data/maps/runningmanctf.map	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/maps/runningmanctf.map	2008-12-12 23:12:17 UTC (rev 5203)
@@ -33747,13 +33747,11 @@
 // entity 348
 {
 "classname" "item_flag_team2"
-"model" "models/ctf/flag_blue.md3"
 "origin" "784 768 320"
 }
 // entity 349
 {
 "classname" "item_flag_team1"
-"model" "models/ctf/flag_red.md3"
 "origin" "-896 2448 312"
 }
 // entity 350

Modified: branches/nexuiz-2.0/data/maps/silvercity.ent
===================================================================
--- branches/nexuiz-2.0/data/maps/silvercity.ent	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/maps/silvercity.ent	2008-12-12 23:12:17 UTC (rev 5203)
@@ -606,12 +606,10 @@
 "origin" "1337 1190 216"
 }
 {
-"model" "models/ctf/flag_red.md3"
 "origin" "1440 -740 24"
 "classname" "item_flag_team1"
 }
 {
-"model" "models/ctf/flag_blue.md3"
 "origin" "-1590 1740 24"
 "classname" "item_flag_team2"
 }

Modified: branches/nexuiz-2.0/data/maps/starship.ent
===================================================================
--- branches/nexuiz-2.0/data/maps/starship.ent	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/maps/starship.ent	2008-12-12 23:12:17 UTC (rev 5203)
@@ -694,12 +694,10 @@
 "origin" "660 -280 -72"
 }
 {
-"model" "models/ctf/flag_red.md3"
 "origin" "1028 -1024 88"
 "classname" "item_flag_team1"
 }
 {
-"model" "models/ctf/flag_blue.md3"
 "origin" "-160 820 24"
 "classname" "item_flag_team2"
 "angle" "90"

Modified: branches/nexuiz-2.0/data/qcsrc/common/items.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/items.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/common/items.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -81,36 +81,18 @@
 }
 string W_FixWeaponOrder(string order, float complete)
 {
-	return fixPriorityList(order, WEP_FIRST, WEP_LAST, complete);
+	return fixPriorityList(order, WEP_FIRST, WEP_LAST, 230 - WEP_FIRST, complete);
 }
 
-// FTEQCC SUCKS // #ifdef SVQC
-// FTEQCC SUCKS // #define register_weapon(id,func,ammotype,i,normalweapon,canclimb,pickupbasevalue,modelname,shortname,wname) \
-// FTEQCC SUCKS // 	register_weapon_real(id,func,ammotype,i,normalweapon,canclimb,pickupbasevalue,modelname,shortname,wname)
-// FTEQCC SUCKS // #else
-// FTEQCC SUCKS // // no weapon funcs here!
-// FTEQCC SUCKS // #define register_weapon(id,func,ammotype,i,normalweapon,canclimb,pickupbasevalue,modelname,shortname,wname) \
-// FTEQCC SUCKS // 	register_weapon_real(id,w_null,ammotype,i,normalweapon,canclimb,pickupbasevalue,modelname,shortname,wname)
-// FTEQCC SUCKS // #endif
-// put this code back in if fteqcc gets fixed
+#ifdef SVQC
+#define register_weapon(id,func,ammotype,i,normalweapon,canclimb,pickupbasevalue,modelname,shortname,wname) \
+	register_weapon_real(id,func,ammotype,i,normalweapon,canclimb,pickupbasevalue,modelname,shortname,wname)
+#else
+// no weapon funcs here!
+#define register_weapon(id,func,ammotype,i,normalweapon,canclimb,pickupbasevalue,modelname,shortname,wname) \
+	register_weapon_real(id,w_null,ammotype,i,normalweapon,canclimb,pickupbasevalue,modelname,shortname,wname)
+#endif
 
-#define register_weapon register_weapon_real
-float(float) w_laser;
-float(float) w_shotgun;
-float(float) w_uzi;
-float(float) w_glauncher;
-float(float) w_electro;
-float(float) w_crylink;
-float(float) w_nex;
-float(float) w_hagar;
-float(float) w_rlauncher;
-float(float) w_porto;
-float(float) w_minstanex;
-float(float) w_hook;
-float(float) w_seeker;
-float(float) w_hlac;
-// I know this causes lots of warnings, but well, alternative code is above - use that code if fteqcc got fixed
-
 void RegisterWeapons()
 {
 	// %weaponaddpoint
@@ -123,7 +105,7 @@
 	register_weapon(WEP_NEX,              w_nex,       IT_CELLS,       7, 1, 0, 10000, "nex",       "nex",             "Nex");
 	register_weapon(WEP_HAGAR,            w_hagar,     IT_ROCKETS,     8, 1, 1,  5000, "hagar",     "hagar",           "Hagar");
 	register_weapon(WEP_ROCKET_LAUNCHER,  w_rlauncher, IT_ROCKETS,     9, 1, 1, 10000, "rl",        "rocketlauncher",  "Rocket Launcher");
-	register_weapon(WEP_PORTO,            w_porto,     IT_SUPERWEAPON, 0, 0, 0,     0, "porto" ,    "porto",           "Port-O-Launch");
+	register_weapon(WEP_PORTO,            w_porto,     0,              0, 0, 0,     0, "porto" ,    "porto",           "Port-O-Launch");
 	register_weapon(WEP_MINSTANEX,        w_minstanex, IT_CELLS,       7, 0, 1, 10000, "minstanex", "minstanex",       "MinstaNex");
 	register_weapon(WEP_HOOK,             w_hook,      IT_CELLS,       0, 0, 1,     0, "hookgun",   "hook",            "Grappling Hook");
 	register_weapon(WEP_SEEKER,           w_seeker,    IT_ROCKETS,     8, 1, 0,     0, "seeker",    "seeker",          "T.A.G. Seeker");

Modified: branches/nexuiz-2.0/data/qcsrc/common/util.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/util.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/common/util.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -641,7 +641,7 @@
 }
 #endif
 
-string fixPriorityList(string order, float from, float to, float complete)
+string fixPriorityList(string order, float from, float to, float subtract, float complete)
 {
 	string neworder;
 	float i, n, w;
@@ -650,8 +650,17 @@
 	for(i = 0; i < n; ++i)
 	{
 		w = stof(argv(i));
-		if(w >= from && w <= to && w == floor(w))
-			neworder = strcat(neworder, ftos(w), " ");
+		if(w == floor(w))
+		{
+			if(w >= from && w <= to)
+				neworder = strcat(neworder, ftos(w), " ");
+			else
+			{
+				w -= subtract;
+				if(w >= from && w <= to)
+					neworder = strcat(neworder, ftos(w), " ");
+			}
+		}
 	}
 
 	if(complete)

Modified: branches/nexuiz-2.0/data/qcsrc/common/util.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/util.qh	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/common/util.qh	2008-12-12 23:12:17 UTC (rev 5203)
@@ -74,7 +74,7 @@
 #define fixedvectoangles vectoangles
 #endif
 
-string fixPriorityList(string pl, float from, float to, float complete);
+string fixPriorityList(string pl, float from, float to, float subtract, float complete);
 string swapInPriorityList(string order, float i, float j);
 
 float cvar_value_issafe(string s);

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_settings_effects.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_settings_effects.c	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_settings_effects.c	2008-12-12 23:12:17 UTC (rev 5203)
@@ -126,9 +126,9 @@
 			setDependentOR(e, "r_shadow_realtime_dlight", 1, 1, "r_shadow_realtime_world", 1, 1);
 	me.TR(me);
 		me.TD(me, 1, 1.5, e = makeNexuizCheckBox(0, "r_glsl_deluxemapping", "Deluxe mapping"));
-			setDependent(e, "r_glsl", 1, 1);
+			setDependentAND(e, "r_glsl", 1, 1, "mod_q3bsp_nolightmaps", 0, 0);
 		me.TD(me, 1, 1.5, e = makeNexuizCheckBox(0, "r_shadow_gloss", "Gloss"));
-			setDependentAND(e, "r_glsl", 1, 1, "r_glsl_deluxemapping", 1, 1);
+			setDependentAND3(e, "r_glsl", 1, 1, "r_glsl_deluxemapping", 1, 1, "mod_q3bsp_nolightmaps", 0, 0);
 	
 	me.TR(me);
 	me.TR(me);

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -55,6 +55,9 @@
 .string cvar2_setDependent;
 .float cvar2Min_setDependent;
 .float cvar2Max_setDependent;
+.string cvar3_setDependent;
+.float cvar3Min_setDependent;
+.float cvar3Max_setDependent;
 .float op_setDependent;
 .string cvarString_setDependent;
 .string cvarValue_setDependent;
@@ -85,6 +88,14 @@
 			else
 				e.disabled = (e.disabled + ((f >= e.cvar2Max_setDependent) && (f <= e.cvar2Min_setDependent)) > e.op_setDependent);
 		}
+		if(e.cvar3_setDependent)
+		{
+			f = cvar(e.cvar3_setDependent);
+			if(e.cvar3Min_setDependent <= e.cvar3Max_setDependent)
+				e.disabled = (e.disabled + ((f < e.cvar3Min_setDependent) || (f > e.cvar3Max_setDependent)) > e.op_setDependent);
+			else
+				e.disabled = (e.disabled + ((f >= e.cvar3Max_setDependent) && (f <= e.cvar3Min_setDependent)) > e.op_setDependent);
+		}
 	}
 }
 void setDependent_Draw(entity e)
@@ -99,6 +110,7 @@
 	e.cvarMin_setDependent = theCvarMin;
 	e.cvarMax_setDependent = theCvarMax;
 	e.cvar2_setDependent = string_null;
+	e.cvar3_setDependent = string_null;
 	e.draw = setDependent_Draw;
 	setDependent_Check(e);
 }
@@ -109,6 +121,7 @@
 	e.cvarValue_setDependent = theCvarValue;
 	e.cvar_setDependent = string_null;
 	e.cvar2_setDependent = string_null;
+	e.cvar3_setDependent = string_null;
 	e.draw = setDependent_Draw;
 	setDependent_Check(e);
 }
@@ -121,6 +134,7 @@
 	e.cvar2_setDependent = theCvar2Name;
 	e.cvar2Min_setDependent = theCvar2Min;
 	e.cvar2Max_setDependent = theCvar2Max;
+	e.cvar3_setDependent = string_null;
 	e.op_setDependent = 0;
 	e.draw = setDependent_Draw;
 	setDependent_Check(e);
@@ -134,10 +148,27 @@
 	e.cvar2_setDependent = theCvar2Name;
 	e.cvar2Min_setDependent = theCvar2Min;
 	e.cvar2Max_setDependent = theCvar2Max;
+	e.cvar3_setDependent = string_null;
 	e.op_setDependent = 1;
 	e.draw = setDependent_Draw;
 	setDependent_Check(e);
 }
+void setDependentAND3(entity e, string theCvarName, float theCvarMin, float theCvarMax, string theCvar2Name, float theCvar2Min, float theCvar2Max, string theCvar3Name, float theCvar3Min, float theCvar3Max)
+{
+	e.draw_setDependent = e.draw;
+	e.cvar_setDependent = theCvarName;
+	e.cvarMin_setDependent = theCvarMin;
+	e.cvarMax_setDependent = theCvarMax;
+	e.cvar2_setDependent = theCvar2Name;
+	e.cvar2Min_setDependent = theCvar2Min;
+	e.cvar2Max_setDependent = theCvar2Max;
+	e.cvar3_setDependent = theCvar3Name;
+	e.cvar3Min_setDependent = theCvar3Min;
+	e.cvar3Max_setDependent = theCvar3Max;
+	e.op_setDependent = 0;
+	e.draw = setDependent_Draw;
+	setDependent_Check(e);
+}
 
 // EXTRESPONSE SYSTEM ////////////////////////////////////////////////////////
 

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qh	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qh	2008-12-12 23:12:17 UTC (rev 5203)
@@ -7,4 +7,5 @@
 void setDependent(entity e, string theCvarName, float theCvarMin, float theCvarMax);
 void setDependentAND(entity e, string theCvarName, float theCvarMin, float theCvarMax, string theCvar2Name, float theCvar2Min, float theCvar2Max);
 void setDependentOR(entity e, string theCvarName, float theCvarMin, float theCvarMax, string theCvar2Name, float theCvar2Min, float theCvar2Max);
+void setDependentAND3(entity e, string theCvarName, float theCvarMin, float theCvarMax, string theCvar2Name, float theCvar2Min, float theCvar2Max, string theCvar3Name, float theCvar3Min, float theCvar3Max);
 void setDependentStringNotEqual(entity e, string theCvarName, string theCvarValue);

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/weaponslist.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/weaponslist.c	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/weaponslist.c	2008-12-12 23:12:17 UTC (rev 5203)
@@ -34,7 +34,7 @@
 	// read in cvar?
 	string s, t;
 	s = cvar_string("cl_weaponpriority");
-	t = fixPriorityList(s, WEP_FIRST, WEP_LAST, 1);
+	t = W_FixWeaponOrder(s, 1);
 	if(t != s)
 	{
 		print("AUTOFIXED\n");

Modified: branches/nexuiz-2.0/data/qcsrc/server/arena.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/arena.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/arena.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -73,7 +73,7 @@
 		}
 		else if(self.flags & FL_ITEM)			// reset items
 		{
-			if(self.cnt == 1)
+			if(self.state == 1)
 			{
 				self.model = string_null;
 				self.solid = SOLID_NOT;

Modified: branches/nexuiz-2.0/data/qcsrc/server/assault.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/assault.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/assault.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -35,8 +35,8 @@
 
 	// activate objective
 	self.health = 100;
-	print("^2Activated objective ", self.targetname, "=", etos(self), "\n");
-	print("Activator is ", activator.classname, "\n");
+	//print("^2Activated objective ", self.targetname, "=", etos(self), "\n");
+	//print("Activator is ", activator.classname, "\n");
 
 	entity oldself;
 	oldself = self;
@@ -199,7 +199,7 @@
 
 
 void target_assault_roundend_reset() {
-	print("round end reset\n");
+	//print("round end reset\n");
 	self.cnt = self.cnt + 1; // up round counter
 	self.winning = 0; // up round
 }
@@ -258,7 +258,7 @@
 // trigger new round
 // reset objectives, toggle spawnpoints, reset triggers, ...
 void assault_new_round() {
-	bprint("ASSAULT: new round\n");
+	//bprint("ASSAULT: new round\n");
 
 	// up round counter
 	self.winning = self.winning + 1;

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -1335,7 +1335,7 @@
 
 	// Here, everything has been done that requires this player to be a client.
 
-	self.flags (-) FL_CLIENT;
+	self.flags &~= FL_CLIENT;
 
 	if (self.chatbubbleentity)
 		remove (self.chatbubbleentity);

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -289,7 +289,7 @@
 		else
 		{
 			// now set angles_x so that the car points forward, but is tilted in velocity direction
-			self.flags (-) FL_ONGROUND;
+			self.flags &~= FL_ONGROUND;
 		}
 
 		self.velocity = (neworigin - self.origin) * (1.0 / frametime);

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -316,7 +316,12 @@
 		if(wb)
 			weapon_action(self.weapon, WR_THINK);
 		if (time + frametime * 0.5 >= self.weapon_nextthink)
-			self.weapon_think();
+		{
+			if(self.weapon_think)
+				self.weapon_think();
+			else
+				bprint("\{1}^1ERROR: undefined weapon think function for ", self.netname, "\n");
+		}
 	}
 
 	// don't let attack_finished fall behind when not firing (must be after weapon_setup calls!)

Modified: branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -224,7 +224,7 @@
 float readyrestart_happened;
 void SV_ParseClientCommand(string s) {
 	local string cmd;
-	local float i, j, tokens, f, effectnum;
+	local float tokens, f, effectnum;
 	local vector start, end;
 
 	tokens = tokenize_sane(s);
@@ -345,39 +345,11 @@
 			}
 		}
 	} else if(argv(0) == "maplist") {
-		local float n;
-		local string col;
-		n = tokenize_sane(cvar_string("g_maplist"));
-		sprint(self, "^7Maps in list: ");
-		for(i = 0, j = 0; i < n; ++i)
-		{
-			if(MapInfo_CheckMap(argv(i)))
-			{
-				if(mod(j, 2))
-					col = "^2";
-				else
-					col = "^3";
-				sprint(self, strcat(col, argv(i), " "));
-				++j;
-			}
-		}
-		sprint(self, "\n");
+		sprint(self, maplist_reply);
 	} else if(argv(0) == "lsmaps") {
-		sprint(self, "^7Maps available: ");
-		for(i = 0, j = 0; i < MapInfo_count; ++i)
-		{
-			if(MapInfo_Get_ByID(i))
-			if not(MapInfo_Map_flags & MAPINFO_FLAG_HIDDEN)
-			{
-				if(mod(i, 2))
-					col = "^2";
-				else
-					col = "^3";
-				++j;
-				sprint(self, strcat(col, MapInfo_Map_bspname, " "));
-			}
-		}
-		sprint(self, "\n");
+		sprint(self, lsmaps_reply);
+	} else if(argv(0) == "records") {
+		sprint(self, records_reply);
 	} else if(argv(0) == "voice") {
 		VoiceMessage(argv(1));
 	} else if(argv(0) == "say") {

Modified: branches/nexuiz-2.0/data/qcsrc/server/constants.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/constants.qh	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/constants.qh	2008-12-12 23:12:17 UTC (rev 5203)
@@ -1,3 +1,5 @@
+string CVAR_CHECK_DEFAULT = "3e222928f6156061e54639483d8961f0";
+string CVAR_CHECK_WEAPONS = "bf8a055d6b6b090133b248bccf916024";
 
 float	FALSE					= 0;
 float	TRUE					= 1;

Modified: branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -424,6 +424,8 @@
 				bprint(other.netname, "^7 captured the ", other.flagcarried.netname, " in ", s, ", failing to break ", strcat(h0, " record of ", s0, " seconds\n"));
 			}
 		}
+		else
+			bprint(other.netname, "^7 captured the ", other.flagcarried.netname, "\n");
 
 		PlayerTeamScore_Add(other, SP_CTF_CAPS, ST_CTF_CAPS, 1);
 		LogCTF("capture", other.flagcarried.team, other);
@@ -919,11 +921,11 @@
 
 void ctf_setstatus()
 {
-	self.items (-) IT_RED_FLAG_TAKEN;
-	self.items (-) IT_RED_FLAG_LOST;
-	self.items (-) IT_BLUE_FLAG_TAKEN;
-	self.items (-) IT_BLUE_FLAG_LOST;
-	self.items (-) IT_CTF_SHIELDED;
+	self.items &~= IT_RED_FLAG_TAKEN;
+	self.items &~= IT_RED_FLAG_LOST;
+	self.items &~= IT_BLUE_FLAG_TAKEN;
+	self.items &~= IT_BLUE_FLAG_LOST;
+	self.items &~= IT_CTF_SHIELDED;
 
 	if (g_ctf) {
 		local entity flag;

Modified: branches/nexuiz-2.0/data/qcsrc/server/defs.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2008-12-12 23:12:17 UTC (rev 5203)
@@ -16,6 +16,8 @@
 
 // Globals
 
+string records_reply, lsmaps_reply, maplist_reply; // cached replies
+
 float ctf_score_value(string parameter);
 
 float g_dm, g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught, g_assault, g_arena, g_lms, g_runematch, g_race;
@@ -28,6 +30,8 @@
 float g_ctf_reverse;
 float g_race_qualifying;
 float inWarmupStage;
+float g_pickup_respawntime_weapon;
+float g_pickup_respawntime_ammo;
 float g_pickup_respawntime_short;
 float g_pickup_respawntime_medium;
 float g_pickup_respawntime_long;

Modified: branches/nexuiz-2.0/data/qcsrc/server/extensions.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/extensions.qh	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/extensions.qh	2008-12-12 23:12:17 UTC (rev 5203)
@@ -912,12 +912,15 @@
 //idea: div0
 //darkplaces implementation: div0
 //loads text from an URL into a string
+//returns 1 on success of initiation, 0 if there are too many concurrent
+//connections already or if the URL is invalid
 //the following callback will receive the data and MUST exist!
 //  void(float id, float status, string data) URI_Get_Callback;
 //status is either
 //  negative for an internal error,
 //  0 for success, or
 //  the HTTP response code on server error (e.g. 404)
+//if 1 is returned by uri_get, the callback will be called in the future
 float(string url, float id) uri_get = #513;
 
 //DP_SV_SPAWNFUNC_PREFIX

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -520,7 +520,7 @@
 					RemoveGrapplingHook(targ); // STOP THAT, you parasite!
 
 	// special rule: gravity bomb does not hit team mates (other than for disconnecting the hook)
-	if(DEATH_WEAPONOF(deathtype) == WEP_HOOK)
+	if(DEATH_ISWEAPON(deathtype, WEP_HOOK))
 	{
 		if(targ.classname == "player")
 			if not(IsDifferentTeam(targ, attacker))

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -232,7 +232,7 @@
 					}
 				}
 
-				self.owner.flags (-) FL_ONGROUND;
+				self.owner.flags &~= FL_ONGROUND;
 			}
 		}
 		else
@@ -248,7 +248,7 @@
 			self.owner.velocity = dir*spd;
 			self.owner.movetype = MOVETYPE_FLY;
 
-			self.owner.flags (-) FL_ONGROUND;
+			self.owner.flags &~= FL_ONGROUND;
 		}
 	}
 
@@ -392,25 +392,25 @@
 		else
 		{
 			self.hook_state |= HOOK_REMOVING;
-			self.hook_state (-) HOOK_WAITING_FOR_RELEASE;
+			self.hook_state &~= HOOK_WAITING_FOR_RELEASE;
 		}
 
-		self.hook_state (-) HOOK_RELEASING;
+		self.hook_state &~= HOOK_RELEASING;
 		if(self.BUTTON_CROUCH)
 		{
-			self.hook_state (-) HOOK_PULLING;
+			self.hook_state &~= HOOK_PULLING;
 			//self.hook_state |= HOOK_RELEASING;
 		}
 		else
 		{
 			self.hook_state |= HOOK_PULLING;
-			//self.hook_state (-) HOOK_RELEASING;
+			//self.hook_state &~= HOOK_RELEASING;
 		}
 	}
 
 	if(!g_grappling_hook && self.weapon != WEP_HOOK)
 	{
-		self.hook_state (-) HOOK_FIRING;
+		self.hook_state &~= HOOK_FIRING;
 		self.hook_state |= HOOK_REMOVING;
 	}
 
@@ -419,13 +419,13 @@
 		if (self.hook)
 			RemoveGrapplingHook(self);
 		FireGrapplingHook();
-		self.hook_state (-) HOOK_FIRING;
+		self.hook_state &~= HOOK_FIRING;
 	}
 	else if(self.hook_state & HOOK_REMOVING)
 	{
 		if (self.hook)
 			RemoveGrapplingHook(self);
-		self.hook_state (-) HOOK_REMOVING;
+		self.hook_state &~= HOOK_REMOVING;
 	}
 	/*
 	// if I have no hook or it's not pulling yet, make sure I'm not flying!

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_triggers.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_triggers.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_triggers.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -96,7 +96,7 @@
 			for(t = world; (t = find(t, targetname, s)); )
 			if(t.use)
 			{
-				print(stemp.classname, " ", stemp.targetname, " -> ", t.classname, " ", t.targetname, "\n");
+				//print(stemp.classname, " ", stemp.targetname, " -> ", t.classname, " ", t.targetname, "\n");
 				self = t;
 				other = stemp;
 				activator = act;
@@ -926,7 +926,12 @@
 		if(self.mdl == "none")
 			self.cnt = -1;
 		else
+		{
 			self.cnt = particleeffectnum(self.mdl);
+			if(self.cnt < 0)
+				if(self.dmg)
+					self.cnt = particleeffectnum("laser_deadly");
+		}
 	}
 	else if(!self.cnt)
 	{
@@ -935,6 +940,8 @@
 		else
 			self.cnt = -1;
 	}
+	if(self.cnt < 0)
+		self.cnt = -1;
 
 	if(self.colormod == '0 0 0')
 		if(!self.alpha)

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -194,13 +194,43 @@
 	cvar_changes = strzone(cvar_changes);
 }
 
+void detect_maptype()
+{
+	vector o, v;
+	float i;
+
+	for(;;)
+	{
+		o = world.mins;
+		o_x += random() * (world.maxs_x - world.mins_x);
+		o_y += random() * (world.maxs_y - world.mins_y);
+		o_z += random() * (world.maxs_z - world.mins_z);
+
+		tracebox(o, PL_MIN, PL_MAX, o - '0 0 32768', MOVE_WORLDONLY, world);
+		if(trace_fraction == 1)
+			continue;
+		
+		v = trace_endpos;
+
+		for(i = 0; i < 64; i += 4)
+		{
+			tracebox(o, '-1 -1 -1' * i, '1 1 1' * i, o - '0 0 32768', MOVE_WORLDONLY, world);
+	if(trace_fraction == 1)
+		continue;
+			print(ftos(i), " -> ", vtos(trace_endpos), "\n");
+		}
+
+		break;
+	}
+}
+
 float world_already_spawned;
 void RegisterWeapons();
 void Nagger_Init();
 void spawnfunc_worldspawn (void)
 {
-	float fd, l;
-	string s;
+	float fd, l, i, j, n;
+	string s, col;
 
 	dprint_load(); // load dprint status from cvar
 
@@ -210,6 +240,12 @@
 
 	remove = remove_safely; // during spawning, watch what you remove!
 
+	if(cvar_string("cvar_check_default") != CVAR_CHECK_DEFAULT)
+		error("Config file mismatch! Please update defaultNexuiz.cfg to match the QuakeC code!");
+
+	if(cvar_string("cvar_check_weapons") != CVAR_CHECK_WEAPONS)
+		error("Config file mismatch! Please update weapons.cfg and weaponsPro.cfg to match the QuakeC code!");
+
 	compressShortVector_init();
 
 	local entity head;
@@ -406,6 +442,42 @@
 	next_pingtime = time + 5;
 	InitializeEntity(self, cvar_changes_init, INITPRIO_CVARS);
 
+	detect_maptype();
+
+	lsmaps_reply = "^7Maps available: ";
+	for(i = 0, j = 0; i < MapInfo_count; ++i)
+	{
+		if(MapInfo_Get_ByID(i))
+			if not(MapInfo_Map_flags & MAPINFO_FLAG_HIDDEN)
+			{
+				if(mod(i, 2))
+					col = "^2";
+				else
+					col = "^3";
+				++j;
+				lsmaps_reply = strcat(lsmaps_reply, col, MapInfo_Map_bspname, " ");
+			}
+	}
+	lsmaps_reply = strzone(strcat(lsmaps_reply, "\n"));
+
+	maplist_reply = "^7Maps in list: ";
+	n = tokenize_sane(cvar_string("g_maplist"));
+	for(i = 0, j = 0; i < n; ++i)
+	{
+		if(MapInfo_CheckMap(argv(i)))
+		{
+			if(mod(j, 2))
+				col = "^2";
+			else
+				col = "^3";
+			maplist_reply = strcat(maplist_reply, col, argv(i), " ");
+			++j;
+		}
+	}
+	maplist_reply = strzone(strcat(maplist_reply, "\n"));
+
+	records_reply = strzone(getrecords());
+
 	world_initialized = 1;
 }
 
@@ -1377,14 +1449,6 @@
 	return WINNING_NO;
 }
 
-void print_to(entity e, string s)
-{
-	if(e)
-		sprint(e, strcat(s, "\n"));
-	else
-		print(s, "\n");
-}
-
 void ShuffleMaplist()
 {
 	string result;
@@ -1420,6 +1484,7 @@
 	cvar_set("g_maplist", result);
 }
 
+float leaderfrags;
 float WinningCondition_Scores(float limit)
 {
 	// TODO make everything use THIS winning condition (except LMS)
@@ -1445,6 +1510,22 @@
 		limit = -limit;
 	}
 
+	if(g_dm || (g_ctf && g_ctf_win_mode != 2) || g_tdm || g_arena || (g_race && !g_race_qualifying))
+	// these modes always score in increments of 1, thus this makes sense
+	{
+		if(leaderfrags != WinningConditionHelper_topscore)
+		{
+			leaderfrags = WinningConditionHelper_topscore;
+
+			if (leaderfrags == limit - 1)
+				play2all("announcer/robotic/1fragleft.wav");
+			else if (leaderfrags == limit - 2)
+				play2all("announcer/robotic/2fragsleft.wav");
+			else if (leaderfrags == limit - 3)
+				play2all("announcer/robotic/3fragsleft.wav");
+		}
+	}
+
 	return GetWinningCode(limit && WinningConditionHelper_topscore && (WinningConditionHelper_topscore >= limit), WinningConditionHelper_equality);
 }
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -473,6 +473,8 @@
 		print("  effectindexdump\n");
 		print("  radarmap [--force] [--quit | --loop] [sharpness]\n");
 		print("  bbox\n");
+		print("  cvar_changes\n");
+		print("  find classname\n");
 		GameCommand_Vote("help", world);
 		GameCommand_Ban("help");
 		GameCommand_Generic("help");
@@ -671,6 +673,19 @@
 		print(cvar_changes);
 		return;
 	}
+	if (argv(0) == "find") if(argc == 2)
+	{
+		for(client = world; (client = find(client, classname, argv(1))); )
+			print(etos(client), "\n");
+		return;
+	}
+	if (argv(0) == "records")
+	{
+		strunzone(records_reply);
+		records_reply = strzone(getrecords());
+		print(records_reply);
+		return;
+	}
 
 	print("Invalid command. For a list of supported commands, try sv_cmd help.\n");
 }

Modified: branches/nexuiz-2.0/data/qcsrc/server/ipban.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ipban.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/ipban.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -1,3 +1,177 @@
+/*
+ * Protocol of online ban list:
+ *
+ * - Reporting a ban:
+ *     GET g_ban_sync_uri?action=ban&ip=xxx.xxx.xxx&duration=nnnn&why=...................
+ *     (IP 1, 2, 3, or 4 octets, 3 octets for example is a /24 mask)
+ * - Removing a ban:
+ *     GET g_ban_sync_uri?action=unban&ip=xxx.xxx.xxx
+ * - Querying the ban list
+ *     GET g_ban_sync_uri?action=list&servers=xxx.xxx.xxx.xxx:xxx.xxx.xxx.xxx:...
+ *     
+ *     shows the bans from the listed servers, and possibly others.
+ *     Format of a ban is ASCII plain text, four lines per ban, delimited by
+ *     newline ONLY (no carriage return):
+ *
+ *     IP address (also 1, 2, 3, or 4 octets, delimited by dot)
+ *     time left in seconds
+ *     reason of the ban
+ *     server IP that registered the ban
+ */
+
+float Ban_Insert(string ip, float bantime, string reason, float dosync);
+
+void OnlineBanList_SendBan(string ip, float bantime, string reason)
+{
+	string uri;
+	float i, n;
+
+	uri = strcat(     "?action=ban&ip=", uri_escape(ip));
+	uri = strcat(uri, "&duration=", ftos(bantime));
+	uri = strcat(uri, "&why=", uri_escape(reason));
+
+	n = tokenize_sane(cvar_string("g_ban_sync_uri"));
+	for(i = 0; i < n; ++i)
+		uri_get(strcat(argv(i), uri), 0); // 0 = "discard" callback target
+}
+
+void OnlineBanList_SendUnban(string ip)
+{
+	string uri;
+	float i, n;
+
+	uri = strcat(     "?action=unban&ip=", uri_escape(ip));
+
+	n = tokenize_sane(cvar_string("g_ban_sync_uri"));
+	for(i = 0; i < n; ++i)
+		uri_get(strcat(argv(i), uri), 0); // 0 = "discard" callback target
+}
+
+string OnlineBanList_Servers;
+float OnlineBanList_Timeout;
+float OnlineBanList_Requests;
+
+void OnlineBanList_URI_Get_Callback(float status, string data)
+{
+	float n, i, j, l;
+	string ip;
+	float timeleft;
+	string reason;
+	string serverip;
+	float syncinterval;
+
+	if(OnlineBanList_Requests <= 0)
+		return;
+
+	--OnlineBanList_Requests;
+
+	if(time > OnlineBanList_Timeout)
+		return;
+
+	syncinterval = cvar("g_ban_sync_interval");
+	if(syncinterval == 0)
+		return;
+	if(syncinterval > 0)
+		syncinterval *= 60;
+
+	if(status != 0)
+	{
+		print("Error receiving the online ban list: Status is ", ftos(status), "\n");
+		return;
+	}
+
+	if(substring(data, 0, 1) == "<")
+	{
+		print("Error receiving the online ban list: Received HTML instead of a ban list: ");
+		return;
+	}
+
+	if(strstrofs(data, "\r", 0) != -1)
+	{
+		print("Error receiving the online ban list: Received carriage returns: ");
+		return;
+	}
+
+	n = tokenizebyseparator(data, "\n");
+	if(mod(n, 4) != 0)
+	{
+		print("Error receiving the online ban list: Received invalid item count: ");
+		return;
+	}
+
+	for(i = 0; i < n; i += 4)
+	{
+		ip = argv(i);
+		timeleft = stof(argv(i + 1));
+		reason = argv(i + 2);
+		serverip = argv(i + 3);
+
+		timeleft -= 15;
+		if(timeleft < 0)
+			continue;
+
+		l = strlen(ip);
+		for(j = 0; j < l; ++j)
+			if(strstrofs("0123456789.", substring(ip, j, 1), 0) == -1)
+			{
+				print("Invalid character ", substring(ip, j, 1), " in IP address ", ip, ". Skipping this ban.\n");
+				goto skip;
+			}
+
+		if(strstrofs(strcat(":", OnlineBanList_Servers, ":"), strcat(":", serverip, ":"), 0) != -1)
+		{
+			if(syncinterval > 0)
+				timeleft = min(syncinterval + 15, timeleft);
+				// 15 seconds for safety
+				// the ban will be prolonged on the next sync
+			Ban_Insert(ip, timeleft, strcat("ban synced from ", serverip), 0);
+			print("Ban list syncing: accepted ban of ", ip, " by ", serverip, ": ", reason, "\n");
+		}
+
+		continue;
+:skip
+	}
+}
+
+void OnlineBanList_Think()
+{
+	float argc;
+	string uri;
+	float i, n;
+	
+	if(cvar_string("g_ban_sync_uri") == "")
+		return;
+	if(cvar("g_ban_sync_interval") == 0) // < 0 is okay, it means "sync on level start only"
+		return;
+	argc = tokenize_sane(cvar_string("g_ban_sync_trusted_servers"));
+	if(argc == 0)
+		return;
+
+	if(OnlineBanList_Requests == 0) // only if there is no ongoing request!
+	{
+		if(OnlineBanList_Servers)
+			strunzone(OnlineBanList_Servers);
+		OnlineBanList_Servers = argv(0);
+		for(i = 1; i < argc; ++i)
+			OnlineBanList_Servers = strcat(OnlineBanList_Servers, ":", argv(i));
+		OnlineBanList_Servers = strzone(OnlineBanList_Servers);
+		
+		uri = strcat(     "?action=list&servers=", uri_escape(OnlineBanList_Servers));
+
+		OnlineBanList_Timeout = time + 10;
+
+		n = tokenize_sane(cvar_string("g_ban_sync_uri"));
+		for(i = 0; i < n; ++i)
+		{
+			++OnlineBanList_Requests;
+			uri_get(strcat(argv(i), uri), 1); // 1 = "banlist" callback target
+		}
+	}
+	
+	if(cvar("g_ban_sync_interval") > 0)
+		self.nextthink = time + max(60, cvar("g_ban_sync_interval") * 60);
+}
+
 #define BAN_MAX 64
 float ban_loaded;
 string ban_ip[BAN_MAX];
@@ -41,7 +215,10 @@
 	if(ban_expire[i] == 0)
 		return FALSE;
 	if(ban_expire[i] > 0)
+	{
+		OnlineBanList_SendUnban(ban_ip[i]);
 		strunzone(ban_ip[i]);
+	}
 	ban_expire[i] = 0;
 	ban_ip[i] = "";
 	Ban_SaveBans();
@@ -65,6 +242,12 @@
 			ban_expire[i] = time + stof(argv(2*i+2));
 		}
 	}
+
+	entity e;
+	e = spawn();
+	e.classname = "bansyncer";
+	e.think = OnlineBanList_Think;
+	e.nextthink = time + 1;
 }
 
 void Ban_View()
@@ -95,15 +278,25 @@
 	return TRUE;
 }
 
-float Ban_IsClientBanned(entity client)
+float Ban_IsClientBanned(entity client, float idx)
 {
-	float i;
+	float i, b, e;
 	if(!ban_loaded)
 		Ban_LoadBans();
 	if(!Ban_GetClientIP(client))
 		return FALSE;
-	for(i = 0; i < ban_count; ++i)
+	if(idx < 0)
 	{
+		b = 0;
+		e = ban_count;
+	}
+	else
+	{
+		b = idx;
+		e = idx + 1;
+	}
+	for(i = b; i < e; ++i)
+	{
 		string s;
 		if(time > ban_expire[i])
 			continue;
@@ -118,7 +311,7 @@
 
 float Ban_MaybeEnforceBan(entity client)
 {
-	if(Ban_IsClientBanned(client))
+	if(Ban_IsClientBanned(client, -1))
 	{
 		string s;
 		s = strcat("^1NOTE:^7 banned client ", client.netaddress, " just tried to enter\n");
@@ -129,15 +322,32 @@
 	return FALSE;
 }
 
-float Ban_Insert(string ip, float bantime)
+float Ban_Insert(string ip, float bantime, string reason, float dosync)
 {
 	float i;
 	float j;
 	float bestscore;
+	entity e;
+	string s;
+
+	if(dosync)
+		if(reason != "")
+			if(substring(reason, 0, 1) != "~") // like IRC: unauthenticated banner
+				OnlineBanList_SendBan(ip, bantime, reason);
+
 	// already banned?
 	for(i = 0; i < ban_count; ++i)
 		if(ban_ip[i] == ip)
+		{
+			// prolong the ban
+			if(time + bantime > ban_expire[i])
+			{
+				ban_expire[i] = time + bantime;
+				print(ip, "'s ban has been prolonged to ", ftos(bantime), " seconds from now\n");
+			}
+			// and abort
 			return FALSE;
+		}
 	// do we have a free slot?
 	for(i = 0; i < ban_count; ++i)
 		if(time > ban_expire[i])
@@ -169,13 +379,24 @@
 
 	Ban_SaveBans();
 
+	// Enforce our new ban
+	s = "";
+	FOR_EACH_REALCLIENT(e)
+		if(Ban_IsClientBanned(e, i))
+		{
+			s = strcat(s, "^1NOTE:^7 banned client ", e.netname, "^7 has to go\n");
+			dropclient(e);
+		}
+	bprint(s);
+
 	return TRUE;
 }
 
-void Ban_KickBanClient(entity client, float bantime, float masksize)
+void Ban_KickBanClient(entity client, float bantime, float masksize, string reason)
 {
 	if(!Ban_GetClientIP(client))
 	{
+		sprint(client, strcat("Kickbanned: ", reason, "\n"));
 		dropclient(client);
 		return;
 	}
@@ -183,19 +404,20 @@
 	switch(masksize)
 	{
 		case 1:
-			Ban_Insert(ban_ip1, bantime);
+			Ban_Insert(ban_ip1, bantime, reason, 1);
 			break;
 		case 2:
-			Ban_Insert(ban_ip2, bantime);
+			Ban_Insert(ban_ip2, bantime, reason, 1);
 			break;
 		case 3:
-			Ban_Insert(ban_ip3, bantime);
+			Ban_Insert(ban_ip3, bantime, reason, 1);
 			break;
 		default:
-			Ban_Insert(ban_ip4, bantime);
+			Ban_Insert(ban_ip4, bantime, reason, 1);
 			break;
 	}
 	// and kick him
+	sprint(client, strcat("Kickbanned: ", reason, "\n"));
 	dropclient(client);
 }
 
@@ -206,6 +428,7 @@
 	entity client;
 	float entno;
 	float masksize;
+	string reason;
 
 	argc = tokenize_sane(command);
 	if(argv(0) == "help")
@@ -232,7 +455,11 @@
 				masksize = stof(argv(4));
 			else
 				masksize = cvar("g_ban_default_masksize");
-			Ban_KickBanClient(client, bantime, masksize);
+			if(argc >= 6)
+				reason = substring(command, argv_start_index(5), strlen(command) - argv_start_index(5));
+			else
+				reason = "";
+			Ban_KickBanClient(client, bantime, masksize, reason);
 			return TRUE;
 		}
 	}
@@ -246,7 +473,11 @@
 				bantime = stof(argv(2));
 			else
 				bantime = cvar("g_ban_default_bantime");
-			Ban_Insert(ip, bantime);
+			if(argc >= 4)
+				reason = substring(command, argv_start_index(3), strlen(command) - argv_start_index(3));
+			else
+				reason = "";
+			Ban_Insert(ip, bantime, reason, 1);
 			return TRUE;
 		}
 	}

Modified: branches/nexuiz-2.0/data/qcsrc/server/ipban.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ipban.qh	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/ipban.qh	2008-12-12 23:12:17 UTC (rev 5203)
@@ -1,5 +1,6 @@
 void Ban_SaveBans();
 void Ban_LoadBans();
-float Ban_IsClientBanned(entity client);
 float Ban_MaybeEnforceBan(entity client);
 float GameCommand_Ban(string command);
+
+void OnlineBanList_URI_Get_Callback(float status, string data);

Modified: branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -162,7 +162,7 @@
 				fn = strcat(substring("00000000", 0, 8 - strlen(fn)), fn);
 			fn = strcat(cvar_string("sv_eventlog_files_nameprefix"), fn, cvar_string("sv_eventlog_files_namesuffix"));
 			logfile = fopen(fn, FILE_APPEND);
-			fputs(logfile, ":logversion:2\n");
+			fputs(logfile, ":logversion:3\n");
 		}
 		if(logfile >= 0)
 		{
@@ -911,8 +911,8 @@
 
 	if(g_grappling_hook) // offhand hook
 	{
-		start_weapons (-) WEPBIT_HOOK;
-		warmup_start_weapons (-) WEPBIT_HOOK;
+		start_weapons &~= WEPBIT_HOOK;
+		warmup_start_weapons &~= WEPBIT_HOOK;
 	}
 }
 
@@ -992,6 +992,8 @@
 	if(g_race && g_race_qualifying == 2 || g_arena || g_assault || cvar("g_campaign"))
 		inWarmupStage = 0; // these modes cannot work together, sorry
 
+	g_pickup_respawntime_weapon = cvar("g_pickup_respawntime_weapon");
+	g_pickup_respawntime_ammo = cvar("g_pickup_respawntime_ammo");
 	g_pickup_respawntime_short = cvar("g_pickup_respawntime_short");
 	g_pickup_respawntime_medium = cvar("g_pickup_respawntime_medium");
 	g_pickup_respawntime_long = cvar("g_pickup_respawntime_long");
@@ -1331,6 +1333,9 @@
 		}
 	}
 
+#if 0
+	// Disabled this code because it simply does not work (e.g. ignores bgmvolume, overlaps with "cd loop" controlled tracks).
+
 	if (!self.noise && self.music) // quake 3 uses the music field
 		self.noise = self.music;
 
@@ -1340,6 +1345,7 @@
 		precache_sound (self.noise);
 		ambientsound ('0 0 0', self.noise, VOL_BASE, ATTN_NONE);
 	}
+#endif
 }
 
 // sorry, but using \ in macros breaks line numbers
@@ -1656,3 +1662,82 @@
 #define PROJECTILE_TOUCH do { if(SUB_OwnerCheck()) return; if(SUB_NoImpactCheck()) { remove(self); return; } } while(0)
 const string STR_MISC_NULL_WAV = "misc/null.wav";
 #define PROJECTILE_TOUCH_NOSOUND do { if(SUB_OwnerCheck()) return; if(SUB_NoImpactCheck()) { sound (self, CHAN_PROJECTILE, STR_MISC_NULL_WAV, VOL_BASE, ATTN_NORM); remove(self); return; } } while(0)
+
+void URI_Get_Callback(float id, float status, string data)
+{
+	dprint("Received HTTP request data for id ", ftos(id), "; status is ", ftos(status), "\nData is\n:");
+	dprint(data);
+	dprint("\nEnd of data.\n");
+
+	switch(id)
+	{
+		case 0:
+			// 0 is the ID for discarding
+			break;
+		case 1:
+			// 1 is the ID for online ban list
+			OnlineBanList_URI_Get_Callback(status, data);
+			break;
+		default:
+			print("Received HTTP request data for an invalid id ", ftos(id), ".\n");
+			break;
+	}
+}
+
+void print_to(entity e, string s)
+{
+	if(e)
+		sprint(e, strcat(s, "\n"));
+	else
+		print(s, "\n");
+}
+
+string getrecords()
+{
+	float rec;
+	string h;
+	float r;
+	float i;
+	string s;
+
+	rec = 0;
+	
+	s = "";
+
+	if(g_ctf)
+	{
+		for(i = 0; i < MapInfo_count; ++i)
+		{
+			if(MapInfo_Get_ByID(i))
+			{
+				r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/captimerecord/time")));
+				if(r == 0)
+					continue;
+				h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/captimerecord/netname"));
+				s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-6, ftos_decimals(r, 2)), " ", h, "\n");
+				++rec;
+			}
+		}
+	}
+
+	if(g_race)
+	{
+		for(i = 0; i < MapInfo_count; ++i)
+		{
+			if(MapInfo_Get_ByID(i))
+			{
+				r = stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/racerecord/time")));
+				if(r == 0)
+					continue;
+				h = db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, "/racerecord/netname"));
+				s = strcat(s, strpad(32, MapInfo_Map_bspname), " ", strpad(-8, mmsss(r)), " ", h, "\n");
+				++rec;
+			}
+		}
+	}
+
+	if(s == "")
+		return "No records are available on this server.\n";
+	else
+		return strcat("Records on this server:\n", s);
+}

Modified: branches/nexuiz-2.0/data/qcsrc/server/t_items.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_items.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_items.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -248,7 +248,7 @@
 		{
 			RandomSelection_Init();
 			for(head = world; (head = findfloat(head, team, self.team)); ) if(head.flags & FL_ITEM)
-				RandomSelection_Add(head, 0, 1, 0);
+				RandomSelection_Add(head, 0, head.cnt, 0);
 			e = RandomSelection_chosen_ent;
 		}
 		else
@@ -268,9 +268,9 @@
 		dprint("Initializing item team ", ftos(self.team), "\n");
 		RandomSelection_Init();
 		for(head = world; (head = findfloat(head, team, self.team)); ) if(head.flags & FL_ITEM)
-			RandomSelection_Add(head, 0, 1, 0);
+			RandomSelection_Add(head, 0, head.cnt, 0);
 		e = RandomSelection_chosen_ent;
-		e.cnt = 0;
+		e.state = 0;
 
 		for(head = world; (head = findfloat(head, team, self.team)); ) if(head.flags & FL_ITEM)
 		{
@@ -279,7 +279,7 @@
 				// make it a non-spawned item
 				head.solid = SOLID_NOT;
 				head.model = string_null;
-				head.cnt = 1; // cnt 1 = initially hidden item
+				head.state = 1; // state 1 = initially hidden item
 			}
 			head.effects = head.effects - (head.effects & EF_NODRAW);
 		}
@@ -288,7 +288,7 @@
 
 // Savage: used for item garbage-collection
 // TODO: perhaps nice special effect?
-void RemoveItem(void) /*FIXDECL*/
+void RemoveItem(void)
 {
 	remove(self);
 }
@@ -506,8 +506,11 @@
 	if (cvar("g_fullbrightitems"))
 		self.effects = self.effects | EF_FULLBRIGHT;
 
+	self.state = 0;
 	if(self.team)
 	{
+		if(!self.cnt)
+			self.cnt = 1; // item probability weight
 		self.effects = self.effects | EF_NODRAW; // marker for item team search
 		InitializeEntity(self, Item_FindTeam, INITPRIO_FINDTARGET);
 	}
@@ -607,7 +610,7 @@
 		if(e.items == IT_SUPERWEAPON)
 			self.respawntime = g_pickup_respawntime_powerup;
 		else
-			self.respawntime = g_pickup_respawntime_short;
+			self.respawntime = g_pickup_respawntime_weapon;
 	}
 
 	if(self.classname != "droppedweapon" && self.classname != "replacedweapon")
@@ -747,7 +750,7 @@
 void spawnfunc_item_rockets (void) {
 	if(!self.ammo_rockets)
 		self.ammo_rockets = g_pickup_rockets;
-	StartItem ("models/items/a_rockets.md3", "misc/itempickup.wav", g_pickup_respawntime_short, "rockets", IT_ROCKETS, 0, 0, commodity_pickupevalfunc, 3000);
+	StartItem ("models/items/a_rockets.md3", "misc/itempickup.wav", g_pickup_respawntime_ammo, "rockets", IT_ROCKETS, 0, 0, commodity_pickupevalfunc, 3000);
 }
 
 void spawnfunc_item_shells (void);
@@ -764,13 +767,13 @@
 
 	if(!self.ammo_nails)
 		self.ammo_nails = g_pickup_nails;
-	StartItem ("models/items/a_bullets.mdl", "misc/itempickup.wav", g_pickup_respawntime_short, "bullets", IT_NAILS, 0, 0, commodity_pickupevalfunc, 2000);
+	StartItem ("models/items/a_bullets.mdl", "misc/itempickup.wav", g_pickup_respawntime_ammo, "bullets", IT_NAILS, 0, 0, commodity_pickupevalfunc, 2000);
 }
 
 void spawnfunc_item_cells (void) {
 	if(!self.ammo_cells)
 		self.ammo_cells = g_pickup_cells;
-	StartItem ("models/items/a_cells.md3", "misc/itempickup.wav", g_pickup_respawntime_short, "cells", IT_CELLS, 0, 0, commodity_pickupevalfunc, 2000);
+	StartItem ("models/items/a_cells.md3", "misc/itempickup.wav", g_pickup_respawntime_ammo, "cells", IT_CELLS, 0, 0, commodity_pickupevalfunc, 2000);
 }
 
 void spawnfunc_item_shells (void) {
@@ -786,7 +789,7 @@
 
 	if(!self.ammo_shells)
 		self.ammo_shells = g_pickup_shells;
-	StartItem ("models/items/a_shells.md3", "misc/itempickup.wav", g_pickup_respawntime_short, "shells", IT_SHELLS, 0, 0, commodity_pickupevalfunc, 500);
+	StartItem ("models/items/a_shells.md3", "misc/itempickup.wav", g_pickup_respawntime_ammo, "shells", IT_SHELLS, 0, 0, commodity_pickupevalfunc, 500);
 }
 
 void spawnfunc_item_armor_small (void) {

Modified: branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -887,6 +887,16 @@
 	if (self.spawnflags & 4)
 	{
 		self.owner = self.enemy = self;
+
+		if (self.health)
+			return;
+		IFTARGETED
+			return;
+		if (self.items)
+			return;
+
+		self.trigger_field = spawn_field(self.mins, self.maxs);
+
 		return;		// don't want to link this door
 	}
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/t_teleporters.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_teleporters.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_teleporters.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -10,12 +10,16 @@
 	else
 		telefragger = player;
 
-	sound (player, CHAN_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTN_NORM);
-	pointparticles(particleeffectnum("teleport"), player.origin, '0 0 0', 1);
-
 	makevectors (to_angles);
-	pointparticles(particleeffectnum("teleport"), to + v_forward * 32, '0 0 0', 1);
 
+	if(self.pushltime < time) // only show one teleport effect per teleporter per 0.2 seconds, for better fps
+	{
+		sound (player, CHAN_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTN_NORM);
+		pointparticles(particleeffectnum("teleport"), player.origin, '0 0 0', 1);
+		pointparticles(particleeffectnum("teleport"), to + v_forward * 32, '0 0 0', 1);
+		self.pushltime = time + 0.2;
+	}
+
 	// Relocate the player
 	// assuming to allows PL_MIN to PL_MAX box and some more
 	setorigin (player, to);

Modified: branches/nexuiz-2.0/data/qcsrc/server/vote.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/vote.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/vote.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -15,8 +15,9 @@
 {
 	float tokens;
 	float n, t;
-	string ns;
+	string ns, s;
 	entity e;
+	string reason;
 
 	tokens = tokenize_sane(vote);
 	ns = "";
@@ -42,6 +43,20 @@
 		else
 			GetKickVoteVictim_reason = "";
 
+		if(cmd != "vdo" || GetKickVoteVictim_reason == "")
+			reason = "~"; // by convention, ~ prefixes a "unverified" kickban which will not be networked
+		else
+			reason = "";
+		if(caller)
+			reason = strcat(reason, "player ", strdecolorize(caller.netname));
+		else
+			reason = strcat(reason, "console vote");
+		if(GetKickVoteVictim_reason != "")
+			reason = strcat(reason, ": ", strdecolorize(GetKickVoteVictim_reason));
+
+		if not(cvar_value_issafe(reason))
+			reason = uri_escape(reason);
+
 		n = stof(ns);
 		if(ns == ftos(n)) if(n >= 1) if(n <= maxclients)
 		{
@@ -49,6 +64,14 @@
 			if(clienttype(e) == CLIENTTYPE_REAL)
 			{
 				GetKickVoteVictim_newcommand = strcat(argv(0), " # ", ns);
+				if(argv(0) == "kickban")
+				{
+					GetKickVoteVictim_newcommand = strcat(GetKickVoteVictim_newcommand, " ", cvar_string("g_ban_default_bantime"), " ", cvar_string("g_ban_default_masksize"), " ", reason);
+				}
+				else if(argv(0) == "kick")
+				{
+					GetKickVoteVictim_newcommand = strcat(GetKickVoteVictim_newcommand, " ", reason);
+				}
 				return e;
 			}
 		}

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_hook.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_hook.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_hook.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -1,3 +1,30 @@
+.float dmg;
+.float dmg_edge;
+.float dmg_radius;
+.float dmg_force;
+.float dmg_power;
+.float dmg_duration;
+.float dmg_last;
+
+void W_Hook_ExplodeThink (void)
+{
+	float dt, dmg_remaining, dmg_remaining_next, f;
+
+	dt = time - self.teleport_time;
+	dmg_remaining_next = pow(bound(0, 1 - dt / self.dmg_duration, 1), self.dmg_power);
+
+	f = self.dmg_last - dmg_remaining_next;
+	self.dmg_last = dmg_remaining_next;
+
+	RadiusDamage (self, self.owner, self.dmg * f, self.dmg_edge * f, self.dmg_radius, self.owner, self.dmg_force * f, self.projectiledeathtype, world);
+	//RadiusDamage (self, world, self.dmg * f, self.dmg_edge * f, self.dmg_radius, world, self.dmg_force * f, self.projectiledeathtype, world);
+
+	if(dt < self.dmg_duration)
+		self.nextthink = time + 0.05; // soon
+	else
+		remove(self);
+}
+
 void W_Hook_Explode2 (void)
 {
 	vector org2;
@@ -7,9 +34,19 @@
 	sound (self, CHAN_PROJECTILE, "weapons/hookbomb_impact.wav", VOL_BASE, ATTN_NORM);
 
 	self.event_damage = SUB_Null;
-	RadiusDamage (self, self.owner, cvar("g_balance_hook_secondary_damage"), cvar("g_balance_hook_secondary_edgedamage"), cvar("g_balance_hook_secondary_radius"), self.owner, cvar("g_balance_hook_secondary_force"), self.projectiledeathtype, other);
+	self.touch = SUB_Null;
 
-	remove(self);
+	self.think = W_Hook_ExplodeThink;
+	self.nextthink = time;
+	self.dmg = cvar("g_balance_hook_secondary_damage");
+	self.dmg_edge = cvar("g_balance_hook_secondary_edgedamage");
+	self.dmg_radius = cvar("g_balance_hook_secondary_radius");
+	self.dmg_force = cvar("g_balance_hook_secondary_force");
+	self.dmg_power = cvar("g_balance_hook_secondary_power");
+	self.dmg_duration = cvar("g_balance_hook_secondary_duration");
+	self.teleport_time = time;
+	self.dmg_last = 1;
+	self.movetype = MOVETYPE_NONE;
 }
 
 void W_Hook_Touch2 (void)
@@ -44,7 +81,11 @@
 	gren.think = adaptor_think2use;
 	gren.use = W_Hook_Explode2;
 	gren.touch = W_Hook_Touch2;
+
 	gren.velocity = '0 0 1' * cvar("g_balance_hook_secondary_speed");
+	if(cvar("g_projectiles_newton_style"))
+		gren.velocity = gren.velocity + self.velocity;
+
 	gren.gravity = cvar("g_balance_hook_secondary_gravity");
 	//W_SetupProjectileVelocity(gren); // just falling down!
 
@@ -95,16 +136,16 @@
 
 		if (self.BUTTON_CROUCH)
 		{
-			self.hook_state (-) HOOK_PULLING;
+			self.hook_state &~= HOOK_PULLING;
 			if (self.BUTTON_ATCK || self.BUTTON_HOOK)
-				self.hook_state (-) HOOK_RELEASING;
+				self.hook_state &~= HOOK_RELEASING;
 			else
 				self.hook_state |= HOOK_RELEASING;
 		}
 		else
 		{
 			self.hook_state |= HOOK_PULLING;
-			self.hook_state (-) HOOK_RELEASING;
+			self.hook_state &~= HOOK_RELEASING;
 
 			if (self.BUTTON_ATCK || self.BUTTON_HOOK)
 			{
@@ -115,7 +156,7 @@
 			else
 			{
 				self.hook_state |= HOOK_REMOVING;
-				self.hook_state (-) HOOK_WAITING_FOR_RELEASE;
+				self.hook_state &~= HOOK_WAITING_FOR_RELEASE;
 			}
 		}
 	}

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_seeker.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_seeker.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_seeker.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -7,7 +7,7 @@
 	vector	org2;
 	float b;
 	org2 = findbetterlocation (self.origin, 12);
-	te_explosion (org2);
+	pointparticles(particleeffectnum("hagar_explode"), org2, '0 0 0', 1);
 
 	b = crandom();
 	if (b<-0.7)
@@ -276,7 +276,7 @@
 	//    return;
 
 	org2 = findbetterlocation (self.origin, 12);
-	te_explosion (org2);
+	pointparticles(particleeffectnum("hagar_explode"), org2, '0 0 0', 1);
 
 	b = crandom();
 	if (b<-0.7)
@@ -378,7 +378,7 @@
 	vector	org2;
 	float b;
 	org2 = findbetterlocation (self.origin, 12);
-	te_explosion (org2);
+	pointparticles(particleeffectnum("flac_explode"), org2, '0 0 0', 1);
 
 	b = crandom();
 	if (b<-0.7)

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc	2008-12-12 23:12:17 UTC (rev 5203)
@@ -89,7 +89,6 @@
 			w_ready();
 			return;
 		}
-		ATTACK_FINISHED(self) = time + cvar("g_balance_uzi_refire");
 		self.uzi_bulletcounter = self.uzi_bulletcounter + 1;
 		W_Uzi_Attack(WEP_UZI);
 		weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), uzi_fire1_02);

Modified: branches/nexuiz-2.0/data/scripts/common.shader
===================================================================
--- branches/nexuiz-2.0/data/scripts/common.shader	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/scripts/common.shader	2008-12-12 23:12:17 UTC (rev 5203)
@@ -28,6 +28,14 @@
 	surfaceparm nomarks
 }
 
+textures/common/forcecaulk
+{
+	surfaceparm nodraw
+	surfaceparm nolightmap
+	surfaceparm nomarks
+	surfaceparm structural
+}
+
 textures/common/clip
 {
 	qer_trans 0.40

Modified: branches/nexuiz-2.0/data/scripts/entities.def
===================================================================
--- branches/nexuiz-2.0/data/scripts/entities.def	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/scripts/entities.def	2008-12-12 23:12:17 UTC (rev 5203)
@@ -280,6 +280,7 @@
 armorvalue: amount of armor it gives (default: 100 (g_pickup_armorlarge))
 max_armorvalue: max of armor it increases to (default: 999 (g_pickup_armorlarge_max))
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -293,6 +294,7 @@
 armorvalue: amount of armor it gives (default: 25 (g_pickup_armormedium))
 max_armorvalue: max of armor it increases to (default: 999 (g_pickup_armormedium_max))
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -306,6 +308,7 @@
 armorvalue: amount of armor it gives (default: 5 (g_pickup_armorsmall))
 max_armorvalue: max of armor it increases to (default: 999 (g_pickup_armorsmall_max))
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -318,6 +321,7 @@
 ammo_nails: bullets gained by this item (if unset, g_pickup_nails is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -330,6 +334,7 @@
 ammo_cells: cells gained by this item (if unset, g_pickup_cells is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -365,6 +370,7 @@
 health: amount of health it gives (default: 50 (g_pickup_healthlarge))
 max_health: max of health it increases to (default: 999 (g_pickup_healthlarge_max))
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -378,6 +384,7 @@
 health: amount of health it gives (default: 25 (g_pickup_healthmedium))
 max_health: max of health it increases to (default: 999 (g_pickup_healthmedium_max))
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -392,6 +399,7 @@
 health: amount of health it gives (default: 100 (g_pickup_healthmega))
 max_health: max of health it increases to (default: 999 (g_pickup_healthmega_max))
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -405,6 +413,7 @@
 health: amount of health it gives (default: 5 (g_pickup_healthsmall))
 max_health: max of health it increases to (default: 5 (g_pickup_healthsmall_max))
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -417,6 +426,7 @@
 -------- KEYS --------
 respawntime: time till it respawns (default: 120)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -430,6 +440,7 @@
 -------- KEYS --------
 respawntime: time till it respawns (default: 45)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -442,6 +453,7 @@
 ammo_rockets: rockets gained by this item (if unset, g_pickup_rockets is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -454,6 +466,7 @@
 ammo_shells: shells gained by this item (if unset, g_pickup_shells is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -466,6 +479,7 @@
 -------- KEYS --------
 respawntime: time till it respawns (default: 120)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -872,6 +886,7 @@
 ammo_cells: initial cells of the weapon (if unset, g_pickup_cells is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -884,6 +899,7 @@
 ammo_cells: initial cells of the weapon (if unset, g_pickup_cells is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -896,6 +912,7 @@
 ammo_rockets: initial rockets of the weapon (if unset, g_pickup_rockets is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -908,6 +925,7 @@
 ammo_rockets: initial rockets of the weapon (if unset, g_pickup_rockets is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -921,6 +939,7 @@
 ammo_cells: initial cells of the weapon (if unset, g_pickup_cells is used)
 respawntime: time till it respawns (default: 15 * g_balance_nex_respawntime_modifier)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -934,6 +953,7 @@
 ammo_rockets: initial rockets of the weapon (if unset, g_pickup_rockets is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -946,6 +966,7 @@
 ammo_shells: initial shells of the weapon (if unset, g_pickup_shells is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -958,6 +979,7 @@
 ammo_nails: initial bullets of the weapon (if unset, g_pickup_nails is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -1076,6 +1098,7 @@
 ammo_cells: initial cells of the weapon (if unset, g_pickup_cells is used)
 respawntime: time till it respawns (default: 15)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -1088,6 +1111,7 @@
 -------- KEYS --------
 respawntime: time till it respawns (default: 120)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -1194,6 +1218,7 @@
 -------- KEYS --------
 respawntime: time till it respawns (default: 30)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
@@ -1205,12 +1230,25 @@
 -------- KEYS --------
 respawntime: time till it respawns (default: 30)
 team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
 -------- SPAWNFLAGS --------
 FLOATING: the item will float in air, instead of aligning to the floor by falling
 -------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
 model="models/weapons/g_seeker.md3"
 */
 
+/*QUAKED weapon_hook (1 0 .5) (-30 -30 0) (30 30 32) FLOATING
+the on-hand Grappling Hook.
+-------- KEYS --------
+respawntime: time till it respawns (default: 30)
+team: out of items with the same value here, only one (random one) will spawn. Useful to put multiple items on one spot.
+cnt: weight of this item for random selection using "team". Set to a lower value for items you want to see less likely.
+-------- SPAWNFLAGS --------
+FLOATING: the item will float in air, instead of aligning to the floor by falling
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/weapons/g_hookgun.md3"
+*/
+
 /*QUAKED trigger_heal (.5 .5 .5) ?
 Any object touching this will be healed.
 -------- KEYS --------

Copied: branches/nexuiz-2.0/data/update-cvarcount.sh (from rev 5202, trunk/data/update-cvarcount.sh)
===================================================================
--- branches/nexuiz-2.0/data/update-cvarcount.sh	                        (rev 0)
+++ branches/nexuiz-2.0/data/update-cvarcount.sh	2008-12-12 23:12:17 UTC (rev 5203)
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+countd=`awk '/^seta? g_/ { print $2; }' defaultNexuiz.cfg | sort -u | md5sum | cut -c 1-32`
+countw=`awk '/^seta? g_/ { print $2; }' weapons.cfg       | sort -u | md5sum | cut -c 1-32`
+countp=`awk '/^seta? g_/ { print $2; }' weaponsPro.cfg    | sort -u | md5sum | cut -c 1-32`
+
+if [ "$countw" != "$countp" ]; then
+	echo "Mismatch between weapons.cfg and weaponsPro.cfg. Aborting."
+	exit 1
+fi
+
+sed -i "s/^set cvar_check_default .*/set cvar_check_default $countd/" defaultNexuiz.cfg
+sed -i "s/^set cvar_check_weapons .*/set cvar_check_weapons $countw/" weapons.cfg
+sed -i "s/^set cvar_check_weapons .*/set cvar_check_weapons $countw/" weaponsPro.cfg
+
+sed -i "s/^string CVAR_CHECK_DEFAULT = .*/string CVAR_CHECK_DEFAULT = \"$countd\";/" qcsrc/server/constants.qh
+sed -i "s/^string CVAR_CHECK_WEAPONS = .*/string CVAR_CHECK_WEAPONS = \"$countw\";/" qcsrc/server/constants.qh
+
+make
+
+echo "New checksums: $countd, $countw"

Modified: branches/nexuiz-2.0/data/weapons.cfg
===================================================================
--- branches/nexuiz-2.0/data/weapons.cfg	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/weapons.cfg	2008-12-12 23:12:17 UTC (rev 5203)
@@ -1,334 +1,345 @@
-set g_start_weapon_laser 1
-set g_start_weapon_shotgun 1
-set g_start_weapon_uzi 0
-set g_start_weapon_grenadelauncher 0
-set g_start_weapon_electro 0
-set g_start_weapon_crylink 0
-set g_start_weapon_nex 0
-set g_start_weapon_hagar 0
-set g_start_weapon_rocketlauncher 0
-set g_start_weapon_minstanex 0
-set g_start_weapon_porto 0
-set g_start_weapon_hook 0
-set g_start_weapon_hlac 0
-set g_start_weapon_seeker 0
-set g_start_ammo_shells 50
-set g_start_ammo_nails 0
-set g_start_ammo_rockets 0
-set g_start_ammo_cells 0
-set g_pickup_shells 15
-set g_pickup_shells_max 999
-set g_pickup_nails 120
-set g_pickup_nails_max 999
-set g_pickup_rockets 15
-set g_pickup_rockets_max 999
-set g_pickup_cells 25
-set g_pickup_cells_max 999
-set g_pickup_armorsmall 5
-set g_pickup_armorsmall_max 999
-set g_pickup_armormedium 25
-set g_pickup_armormedium_max 999
-set g_pickup_armorlarge 100
-set g_pickup_armorlarge_max 999
-set g_pickup_healthsmall 5
-set g_pickup_healthsmall_max 999
-set g_pickup_healthmedium 25
-set g_pickup_healthmedium_max 999
-set g_pickup_healthlarge 50
-set g_pickup_healthlarge_max 999
-set g_pickup_healthmega 100
-set g_pickup_healthmega_max 999
-set g_pickup_respawntime_short 15
-set g_pickup_respawntime_medium 20
-set g_pickup_respawntime_long 30
-set g_pickup_respawntime_powerup 120
-
-set g_balance_laser_primary_damage 35
-set g_balance_laser_primary_edgedamage 10
-set g_balance_laser_primary_force 400
-set g_balance_laser_primary_radius 70
-set g_balance_laser_primary_speed 9000
-set g_balance_laser_primary_refire 0.7
-set g_balance_laser_primary_animtime 0.3
-set g_balance_laser_primary_lifetime 30
-set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
-set g_balance_laser_secondary_damage 35
-set g_balance_laser_secondary_edgedamage 10
-set g_balance_laser_secondary_force 400
-set g_balance_laser_secondary_radius 70
-set g_balance_laser_secondary_speed 9000
-set g_balance_laser_secondary_refire 0.7
-set g_balance_laser_secondary_animtime 0.3
-set g_balance_laser_secondary_lifetime 30
-
-set g_balance_shotgun_primary_bullets 5
-set g_balance_shotgun_primary_damage 12
-set g_balance_shotgun_primary_force 60
-set g_balance_shotgun_primary_spread 0.08
-set g_balance_shotgun_primary_refire 0.5
-set g_balance_shotgun_primary_animtime 0.2
-set g_balance_shotgun_primary_ammo 1
-set g_balance_shotgun_secondary_bullets 5
-set g_balance_shotgun_secondary_damage 12
-set g_balance_shotgun_secondary_force 60
-set g_balance_shotgun_secondary_spread 0.12
-set g_balance_shotgun_secondary_refire 1.35
-set g_balance_shotgun_secondary_animtime 0.2
-set g_balance_shotgun_secondary_ammo 1
-
-set g_balance_uzi_first_damage 30
-set g_balance_uzi_first_force 50
-set g_balance_uzi_first_spread 0.01
-set g_balance_uzi_first_refire 0.2
-set g_balance_uzi_first_ammo 1
-set g_balance_uzi_sustained_damage 16
-set g_balance_uzi_sustained_force 27
-set g_balance_uzi_sustained_spread 0.05
-set g_balance_uzi_sustained_refire 0.1
-set g_balance_uzi_sustained_ammo 1
-
-set g_balance_grenadelauncher_primary_damage 65
-set g_balance_grenadelauncher_primary_edgedamage 35
-set g_balance_grenadelauncher_primary_force 400
-set g_balance_grenadelauncher_primary_radius 140
-set g_balance_grenadelauncher_primary_speed 2000
-set g_balance_grenadelauncher_primary_speed_up 200
-set g_balance_grenadelauncher_primary_lifetime 30
-set g_balance_grenadelauncher_primary_refire 0.7
-set g_balance_grenadelauncher_primary_animtime 0.3
-set g_balance_grenadelauncher_primary_ammo 2
-set g_balance_grenadelauncher_secondary_damage 65
-set g_balance_grenadelauncher_secondary_edgedamage 35
-set g_balance_grenadelauncher_secondary_force 400
-set g_balance_grenadelauncher_secondary_radius 140
-set g_balance_grenadelauncher_secondary_speed 1400
-set g_balance_grenadelauncher_secondary_speed_up 200
-set g_balance_grenadelauncher_secondary_lifetime 2.5
-set g_balance_grenadelauncher_secondary_refire 0.6
-set g_balance_grenadelauncher_secondary_animtime 0.3
-set g_balance_grenadelauncher_secondary_ammo 2
-set g_balance_grenadelauncher_secondary_health 10
-
-set g_balance_electro_primary_damage 80
-set g_balance_electro_primary_edgedamage 0
-set g_balance_electro_primary_force 200
-set g_balance_electro_primary_radius 150
-set g_balance_electro_primary_speed 2000
-set g_balance_electro_primary_lifetime 30
-set g_balance_electro_primary_refire 0.6
-set g_balance_electro_primary_animtime 0.3
-set g_balance_electro_primary_ammo 2
-set g_balance_electro_secondary_damage 60
-set g_balance_electro_secondary_spread 0.05
-set g_balance_electro_secondary_edgedamage 0
-set g_balance_electro_secondary_force 200
-set g_balance_electro_secondary_radius 150
-set g_balance_electro_secondary_speed 900
-set g_balance_electro_secondary_speed_up 200
-set g_balance_electro_secondary_lifetime 5
-set g_balance_electro_secondary_refire 0.3
-set g_balance_electro_secondary_animtime 0.3
-set g_balance_electro_secondary_ammo 2
-set g_balance_electro_secondary_health 5
-set g_balance_electro_combo_damage 70
-set g_balance_electro_combo_edgedamage 0
-set g_balance_electro_combo_force 200
-set g_balance_electro_combo_radius 250
-set g_balance_electro_combo_speed 2000
-
-set g_balance_crylink_primary_damage 20
-set g_balance_crylink_primary_edgedamage 0
-set g_balance_crylink_primary_force -55
-set g_balance_crylink_primary_radius 80
-set g_balance_crylink_primary_speed 7000
-set g_balance_crylink_primary_spread 0.03
-set g_balance_crylink_primary_shots 4
-set g_balance_crylink_primary_bounces 1
-set g_balance_crylink_primary_refire 0.4
-set g_balance_crylink_primary_animtime 0.3
-set g_balance_crylink_primary_ammo 2
-set g_balance_crylink_primary_bouncedamagefactor 0.5
-
-set g_balance_crylink_primary_middle_lifetime 5 // range: 35000 full, fades to 70000
-set g_balance_crylink_primary_middle_fadetime 5
-set g_balance_crylink_primary_star_lifetime 0.1 // range: 700 full, fades to 2100
-set g_balance_crylink_primary_star_fadetime 0.2
-set g_balance_crylink_primary_other_lifetime 0.1 // range: 700 full, fades to 2100
-set g_balance_crylink_primary_other_fadetime 0.2
-
-set g_balance_crylink_secondary_damage 20
-set g_balance_crylink_secondary_edgedamage 0
-set g_balance_crylink_secondary_force -55
-set g_balance_crylink_secondary_radius 3
-set g_balance_crylink_secondary_speed 7000
-set g_balance_crylink_secondary_spread 0.08
-set g_balance_crylink_secondary_shots 7
-set g_balance_crylink_secondary_bounces 0
-set g_balance_crylink_secondary_refire 0.5
-set g_balance_crylink_secondary_animtime 0.3
-set g_balance_crylink_secondary_ammo 2
-set g_balance_crylink_secondary_bouncedamagefactor 0.5
-
-set g_balance_crylink_secondary_middle_lifetime 5 // range: 35000 full, fades to 70000
-set g_balance_crylink_secondary_middle_fadetime 5
-set g_balance_crylink_secondary_line_lifetime 2 // range: 35000 full, fades to 70000
-set g_balance_crylink_secondary_line_fadetime 2
-
-set g_balance_nex_damage 140
-set g_balance_nex_force 600
-set g_balance_nex_refire 1.5
-set g_balance_nex_animtime 0.3
-set g_balance_nex_ammo 5
-
-set g_balance_minstanex_refire 1
-set g_balance_minstanex_animtime 0.3
-set g_balance_minstanex_ammo 10
-
-set g_balance_hagar_primary_damage 40
-set g_balance_hagar_primary_edgedamage 15
-set g_balance_hagar_primary_force 100
-set g_balance_hagar_primary_radius 70
-set g_balance_hagar_primary_spread 0.010
-set g_balance_hagar_primary_speed 3000
-set g_balance_hagar_primary_lifetime 30
-set g_balance_hagar_primary_refire 0.15
-set g_balance_hagar_primary_ammo 1
-set g_balance_hagar_secondary_damage 40
-set g_balance_hagar_secondary_edgedamage 15
-set g_balance_hagar_secondary_force 100
-set g_balance_hagar_secondary_radius 70
-set g_balance_hagar_secondary_spread 0.015
-set g_balance_hagar_secondary_speed 1400
-set g_balance_hagar_secondary_lifetime 30
-set g_balance_hagar_secondary_refire 0.15
-set g_balance_hagar_secondary_ammo 1
-
-set g_balance_rocketlauncher_damage 130
-set g_balance_rocketlauncher_edgedamage 50
-set g_balance_rocketlauncher_force 600
-set g_balance_rocketlauncher_radius 170
-set g_balance_rocketlauncher_speed 850
-set g_balance_rocketlauncher_speedaccel 0
-set g_balance_rocketlauncher_speedstart 850
-set g_balance_rocketlauncher_lifetime 30
-set g_balance_rocketlauncher_refire 1
-set g_balance_rocketlauncher_animtime 0.3
-set g_balance_rocketlauncher_ammo 3
-set g_balance_rocketlauncher_health 30
-set g_balance_rocketlauncher_detonatedelay 0.2 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
-set g_balance_rocketlauncher_laserguided_speed 1000  //650
-set g_balance_rocketlauncher_laserguided_speedaccel 0
-set g_balance_rocketlauncher_laserguided_speedstart 1000
-set g_balance_rocketlauncher_laserguided_turnrate	0.75  //0.5
-set g_balance_rocketlauncher_laserguided_allow_steal	1
-
-// TESTING: port-o-launch
-set g_balance_porto_primary_refire 1.5
-set g_balance_porto_primary_speed 2000
-set g_balance_porto_primary_lifetime 30
-set g_balance_porto_primary_ammo 25
-set g_balance_portal_health 200 // these get recharged whenever the portal is used
-set g_balance_portal_lifetime 15 // these get recharged whenever the portal is used
-
-// TESTING: on-hand hook with bomb
-set g_balance_hook_primary_ammo 0 // hook monkeys
-set g_balance_hook_primary_refire 0 // hook monkeys
-set g_balance_hook_primary_animtime 0.3 // good shoot anim
-set g_balance_hook_secondary_damage 25 // not much
-set g_balance_hook_secondary_edgedamage 5 // not much
-set g_balance_hook_secondary_radius 800 // LOTS
-set g_balance_hook_secondary_force -2000 // LOTS
-set g_balance_hook_secondary_ammo 25 // a whole pack
-set g_balance_hook_secondary_lifetime 30 // infinite
-set g_balance_hook_secondary_speed 0 // not much throwing
-set g_balance_hook_secondary_gravity 5 // fast falling
-set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
-set g_balance_hook_secondary_animtime 0.3 // good shoot anim
-
-// HLAC 
-set g_balance_hlac_primary_spread_min 0.01
-set g_balance_hlac_primary_spread_max 0.25
-set g_balance_hlac_primary_spread_add 0.0045
-set g_balance_hlac_primary_spread_crouchmod 0.25
-
-set g_balance_hlac_primary_damage 30
-set g_balance_hlac_primary_edgedamage 10
-set g_balance_hlac_primary_force 100
-set g_balance_hlac_primary_radius 70
-set g_balance_hlac_primary_speed 9000
-set g_balance_hlac_primary_lifetime 5
-
-set g_balance_hlac_primary_refire 0.1
-set g_balance_hlac_primary_animtime 0.1
-set g_balance_hlac_primary_ammo 1
-
-set g_balance_hlac_secondary_spread 0.15
-set g_balance_hlac_secondary_spread_crouchmod 0.5
-
-set g_balance_hlac_secondary_damage 30
-set g_balance_hlac_secondary_edgedamage 10
-set g_balance_hlac_secondary_force 150
-set g_balance_hlac_secondary_radius 100
-set g_balance_hlac_secondary_speed 9000
-set g_balance_hlac_secondary_lifetime 5
-
-set g_balance_hlac_secondary_refire 1
-set g_balance_hlac_secondary_animtime 0.3
-set g_balance_hlac_secondary_ammo 10
-set g_balance_hlac_secondary_shots 6
-
-
-// TAG Seeker
-set g_balance_seeker_tag_speed   9000
-set g_balance_seeker_tag_ammo    1
-set g_balance_seeker_tag_animtime 0.1
-set g_balance_seeker_tag_refire  0.7
-
-set g_balance_seeker_missile_delay 0.25
-set g_balance_seeker_missile_activate_delay 0.1
-
-set g_balance_seeker_missile_speed        700
-set g_balance_seeker_missile_accel		1.05
-set g_balance_seeker_missile_decel		0.9
-
-set g_balance_seeker_missile_speed_max    1250
-set g_balance_seeker_missile_turnrate     0.65
-
-set g_balance_seeker_missile_damage       40
-set g_balance_seeker_missile_edgedamage   10
-set g_balance_seeker_missile_radius       80
-set g_balance_seeker_missile_force        250
-
-set g_balance_seeker_missile_count		    4
-set g_balance_seeker_missile_lifetime 	    15
-set g_balance_seeker_missile_refire           0.5
-set g_balance_seeker_missile_animtime 	    0.25
-set g_balance_seeker_missile_ammo             2
-
-set g_balance_seeker_missile_proxy            0
-set g_balance_seeker_missile_proxy_maxrange   45
-set g_balance_seeker_missile_proxy_delay      0.2
-
-// World avoidance
-set g_balance_seeker_missile_smart             1
-set g_balance_seeker_missile_smart_mindist     800
-set g_balance_seeker_missile_smart_trace_max   2500
-set g_balance_seeker_missile_smart_trace_min   1000
-// End new seeker
-
-
-set g_balance_seeker_flac_lifetime      0.1
-set g_balance_seeker_flac_lifetime_rand 0.05
-set g_balance_seeker_flac_speed         3000
-set g_balance_seeker_flac_spread	    0.4
-
-set g_balance_seeker_flac_damage       15
-set g_balance_seeker_flac_edgedamage   10
-set g_balance_seeker_flac_radius       100
-set g_balance_seeker_flac_force        50
-
-set g_balance_seeker_flac_refire       0.1
-set g_balance_seeker_flac_animtime     0.1
-set g_balance_seeker_flac_ammo         0.5
-
-
+// NOTE: whenever you add a cvar to this file, run update-cvarcount.sh to
+// update this checksum!
+//
+// And... don't forget to edit weaponsPro.cfg too.
+
+set cvar_check_weapons bf8a055d6b6b090133b248bccf916024
+
+set g_start_weapon_laser 1
+set g_start_weapon_shotgun 1
+set g_start_weapon_uzi 0
+set g_start_weapon_grenadelauncher 0
+set g_start_weapon_electro 0
+set g_start_weapon_crylink 0
+set g_start_weapon_nex 0
+set g_start_weapon_hagar 0
+set g_start_weapon_rocketlauncher 0
+set g_start_weapon_minstanex 0
+set g_start_weapon_porto 0
+set g_start_weapon_hook 0
+set g_start_weapon_hlac 0
+set g_start_weapon_seeker 0
+set g_start_ammo_shells 50
+set g_start_ammo_nails 0
+set g_start_ammo_rockets 0
+set g_start_ammo_cells 0
+set g_pickup_shells 15
+set g_pickup_shells_max 999
+set g_pickup_nails 120
+set g_pickup_nails_max 999
+set g_pickup_rockets 15
+set g_pickup_rockets_max 999
+set g_pickup_cells 25
+set g_pickup_cells_max 999
+set g_pickup_armorsmall 5
+set g_pickup_armorsmall_max 999
+set g_pickup_armormedium 25
+set g_pickup_armormedium_max 999
+set g_pickup_armorlarge 100
+set g_pickup_armorlarge_max 999
+set g_pickup_healthsmall 5
+set g_pickup_healthsmall_max 999
+set g_pickup_healthmedium 25
+set g_pickup_healthmedium_max 999
+set g_pickup_healthlarge 50
+set g_pickup_healthlarge_max 999
+set g_pickup_healthmega 100
+set g_pickup_healthmega_max 999
+set g_pickup_respawntime_short 15
+set g_pickup_respawntime_medium 20
+set g_pickup_respawntime_long 30
+set g_pickup_respawntime_powerup 120
+set g_pickup_respawntime_weapon 15
+set g_pickup_respawntime_ammo 15
+
+set g_balance_laser_primary_damage 35
+set g_balance_laser_primary_edgedamage 10
+set g_balance_laser_primary_force 400
+set g_balance_laser_primary_radius 70
+set g_balance_laser_primary_speed 9000
+set g_balance_laser_primary_refire 0.7
+set g_balance_laser_primary_animtime 0.3
+set g_balance_laser_primary_lifetime 30
+set g_balance_laser_secondary 0 // when 1, a secondary laser mode exists
+set g_balance_laser_secondary_damage 35
+set g_balance_laser_secondary_edgedamage 10
+set g_balance_laser_secondary_force 400
+set g_balance_laser_secondary_radius 70
+set g_balance_laser_secondary_speed 9000
+set g_balance_laser_secondary_refire 0.7
+set g_balance_laser_secondary_animtime 0.3
+set g_balance_laser_secondary_lifetime 30
+
+set g_balance_shotgun_primary_bullets 5
+set g_balance_shotgun_primary_damage 12
+set g_balance_shotgun_primary_force 60
+set g_balance_shotgun_primary_spread 0.08
+set g_balance_shotgun_primary_refire 0.5
+set g_balance_shotgun_primary_animtime 0.2
+set g_balance_shotgun_primary_ammo 1
+set g_balance_shotgun_secondary_bullets 5
+set g_balance_shotgun_secondary_damage 12
+set g_balance_shotgun_secondary_force 60
+set g_balance_shotgun_secondary_spread 0.12
+set g_balance_shotgun_secondary_refire 1.35
+set g_balance_shotgun_secondary_animtime 0.2
+set g_balance_shotgun_secondary_ammo 1
+
+set g_balance_uzi_first_damage 30
+set g_balance_uzi_first_force 50
+set g_balance_uzi_first_spread 0.01
+set g_balance_uzi_first_refire 0.2
+set g_balance_uzi_first_ammo 1
+set g_balance_uzi_sustained_damage 16
+set g_balance_uzi_sustained_force 27
+set g_balance_uzi_sustained_spread 0.05
+set g_balance_uzi_sustained_refire 0.1
+set g_balance_uzi_sustained_ammo 1
+
+set g_balance_grenadelauncher_primary_damage 65
+set g_balance_grenadelauncher_primary_edgedamage 35
+set g_balance_grenadelauncher_primary_force 400
+set g_balance_grenadelauncher_primary_radius 140
+set g_balance_grenadelauncher_primary_speed 2000
+set g_balance_grenadelauncher_primary_speed_up 200
+set g_balance_grenadelauncher_primary_lifetime 30
+set g_balance_grenadelauncher_primary_refire 0.7
+set g_balance_grenadelauncher_primary_animtime 0.3
+set g_balance_grenadelauncher_primary_ammo 2
+set g_balance_grenadelauncher_secondary_damage 65
+set g_balance_grenadelauncher_secondary_edgedamage 35
+set g_balance_grenadelauncher_secondary_force 400
+set g_balance_grenadelauncher_secondary_radius 140
+set g_balance_grenadelauncher_secondary_speed 1400
+set g_balance_grenadelauncher_secondary_speed_up 200
+set g_balance_grenadelauncher_secondary_lifetime 2.5
+set g_balance_grenadelauncher_secondary_refire 0.6
+set g_balance_grenadelauncher_secondary_animtime 0.3
+set g_balance_grenadelauncher_secondary_ammo 2
+set g_balance_grenadelauncher_secondary_health 10
+
+set g_balance_electro_primary_damage 80
+set g_balance_electro_primary_edgedamage 0
+set g_balance_electro_primary_force 200
+set g_balance_electro_primary_radius 150
+set g_balance_electro_primary_speed 2000
+set g_balance_electro_primary_lifetime 30
+set g_balance_electro_primary_refire 0.6
+set g_balance_electro_primary_animtime 0.3
+set g_balance_electro_primary_ammo 2
+set g_balance_electro_secondary_damage 60
+set g_balance_electro_secondary_spread 0.05
+set g_balance_electro_secondary_edgedamage 0
+set g_balance_electro_secondary_force 200
+set g_balance_electro_secondary_radius 150
+set g_balance_electro_secondary_speed 900
+set g_balance_electro_secondary_speed_up 200
+set g_balance_electro_secondary_lifetime 5
+set g_balance_electro_secondary_refire 0.3
+set g_balance_electro_secondary_animtime 0.3
+set g_balance_electro_secondary_ammo 2
+set g_balance_electro_secondary_health 5
+set g_balance_electro_combo_damage 70
+set g_balance_electro_combo_edgedamage 0
+set g_balance_electro_combo_force 200
+set g_balance_electro_combo_radius 250
+set g_balance_electro_combo_speed 2000
+
+set g_balance_crylink_primary_damage 20
+set g_balance_crylink_primary_edgedamage 0
+set g_balance_crylink_primary_force -55
+set g_balance_crylink_primary_radius 80
+set g_balance_crylink_primary_speed 7000
+set g_balance_crylink_primary_spread 0.03
+set g_balance_crylink_primary_shots 4
+set g_balance_crylink_primary_bounces 1
+set g_balance_crylink_primary_refire 0.4
+set g_balance_crylink_primary_animtime 0.3
+set g_balance_crylink_primary_ammo 2
+set g_balance_crylink_primary_bouncedamagefactor 0.5
+
+set g_balance_crylink_primary_middle_lifetime 5 // range: 35000 full, fades to 70000
+set g_balance_crylink_primary_middle_fadetime 5
+set g_balance_crylink_primary_star_lifetime 0.1 // range: 700 full, fades to 2100
+set g_balance_crylink_primary_star_fadetime 0.2
+set g_balance_crylink_primary_other_lifetime 0.1 // range: 700 full, fades to 2100
+set g_balance_crylink_primary_other_fadetime 0.2
+
+set g_balance_crylink_secondary_damage 20
+set g_balance_crylink_secondary_edgedamage 0
+set g_balance_crylink_secondary_force -55
+set g_balance_crylink_secondary_radius 3
+set g_balance_crylink_secondary_speed 7000
+set g_balance_crylink_secondary_spread 0.08
+set g_balance_crylink_secondary_shots 7
+set g_balance_crylink_secondary_bounces 0
+set g_balance_crylink_secondary_refire 0.5
+set g_balance_crylink_secondary_animtime 0.3
+set g_balance_crylink_secondary_ammo 2
+set g_balance_crylink_secondary_bouncedamagefactor 0.5
+
+set g_balance_crylink_secondary_middle_lifetime 5 // range: 35000 full, fades to 70000
+set g_balance_crylink_secondary_middle_fadetime 5
+set g_balance_crylink_secondary_line_lifetime 2 // range: 35000 full, fades to 70000
+set g_balance_crylink_secondary_line_fadetime 2
+
+set g_balance_nex_damage 140
+set g_balance_nex_force 600
+set g_balance_nex_refire 1.5
+set g_balance_nex_animtime 0.3
+set g_balance_nex_ammo 5
+
+set g_balance_minstanex_refire 1
+set g_balance_minstanex_animtime 0.3
+set g_balance_minstanex_ammo 10
+
+set g_balance_hagar_primary_damage 40
+set g_balance_hagar_primary_edgedamage 15
+set g_balance_hagar_primary_force 100
+set g_balance_hagar_primary_radius 70
+set g_balance_hagar_primary_spread 0.010
+set g_balance_hagar_primary_speed 3000
+set g_balance_hagar_primary_lifetime 30
+set g_balance_hagar_primary_refire 0.15
+set g_balance_hagar_primary_ammo 1
+set g_balance_hagar_secondary_damage 40
+set g_balance_hagar_secondary_edgedamage 15
+set g_balance_hagar_secondary_force 100
+set g_balance_hagar_secondary_radius 70
+set g_balance_hagar_secondary_spread 0.015
+set g_balance_hagar_secondary_speed 1400
+set g_balance_hagar_secondary_lifetime 30
+set g_balance_hagar_secondary_refire 0.15
+set g_balance_hagar_secondary_ammo 1
+
+set g_balance_rocketlauncher_damage 130
+set g_balance_rocketlauncher_edgedamage 50
+set g_balance_rocketlauncher_force 600
+set g_balance_rocketlauncher_radius 170
+set g_balance_rocketlauncher_speed 850
+set g_balance_rocketlauncher_speedaccel 0
+set g_balance_rocketlauncher_speedstart 850
+set g_balance_rocketlauncher_lifetime 30
+set g_balance_rocketlauncher_refire 1
+set g_balance_rocketlauncher_animtime 0.3
+set g_balance_rocketlauncher_ammo 3
+set g_balance_rocketlauncher_health 30
+set g_balance_rocketlauncher_detonatedelay 0.2 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
+set g_balance_rocketlauncher_laserguided_speed 1000  //650
+set g_balance_rocketlauncher_laserguided_speedaccel 0
+set g_balance_rocketlauncher_laserguided_speedstart 1000
+set g_balance_rocketlauncher_laserguided_turnrate	0.75  //0.5
+set g_balance_rocketlauncher_laserguided_allow_steal	1
+
+// TESTING: port-o-launch
+set g_balance_porto_primary_refire 1.5
+set g_balance_porto_primary_speed 2000
+set g_balance_porto_primary_lifetime 30
+set g_balance_porto_primary_ammo 25
+set g_balance_portal_health 200 // these get recharged whenever the portal is used
+set g_balance_portal_lifetime 15 // these get recharged whenever the portal is used
+
+// TESTING: on-hand hook with bomb
+set g_balance_hook_primary_ammo 0 // hook monkeys
+set g_balance_hook_primary_refire 0 // hook monkeys
+set g_balance_hook_primary_animtime 0.3 // good shoot anim
+set g_balance_hook_secondary_damage 25 // not much
+set g_balance_hook_secondary_edgedamage 5 // not much
+set g_balance_hook_secondary_radius 500 // LOTS
+set g_balance_hook_secondary_force -2000 // LOTS
+set g_balance_hook_secondary_ammo 25 // a whole pack
+set g_balance_hook_secondary_lifetime 30 // infinite
+set g_balance_hook_secondary_speed 0 // not much throwing
+set g_balance_hook_secondary_gravity 5 // fast falling
+set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
+set g_balance_hook_secondary_animtime 0.3 // good shoot anim
+set g_balance_hook_secondary_power 3 // effect behaves like a square function
+set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
+
+// HLAC 
+set g_balance_hlac_primary_spread_min 0.01
+set g_balance_hlac_primary_spread_max 0.25
+set g_balance_hlac_primary_spread_add 0.0045
+set g_balance_hlac_primary_spread_crouchmod 0.25
+
+set g_balance_hlac_primary_damage 25
+set g_balance_hlac_primary_edgedamage 10
+set g_balance_hlac_primary_force 100
+set g_balance_hlac_primary_radius 70
+set g_balance_hlac_primary_speed 9000
+set g_balance_hlac_primary_lifetime 5
+
+set g_balance_hlac_primary_refire 0.1
+set g_balance_hlac_primary_animtime 0.1
+set g_balance_hlac_primary_ammo 1
+
+set g_balance_hlac_secondary_spread 0.15
+set g_balance_hlac_secondary_spread_crouchmod 0.5
+
+set g_balance_hlac_secondary_damage 25
+set g_balance_hlac_secondary_edgedamage 10
+set g_balance_hlac_secondary_force 100
+set g_balance_hlac_secondary_radius 70
+set g_balance_hlac_secondary_speed 9000
+set g_balance_hlac_secondary_lifetime 5
+
+set g_balance_hlac_secondary_refire 1
+set g_balance_hlac_secondary_animtime 0.3
+set g_balance_hlac_secondary_ammo 10
+set g_balance_hlac_secondary_shots 6
+
+
+// TAG Seeker
+set g_balance_seeker_tag_speed   9000
+set g_balance_seeker_tag_ammo    1
+set g_balance_seeker_tag_animtime 0.1
+set g_balance_seeker_tag_refire  0.7
+
+set g_balance_seeker_missile_delay 0.25
+set g_balance_seeker_missile_activate_delay 0.1
+
+set g_balance_seeker_missile_speed        700
+set g_balance_seeker_missile_accel		1.05
+set g_balance_seeker_missile_decel		0.9
+
+set g_balance_seeker_missile_speed_max    1250
+set g_balance_seeker_missile_turnrate     0.65
+
+set g_balance_seeker_missile_damage       40
+set g_balance_seeker_missile_edgedamage   10
+set g_balance_seeker_missile_radius       80
+set g_balance_seeker_missile_force        250
+
+set g_balance_seeker_missile_count		    4
+set g_balance_seeker_missile_lifetime 	    15
+set g_balance_seeker_missile_refire           0.5
+set g_balance_seeker_missile_animtime 	    0.25
+set g_balance_seeker_missile_ammo             2
+
+set g_balance_seeker_missile_proxy            0
+set g_balance_seeker_missile_proxy_maxrange   45
+set g_balance_seeker_missile_proxy_delay      0.2
+
+// World avoidance
+set g_balance_seeker_missile_smart             1
+set g_balance_seeker_missile_smart_mindist     800
+set g_balance_seeker_missile_smart_trace_max   2500
+set g_balance_seeker_missile_smart_trace_min   1000
+// End new seeker
+
+
+set g_balance_seeker_flac_lifetime      0.1
+set g_balance_seeker_flac_lifetime_rand 0.05
+set g_balance_seeker_flac_speed         3000
+set g_balance_seeker_flac_spread	    0.4
+
+set g_balance_seeker_flac_damage       15
+set g_balance_seeker_flac_edgedamage   10
+set g_balance_seeker_flac_radius       100
+set g_balance_seeker_flac_force        50
+
+set g_balance_seeker_flac_refire       0.1
+set g_balance_seeker_flac_animtime     0.1
+set g_balance_seeker_flac_ammo         0.5
+
+

Modified: branches/nexuiz-2.0/data/weaponsPro.cfg
===================================================================
--- branches/nexuiz-2.0/data/weaponsPro.cfg	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/data/weaponsPro.cfg	2008-12-12 23:12:17 UTC (rev 5203)
@@ -1,3 +1,5 @@
+set cvar_check_weapons bf8a055d6b6b090133b248bccf916024
+
 set g_start_weapon_laser 1
 set g_start_weapon_shotgun 1
 set g_start_weapon_uzi 0
@@ -42,6 +44,8 @@
 set g_pickup_respawntime_medium 20
 set g_pickup_respawntime_long 30
 set g_pickup_respawntime_powerup 120
+set g_pickup_respawntime_weapon 15
+set g_pickup_respawntime_ammo 15
 
 set g_balance_laser_primary_damage 20
 set g_balance_laser_primary_edgedamage 10
@@ -236,7 +240,7 @@
 set g_balance_hook_primary_animtime 0.3 // good shoot anim
 set g_balance_hook_secondary_damage 25 // not much
 set g_balance_hook_secondary_edgedamage 5 // not much
-set g_balance_hook_secondary_radius 800 // LOTS
+set g_balance_hook_secondary_radius 500 // LOTS
 set g_balance_hook_secondary_force -2000 // LOTS
 set g_balance_hook_secondary_ammo 25 // a whole pack
 set g_balance_hook_secondary_lifetime 30 // infinite
@@ -244,6 +248,8 @@
 set g_balance_hook_secondary_gravity 5 // fast falling
 set g_balance_hook_secondary_refire 3 // don't drop too many bombs...
 set g_balance_hook_secondary_animtime 0.3 // good shoot anim
+set g_balance_hook_secondary_power 3 // effect behaves like a square function
+set g_balance_hook_secondary_duration 1.5 // effect runs for three seconds
 
 // HLAC 
 set g_balance_hlac_primary_spread_min 0.01
@@ -251,7 +257,7 @@
 set g_balance_hlac_primary_spread_add 0.0045
 set g_balance_hlac_primary_spread_crouchmod 0.25
 
-set g_balance_hlac_primary_damage 30
+set g_balance_hlac_primary_damage 25
 set g_balance_hlac_primary_edgedamage 10
 set g_balance_hlac_primary_force 100
 set g_balance_hlac_primary_radius 70
@@ -265,10 +271,10 @@
 set g_balance_hlac_secondary_spread 0.15
 set g_balance_hlac_secondary_spread_crouchmod 0.5
 
-set g_balance_hlac_secondary_damage 30
+set g_balance_hlac_secondary_damage 25
 set g_balance_hlac_secondary_edgedamage 10
-set g_balance_hlac_secondary_force 150
-set g_balance_hlac_secondary_radius 100
+set g_balance_hlac_secondary_force 100
+set g_balance_hlac_secondary_radius 70
 set g_balance_hlac_secondary_speed 9000
 set g_balance_hlac_secondary_lifetime 5
 

Modified: branches/nexuiz-2.0/misc/bsptool.pl
===================================================================
--- branches/nexuiz-2.0/misc/bsptool.pl	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/misc/bsptool.pl	2008-12-12 23:12:17 UTC (rev 5203)
@@ -2,10 +2,47 @@
 
 use strict;
 use warnings;
+use Image::Magick;
+use POSIX qw/floor ceil/;
 
+my @lumpname = qw/entities textures planes nodes leafs leaffaces leafbrushes models brushes brushsides vertices triangles effects faces lightmaps lightgrid pvs advertisements/;
+my %lumpid = map { $lumpname[$_] => $_ } 0.. at lumpname-1;
 my $msg = "";
+my @bsp;
 
+# READ THE BSP
+
+if(!@ARGV || $ARGV[0] eq '-h' || $ARGV[0] eq '--help')
+{
+	print <<EOF;
+Usage:
+  $0 filename.bsp [operations...]
+
+Operations are:
+  Information requests:
+    -i                print info about the BSP file
+    -xlumpname        extract a lump (see -i)
+
+  Changes:
+    -dlumpname        delete a lump (see -i)
+    -gfilename.tga    save the lightgrid as filename.tga (debugging)
+    -Gratio           scale down the lightgrid to reduce BSP file size
+    -ljpgNNN          externalize the lightmaps as JPEG, quality NNN (number from 1 to 100)
+    -lpng             externalize the lightmaps as PNG
+    -ltga             externalize the lightmaps as TGA
+    -mMESSAGE         set the BSP file comment message
+
+  Save commands:
+    -o                actually apply the changes to the BSP
+    -ofilename2.bsp   save the changes to a new BSP file
+EOF
+	exit;
+}
+
 my $fn = shift @ARGV;
+$fn =~ /(.*)\.bsp$/
+	or die "invalid input file name (must be a .bsp): $fn";
+my $basename = $1;
 open my $fh, "<", $fn
 	or die "$fn: $!";
 
@@ -14,17 +51,11 @@
 die "Invalid BSP format"
 	if $header ne "IBSP\x2e\x00\x00\x00";
 
-my @lumpname = qw/entities textures planes nodes leafs leaffaces leafbrushes models brushes brushsides vertices triangles effects faces lightmaps lightgrid pvs advertisements/;
-my %lumpid = map { $lumpname[$_] => $_ } 0.. at lumpname-1;
-
-my @bsp;
-
 for(0..16)
 {
 	read $fh, my $lump, 8;
 	my ($offset, $length) = unpack "VV", $lump;
 
-	print "BSP lump $_ ($lumpname[$_]): offset $offset length $length\n";
 	push @bsp, [$offset, $length, undef];
 }
 
@@ -38,30 +69,415 @@
 	$_->[2] = $data;
 }
 
+close $fh;
+
+# STRUCT DECODING
+
+sub DecodeLump($@)
+{
+	my ($lump, @fields) = @_;
+	my @decoded;
+
+	my $spec = "";
+	my @decoders;
+
+	my $item;
+	my @data;
+	my $idx;
+
+	for(@fields)
+	{
+		if(/^(\w*)=(.*?)(\d*)$/)
+		{
+			$spec .= "$2$3 ";
+			my $f = $1;
+			my $n = $3;
+			if($n eq '')
+			{
+				push @decoders, sub { $item->{$f} = $data[$idx++]; };
+			}
+			else
+			{
+				push @decoders, sub { $item->{$f} = [ map { $data[$idx++] } 1..$n ]; };
+			}
+		}
+	}
+
+	my $itemlen = length pack $spec, ();
+	my $len = length $lump;
+
+	die "Invalid lump size: $len not divisible by $itemlen"
+		if $len % $itemlen;
+
+	my $items = $len / $itemlen;
+	for(0..$items - 1)
+	{
+		@data = unpack $spec, substr $lump, $_ * $itemlen, $itemlen;
+		$item = {};
+		$idx = 0;
+		$_->() for @decoders;
+		push @decoded, $item;
+	}
+	@decoded;
+}
+
+sub EncodeLump($@)
+{
+	my ($items, @fields) = @_;
+	my @decoded;
+
+	my @encoders;
+
+	my $item;
+	my @data;
+	my $idx;
+	my $data = "";
+
+	for(@fields)
+	{
+		if(/^(\w*)=(.*?)(\d*)$/)
+		{
+			my $spec = "$2$3";
+			my $f = $1;
+			my $n = $3;
+			if($n eq '')
+			{
+				push @encoders, sub { $data .= pack $spec, $item->{$f}; };
+			}
+			else
+			{
+				push @encoders, sub { $data .= pack $spec, @{$item->{$f}}; };
+			}
+		}
+	}
+
+	for my $i(@$items)
+	{
+		$item = $i;
+		$_->() for @encoders;
+	}
+
+	$data;
+}
+
+sub EncodeDirection(@)
+{
+	my ($x, $y, $z) = @_;
+
+	return [
+		map { ($_ / 0.02454369260617025967) & 0xFF }
+		(
+			atan2(sqrt($x * $x + $y * $y), $z),
+			atan2($y, $x)
+		)
+	];
+}
+
+sub DecodeDirection($)
+{
+	my ($dir) = @_;
+
+	my ($pitch, $yaw) = map { $_ * 0.02454369260617025967 } @$dir; # maps 256 to 2pi
+
+	return (
+		cos($yaw) * sin($pitch),
+		sin($yaw) * sin($pitch),
+		cos($pitch)
+	);
+}
+
+sub IntervalIntersection($$$$)
+{
+	my ($a, $al, $b, $bl) = @_;
+	my $a0 = $a - 0.5 * $al;
+	my $a1 = $a + 0.5 * $al;
+	my $b0 = $b - 0.5 * $bl;
+	my $b1 = $b + 0.5 * $bl;
+	my $left = ($a0 > $b0) ? $a0 : $b0;
+	my $right = ($a1 > $b1) ? $b1 : $a1;
+	die "Non-intersecting intervals $a $al $b $bl"
+		if $right < $left;
+	return $right - $left;
+}
+
+sub BoxIntersection(@)
+{
+	my ($x, $y, $z, $w, $h, $d, $x2, $y2, $z2, $w2, $h2, $d2) = @_;
+	return
+		IntervalIntersection($x, $w, $x2, $w2)
+		*
+		IntervalIntersection($y, $h, $y2, $h2)
+		*
+		IntervalIntersection($z, $d, $z2, $d2);
+}
+
+# OPTIONS
+
 for(@ARGV)
 {
-	if(/^-x(.*)$/)
+	if(/^-i$/) # info
 	{
+		my $total = 17 * 8 + 8 + length($msg);
+		my $max = 0;
+		for(0.. at bsp-1)
+		{
+			my $nl = length $bsp[$_]->[2];
+			$total += $nl;
+			print "BSP lump $_ ($lumpname[$_]): offset $bsp[$_]->[0] length $bsp[$_]->[1] newlength $nl\n";
+			my $endpos = $bsp[$_]->[0] + $bsp[$_]->[1];
+			$max = $endpos if $max < $endpos;
+		}
+		print "BSP file size will change from $max to $total bytes\n";
+	}
+	elsif(/^-d(.+)$/) # delete a lump
+	{
 		my $id = $lumpid{$1};
 		die "invalid lump $1 to remove"
 			unless defined $id;
 		$bsp[$id]->[2] = "";
 	}
-	elsif(/^-m(.*)$/)
+	elsif(/^-m(.*)$/) # change the message
 	{
 		$msg = $1;
 	}
-	elsif(/^-e(.*)$/) # extract lump
+	elsif(/^-l(jpg|png|tga)(\d+)?$/) # externalize lightmaps (deleting the internal ones)
 	{
+		my $ext = $1;
+		my $quality = $2;
+		my %lightmaps = ();
+		my $faces = $bsp[$lumpid{faces}]->[2];
+		my $lightmaps = $bsp[$lumpid{lightmaps}]->[2];
+		my @values = DecodeLump $faces,
+			qw/texture=V effect=V type=V vertex=V n_vertexes=V meshvert=V n_meshverts=V lm_index=V lm_start=f2 lm_size=f2 lm_origin=f3 lm_vec_0=f3 lm_vec_1=f3 normal=f3 size=V2/;
+		my $oddfound = 0;
+		for(@values)
+		{
+			my $l = $_->{lm_index};
+			next if $l >= 2**31; # signed
+			$oddfound = 1
+				if $l % 2;
+			++$lightmaps{$l};
+		}
+		if(!$oddfound)
+		{
+			$lightmaps{$_+1} = $lightmaps{$_} for keys %lightmaps;
+		}
+		for(sort { $a <=> $b } keys %lightmaps)
+		{
+			print STDERR "Lightmap $_ was used $lightmaps{$_} times\n";
+
+			# export that lightmap
+			my $lmsize = 128 * 128 * 3;
+			next if length $lightmaps < ($_ + 1) * $lmsize;
+			my $lmdata = substr $lightmaps, $_ * $lmsize, $lmsize;
+			my $img = Image::Magick->new(size => '128x128', depth => 8, magick => 'RGB');
+			$img->BlobToImage($lmdata);
+			my $outfn = sprintf "%s/lm_%04d.$ext", $basename, $_;
+			mkdir $basename;
+			$img->Set(quality => $quality)
+				if defined $quality;
+			my $err = $img->Write($outfn);
+			die $err
+				if $err;
+			print STDERR "Wrote $outfn\n";
+		}
+
+		# nullify the lightmap lump
+		$bsp[$lumpid{lightmaps}]->[2] = "";
+	}
+	elsif(/^-g(.+)$/) # export light grid as an image (for debugging)
+	{
+		my $filename = $1;
+		my @models = DecodeLump $bsp[$lumpid{models}]->[2],
+			qw/mins=f3 maxs=f3 face=V n_faces=V brush=V n_brushes=V/;
+		my $entities = $bsp[$lumpid{entities}]->[2];
+		my @entitylines = split /\r?\n/, $entities;
+		my $gridsize = "64 64 128";
+		for(@entitylines)
+		{
+			last if $_ eq '}';
+			/^\s*"gridsize"\s+"(.*)"$/
+				and $gridsize = $1;
+		}
+		my @scale = map { 1 / $_ } split / /, $gridsize;
+		my @imins = map { ceil($models[0]{mins}[$_] * $scale[$_]) } 0..2;
+		my @imaxs = map { floor($models[0]{maxs}[$_] * $scale[$_]) } 0..2;
+		my @isize = map { $imaxs[$_] - $imins[$_] + 1 } 0..2;
+		my $isize = $isize[0] * $isize[1] * $isize[2];
+		my @gridcells = DecodeLump $bsp[$lumpid{lightgrid}]->[2],
+			qw/ambient=C3 directional=C3 dir=C2/;
+		die "Cannot decode light grid"
+			unless $isize == @gridcells;
+
+		# sum up the "ambient" light over all pixels
+		my @pixels;
+		my $max = 1;
+		for my $y(0..$isize[1]-1)
+		{
+			for my $x(0..$isize[0]-1)
+			{
+				my ($r, $g, $b) = (0, 0, 0);
+				for my $z(0..$isize[2]-1)
+				{
+					my $cell = $gridcells[$x + $y * $isize[0] + $z * $isize[0] * $isize[1]];
+					$r += $cell->{ambient}->[0];
+					$g += $cell->{ambient}->[1];
+					$b += $cell->{ambient}->[2];
+				}
+				push @pixels, [$r, $g, $b];
+				$max = $r if $max < $r;
+				$max = $g if $max < $g;
+				$max = $b if $max < $b;
+			}
+		}
+		my $pixeldata = "";
+		for my $p(@pixels)
+		{
+			$pixeldata .= pack "CCC", map { 255 * $p->[$_] / $max } 0..2;
+		}
+
+		my $img = Image::Magick->new(size => sprintf("%dx%d", $isize[0], $isize[1]), depth => 8, magick => 'RGB');
+		$img->BlobToImage($pixeldata);
+		$img->Write($filename);
+		print STDERR "Wrote $filename\n";
+	}
+	elsif(/^-G(.+)$/) # decimate light grid
+	{
+		my $decimate = $1;
+		my $filter = 1; # 0 = nearest, 1 = box filter
+
+		my @models = DecodeLump $bsp[$lumpid{models}]->[2],
+			qw/mins=f3 maxs=f3 face=V n_faces=V brush=V n_brushes=V/;
+		my $entities = $bsp[$lumpid{entities}]->[2];
+		my @entitylines = split /\r?\n/, $entities;
+		my $gridsize = "64 64 128";
+		my $gridsizeindex = undef;
+		for(0.. at entitylines-1)
+		{
+			my $l = $entitylines[$_];
+			last if $l eq '}';
+			if($l =~ /^\s*"gridsize"\s+"(.*)"$/)
+			{
+				$gridsize = $1;
+				$gridsizeindex = $_;
+			}
+		}
+		my @scale = map { 1 / $_ } split / /, $gridsize;
+		my @imins = map { ceil($models[0]{mins}[$_] * $scale[$_]) } 0..2;
+		my @imaxs = map { floor($models[0]{maxs}[$_] * $scale[$_]) } 0..2;
+		my @isize = map { $imaxs[$_] - $imins[$_] + 1 } 0..2;
+		my $isize = $isize[0] * $isize[1] * $isize[2];
+		my @gridcells = DecodeLump $bsp[$lumpid{lightgrid}]->[2],
+			qw/ambient=C3 directional=C3 dir=C2/;
+		die "Cannot decode light grid"
+			unless $isize == @gridcells;
+
+		# get the new grid size values
+		my @newscale = map { $_ / $decimate } @scale;
+		my $newgridsize = join " ", map { 1 / $_ } @newscale;
+		my @newimins = map { ceil($models[0]{mins}[$_] * $newscale[$_]) } 0..2;
+		my @newimaxs = map { floor($models[0]{maxs}[$_] * $newscale[$_]) } 0..2;
+		my @newisize = map { $newimaxs[$_] - $newimins[$_] + 1 } 0..2;
+
+		# do the decimation
+		my @newgridcells = ();
+		for my $z($newimins[2]..$newimaxs[2])
+		{
+			# the coords are MIDPOINTS of the grid cells!
+			my @oldz = grep { $_ >= $imins[2] && $_ <= $imaxs[2] } floor(($z - 0.5) * $decimate + 0.5) .. ceil(($z + 0.5) * $decimate - 0.5);
+			my $innerz_raw = $z * $decimate;
+			my $innerz = floor($innerz_raw + 0.5);
+			$innerz = $imins[2] if $innerz < $imins[2];
+			$innerz = $imaxs[2] if $innerz > $imaxs[2];
+			for my $y($newimins[1]..$newimaxs[1])
+			{
+				my @oldy = grep { $_ >= $imins[1] && $_ <= $imaxs[1] } floor(($y - 0.5) * $decimate + 0.5) .. ceil(($y + 0.5) * $decimate - 0.5);
+				my $innery_raw = $y * $decimate;
+				my $innery = floor($innery_raw + 0.5);
+				$innery = $imins[1] if $innery < $imins[1];
+				$innery = $imaxs[1] if $innery > $imaxs[1];
+				for my $x($newimins[0]..$newimaxs[0])
+				{
+					my @oldx = grep { $_ >= $imins[0] && $_ <= $imaxs[0] } floor(($x - 0.5) * $decimate + 0.5) .. ceil(($x + 0.5) * $decimate - 0.5);
+					my $innerx_raw = $x * $decimate;
+					my $innerx = floor($innerx_raw + 0.5);
+					$innerx = $imins[0] if $innerx < $imins[0];
+					$innerx = $imaxs[0] if $innerx > $imaxs[0];
+
+					my @vec = (0, 0, 0);
+					my @dir = (0, 0, 0);
+					my @amb = (0, 0, 0);
+					my $weight = 0;
+					my $innercell = $gridcells[($innerx - $imins[0]) + $isize[0] * ($innery - $imins[1]) + $isize[0] * $isize[1] * ($innerz - $imins[2])];
+					for my $Z(@oldz)
+					{
+						for my $Y(@oldy)
+						{
+							for my $X(@oldx)
+							{
+								my $cell = $gridcells[($X - $imins[0]) + $isize[0] * ($Y - $imins[1]) + $isize[0] * $isize[1] * ($Z - $imins[2])];
+
+								my $cellweight = BoxIntersection(
+									$X, $Y, $Z, 1, 1, 1,
+									map { $_ * $decimate } $x, $y, $z, 1, 1, 1
+								);
+
+								$dir[$_] += $cellweight * $cell->{directional}->[$_] for 0..2;
+								$amb[$_] += $cellweight * $cell->{ambient}->[$_] for 0..2;
+								my @norm = DecodeDirection $cell->{dir};
+								$vec[$_] += $cellweight * $norm[$_] for 0..2;
+								$weight += $cellweight;
+							}
+						}
+					}
+					if($weight)
+					{
+						$dir[$_] /= $weight for 0..2;
+						$dir[$_] *= $filter for 0..2;
+						$dir[$_] += (1 - $filter) * $innercell->{directional}->[$_] for 0..2;
+
+						$amb[$_] /= $weight for 0..2;
+						$amb[$_] *= $filter for 0..2;
+						$amb[$_] += (1 - $filter) * $innercell->{ambient}->[$_] for 0..2;
+
+						my @norm = DecodeDirection $innercell->{dir};
+						$vec[$_] /= $weight for 0..2;
+						$vec[$_] *= $filter for 0..2;
+						$vec[$_] += (1 - $filter) * $norm[$_] for 0..2;
+
+						$innercell = {
+							ambient => \@amb,
+							directional => \@dir,
+							dir => EncodeDirection @norm
+						};
+					}
+
+					push @newgridcells, $innercell;
+				}
+			}
+		}
+
+		$bsp[$lumpid{lightgrid}]->[2] = EncodeLump \@newgridcells,
+			qw/ambient=C3 directional=C3 dir=C2/;
+		splice @entitylines, $gridsizeindex, 1, ()
+			if defined $gridsizeindex;
+		splice @entitylines, 1, 0, qq{"gridsize" "$newgridsize"};
+		$bsp[$lumpid{entities}]->[2] = join "\n", @entitylines;
+	}
+	elsif(/^-x(.+)$/) # extract lump to stdout
+	{
 		my $id = $lumpid{$1};
 		die "invalid lump $1 to extract"
 			unless defined $id;
 		print $bsp[$id]->[2];
 	}
-	elsif(/^-o(.*)$/)
+	elsif(/^-o(.+)?$/) # write the final BSP file
 	{
-		open my $fh, ">", $1
-			or die "$1: $!";
+		my $outfile = $1;
+		$outfile = $fn
+			if not defined $outfile;
+		open my $fh, ">", $outfile
+			or die "$outfile: $!";
 		print $fh $header;
 		my $pos = 17 * 8 + tell($fh) + length $msg;
 		for(@bsp)
@@ -76,11 +492,16 @@
 		{
 			print $fh $_->[2];
 		}
+		close $fh;
+		print STDERR "Wrote $outfile\n";
 	}
+	else
+	{
+		die "Invalid option: $_";
+	}
 }
 
 # TODO:
 #   features like:
-#     externalize lightmaps
 #     decimate light grid
 #     edit lightmaps/grid


Property changes on: branches/nexuiz-2.0/misc/bsptool.pl
___________________________________________________________________
Name: svn:executable
   + *

Copied: branches/nexuiz-2.0/misc/dependencies.pl (from rev 5202, trunk/misc/dependencies.pl)
===================================================================
--- branches/nexuiz-2.0/misc/dependencies.pl	                        (rev 0)
+++ branches/nexuiz-2.0/misc/dependencies.pl	2008-12-12 23:12:17 UTC (rev 5203)
@@ -0,0 +1,303 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my %files = ();
+my %shaders = ();
+
+sub ReadShaders()
+{
+	for my $sf(<scripts/*.shader>)
+	{
+		my $curshader = undef;
+		my @tex = ();
+		my $level = 0;
+		open my $fh, "<", $sf
+			or die "<$sf: $!";
+		while(<$fh>)
+		{
+			s/\r//gs;
+			chomp;
+
+			s/\/\/.*//s;
+			s/^\s+//;
+			s/\s+$//;
+			next if /^$/;
+
+			my @line = map { s/"//g; $_; } split /\s+/, $_;
+
+			if($line[0] eq '{')
+			{
+				++$level;
+			}
+			elsif($line[0] eq '}')
+			{
+				--$level;
+				if($level <= 0)
+				{
+					$level = 0;
+					if(defined $curshader)
+					{
+						$shaders{lc $curshader} = { shaderfile => $sf, textures => [ @tex ] };
+					}
+					$curshader = undef;
+				}
+			}
+			elsif($level == 0)
+			{
+				$curshader = $line[0];
+				@tex = ();
+			}
+			elsif($level == 1 and lc $line[0] eq 'qer_editorimage')
+			{
+				push @tex, $line[1];
+			}
+			elsif($level == 1 and lc $line[0] eq 'qer_lightimage')
+			{
+				push @tex, $line[1];
+			}
+			elsif($level == 1 and lc $line[0] eq 'skyparms')
+			{
+				for(qw/rt lf ft bk up dn/)
+				{
+					push @tex, "$line[1]_$_";
+					push @tex, "$line[3]_$_";
+				}
+			}
+			elsif($level == 2 and lc $line[0] eq 'map')
+			{
+				push @tex, $line[1];
+			}
+			elsif($level == 2 and lc $line[0] eq 'animmap')
+			{
+				for(2..(@line - 1))
+				{
+					push @tex, $line[$_];
+				}
+			}
+		}
+	}
+}
+
+sub AddFile($)
+{
+	my ($file) = @_;
+	return 0
+		unless -e $file;
+	++$files{$file};
+	return 1;
+}
+
+sub AddSound($)
+{
+	my ($tex) = @_;
+	$tex =~ s/\.ogg$|\.wav$//i;
+	AddFile "$tex.ogg" or
+	AddFile "$tex.wav" or
+	AddFile "sound/$tex.ogg" or
+	AddFile "sound/$tex.wav";
+}
+
+sub AddTexture($)
+{
+	my ($tex) = @_;
+	$tex =~ s/\.jpg$|\.tga$|\.png$//i;
+	AddFile "$tex.jpg" or
+	AddFile "$tex.tga" or
+	AddFile "$tex.png"
+		or return 0;
+	for('_shirt', '_pants', '_glow', '_norm', '_bump', '_gloss')
+	{
+		AddFile "$tex$_.jpg" or
+		AddFile "$tex$_.tga" or
+		AddFile "$tex$_.png";
+	}
+	return 1;
+}
+
+sub AddShader($)
+{
+	my ($shader) = @_;
+	$shader =~ s/\.jpg$|\.tga$|\.png$//i;
+	my $si = $shaders{lc $shader};
+	if(not defined $si)
+	{
+		AddTexture $shader
+			or warn "Unknown shader used: $shader";
+	}
+	else
+	{
+		AddFile $si->{shaderfile};
+		AddTexture $_
+			for @{$si->{textures}};
+	}
+}
+
+sub AddMapDependencies($)
+{
+	my ($data) = @_;
+	for(/^"noise.*" "(.*)"/gm)
+	{
+		AddSound $1;
+	}
+	for(/^"sound.*" "(.*)"/gm)
+	{
+		AddSound $1;
+	}
+	for(/^"music" "(.*)"/gm)
+	{
+		AddSound $1;
+	}
+	for(/^"model" "(.*)"/gm)
+	{
+		# TODO make this AddModel
+		# TODO and find the shaders the model uses
+		AddFile $1;
+	}
+	for(/^"lodmodel.*" "(.*)"/gm)
+	{
+		AddFile $1;
+	}
+}
+
+sub AddMapinfoDependencies($)
+{
+	my ($data) = @_;
+	for($data =~ /^cdtrack (.*)$/gm)
+	{
+		AddSound "sound/cdtracks/$1";
+	}
+}
+
+sub AddCfgDependencies($)
+{
+	my ($data) = @_;
+	for($data =~ /^cd loop "?(.*?)"?$/gm)
+	{
+		AddSound "sound/cdtracks/$1";
+	}
+}
+
+sub AddShaderDependencies($)
+{
+	my ($data) = @_;
+
+	my $n = length($data) / 72;
+	for(0..($n-1))
+	{
+		my $s = substr $data, $_ * 72, 64;
+		$s =~ s/\0.*$//s;
+		AddShader $s;
+	}
+}
+
+sub AddFaceDependencies($$)
+{
+	my ($base, $data) = @_;
+
+	my $n = length($data) / 104;
+	for(0..($n-1))
+	{
+		my $l = unpack "V", substr $data, $_ * 104 + 28, 4;
+		AddTexture sprintf "maps/%s/lm_%04d", $base, $l;
+		AddTexture sprintf "maps/%s/lm_%04d", $base, $l | 1; # deluxe
+	}
+}
+
+
+ReadShaders();
+
+for(<maps/*.ent>)
+{
+	AddFile $_;
+
+	my $data = do {
+		undef local $/;
+		open my $fh, "<", $_
+			or die "<$_: $!";
+		<$fh>;
+	};
+	AddMapDependencies $data;
+}
+
+for(<maps/*.bsp>)
+{
+	AddFile $_;
+
+	m!^maps/(.*)\.bsp! or die "perl is stupid";
+	my $b = $1;
+	AddFile "maps/$b.mapinfo";
+	AddFile "maps/$b.jpg";
+	AddFile "maps/$b.cfg";
+	AddFile "maps/$b.waypoints";
+	AddFile "maps/$b.rtlights";
+	AddTexture "gfx/$b\_radar.tga";
+	AddTexture "gfx/$b\_mini.tga";
+
+	my $data = do {
+		undef local $/;
+		open my $fh, "<", "maps/$b.mapinfo"
+			or warn "<maps/$b.mapinfo: $!";
+		<$fh>;
+	};
+	AddMapinfoDependencies $data;
+
+	$data = do {
+		undef local $/;
+		open my $fh, "<", "maps/$b.cfg"
+			or warn "<maps/$b.cfg: $!";
+		<$fh>;
+	};
+	AddCfgDependencies $data;
+
+	$data = do {
+		undef local $/;
+		open my $fh, "-|", 'bsptool.pl', $_, '-xentities'
+			or die "<$_: $!";
+		<$fh>;
+	};
+	AddMapDependencies $data;
+
+	$data = do {
+		undef local $/;
+		open my $fh, "-|", 'bsptool.pl', $_, '-xfaces'
+			or die "<$_: $!";
+		<$fh>;
+	};
+	AddFaceDependencies $b, $data;
+
+	$data = do {
+		undef local $/;
+		open my $fh, "-|", 'bsptool.pl', $_, '-xtextures'
+			or die "<$_: $!";
+		<$fh>;
+	};
+	AddShaderDependencies $data;
+}
+
+sub RecurseDir($);
+sub RecurseDir($)
+{
+	my ($dir) = @_;
+	if(-d $dir)
+	{
+		for(<$dir/*>)
+		{
+			RecurseDir $_;
+		}
+	}
+	else
+	{
+		warn "Unused file: $dir"
+			unless $files{$dir};
+	}
+}
+
+for(<*>)
+{
+	RecurseDir $_;
+}
+
+print "$_\0"
+	for sort keys %files;

Copied: branches/nexuiz-2.0/misc/jpeg-if-not-alpha.sh (from rev 5202, trunk/misc/jpeg-if-not-alpha.sh)
===================================================================
--- branches/nexuiz-2.0/misc/jpeg-if-not-alpha.sh	                        (rev 0)
+++ branches/nexuiz-2.0/misc/jpeg-if-not-alpha.sh	2008-12-12 23:12:17 UTC (rev 5203)
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+set -e
+
+: ${qual:=95}
+
+for X in "$@"; do
+	case "$X" in
+		*.jpg)
+			jpegoptim --strip-all -m$qual "$X"
+			;;
+		*.png|*.tga)
+			if convert "$X" -depth 16 RGBA:- | perl -e 'local $/ = \8; while(<>) { substr($_, 6, 2) eq "\xFF\xFF" or exit 1; ++$pix; } END { exit not $pix; }'; then
+				echo "$X has no alpha, converting"
+				convert "$X" -quality 100 "${X%.*}.jpg"
+				jpegoptim --strip-all -m$qual "${X%.*}.jpg"
+				rm -f "$X"
+			else
+				echo "$X has alpha, not converting"
+			fi
+			;;
+	esac
+done

Modified: branches/nexuiz-2.0/misc/ttf2conchars/ttf2conchars.c
===================================================================
--- branches/nexuiz-2.0/misc/ttf2conchars/ttf2conchars.c	2008-12-12 21:40:50 UTC (rev 5202)
+++ branches/nexuiz-2.0/misc/ttf2conchars/ttf2conchars.c	2008-12-12 23:12:17 UTC (rev 5203)
@@ -1,10 +1,51 @@
 #include <stdio.h>
-#include <err.h>
+#include <errno.h>
+#include <stdarg.h>
 #include <math.h>
 #include "SDL/SDL.h" 
 #include "SDL/SDL_ttf.h" 
 #include "SDL/SDL_image.h" 
 
+void warn(char *fmt, ...)
+{
+	va_list list;
+	int e = errno;
+	va_start(list, fmt);
+	vfprintf(stderr, fmt, list);
+	fputs(": ", stderr);
+	fputs(strerror(e), stderr);
+	fputs("\n", stderr);
+}
+
+void warnx(char *fmt, ...)
+{
+	va_list list;
+	va_start(list, fmt);
+	vfprintf(stderr, fmt, list);
+	fputs("\n", stderr);
+}
+
+void err(int ex, char *fmt, ...)
+{
+	va_list list;
+	int e = errno;
+	va_start(list, fmt);
+	vfprintf(stderr, fmt, list);
+	fputs(": ", stderr);
+	fputs(strerror(e), stderr);
+	fputs("\n", stderr);
+	exit(ex);
+}
+
+void errx(int ex, char *fmt, ...)
+{
+	va_list list;
+	va_start(list, fmt);
+	vfprintf(stderr, fmt, list);
+	fputs("\n", stderr);
+	exit(ex);
+}
+
 void Image_WriteTGABGRA (const char *filename, int width, int height, const unsigned char *data)
 {
     int y;
@@ -150,7 +191,7 @@
 	double r, g, b, a, f;
 	Uint8 pr, pg, pb, pa;
 	int i, j;
-	int imax = BLURFUNCIMAX(A,B);
+	int imax = (int) BLURFUNCIMAX(A,B);
 
 	// 1. calculate blackened blurred image
 	a = 0;
@@ -198,20 +239,30 @@
 	else if(C < 0)
 		r = g = b = MAX(0, 255 + C * a);
 
-	return SDL_MapRGBA(fmt, r, g, b, a);
+	return SDL_MapRGBA(fmt, (unsigned char) r, (unsigned char) g, (unsigned char) b, (unsigned char) a);
 }
 
 void blitfilter(SDL_Surface *src, SDL_Surface *dest, int x0, int y0, double A, double B, double C)
 {
 	// note: x0, y0 is the origin of the UNFILTERED image; it is "transparently" expanded by a BLURFUNCIMAX.
-	int x, y, d;
+	int x, y, d, xa, ya, xb, yb;
 
-	d = BLURFUNCIMAX(A,B);
+	d = (int) BLURFUNCIMAX(A,B);
 	SDL_LockSurface(src);
 	SDL_LockSurface(dest);
-	for(y = -d; y < d + src->h; ++y)
-		for(x = -d; x < d + src->w; ++x)
-			putpixel(dest, x + x0, y + y0, getpixelfilter(src, dest->format, x, y, A, B, C));
+
+	xa = x0 - d;
+	ya = y0 - d;
+	xb = x0 + src->w + d;
+	yb = y0 + src->h + d;
+
+	if(xa < 0) xa = 0;
+	if(ya < 0) ya = 0;
+	if(xa >= dest->w) xa = dest->w - 1;
+	if(ya >= dest->h) ya = dest->h - 1;
+	for(y = ya; y <= yb; ++y)
+		for(x = xa; x <= xb; ++x)
+			putpixel(dest, x, y, getpixelfilter(src, dest->format, x - x0, y - y0, A, B, C));
 	SDL_UnlockSurface(dest);
 	SDL_UnlockSurface(src);
 }
@@ -387,7 +438,7 @@
 					if(j == (toY))
 						inc *= dtoY;
 
-					int iinc = inc * 256;
+					int iinc = (int) (inc * 256);
 
 					r += (pr * iinc);
 					g += (pg * iinc);
@@ -544,7 +595,7 @@
 	char widthfilename[512];
 	snprintf(widthfilename, sizeof(widthfilename), "%.*s.width", (int)strlen(outfilename) - 4, outfilename);
 
-	int border=BLURFUNCIMAX(A, B);
+	int border=(int) BLURFUNCIMAX(A, B);
 
 	fprintf(stderr, "Using %d border pixels\n", border);
 
@@ -647,8 +698,10 @@
 
 		if(differentFonts)
 		{
-			TTF_CloseFont(fonts[2]);
-			TTF_CloseFont(fonts[1]);
+			if(fonts[2])
+				TTF_CloseFont(fonts[2]);
+			if(fonts[1])
+				TTF_CloseFont(fonts[1]);
 		}
 		TTF_CloseFont(fonts[0]);
 	}
@@ -708,8 +761,8 @@
 			//   destBottom = referenceBottom / cell * h + y
 
 			dest.x = 0;
-			dest.y = (destBottom * referenceTop - destTop * referenceBottom) / (double) (referenceTop - referenceBottom);
-			dest.h = cell * (destBottom - destTop) / (double) (referenceBottom - referenceTop);
+			dest.y = (int) ((double) (destBottom * referenceTop - destTop * referenceBottom) / (double) (referenceTop - referenceBottom));
+			dest.h = (int) (cell * (double) (destBottom - destTop) / (double) (referenceBottom - referenceTop));
 			dest.w = dest.h;
 
 			/*
@@ -769,7 +822,7 @@
 
 	fprintf(stderr, "Writing...\n");
 
-	Image_WriteTGABGRA(outfilename, conchars->w, conchars->h, conchars->pixels);
+	Image_WriteTGABGRA(outfilename, conchars->w, conchars->h, (unsigned char *) conchars->pixels);
 
 	SDL_FreeSurface(conchars);
 




More information about the nexuiz-commits mailing list