r4731 - in branches/nexuiz-2.0: . Docs/server Docs/server/rcon2irc data data/particles data/qcsrc/client data/qcsrc/common data/qcsrc/menu data/qcsrc/menu/nexuiz data/qcsrc/server data/qcsrc/server/tturrets/system data/qcsrc/server/tturrets/units data/scripts data/sound/weapons

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sat Oct 11 11:11:19 EDT 2008


Author: div0
Date: 2008-10-11 11:11:15 -0400 (Sat, 11 Oct 2008)
New Revision: 4731

Added:
   branches/nexuiz-2.0/data/build-compat-pack.sh
   branches/nexuiz-2.0/data/ctfscoring-div0.cfg
   branches/nexuiz-2.0/data/ctfscoring-z-lowdeposit.cfg
   branches/nexuiz-2.0/data/qcsrc/common/util-pre.qh
   branches/nexuiz-2.0/data/sound/weapons/minstanexfire.ogg
Modified:
   branches/nexuiz-2.0/.patchsets
   branches/nexuiz-2.0/Docs/server/rcon2irc/rcon2irc-example.conf
   branches/nexuiz-2.0/Docs/server/rcon2irc/rcon2irc.pl
   branches/nexuiz-2.0/Docs/server/server.cfg
   branches/nexuiz-2.0/data/ctfscoring-ai.cfg
   branches/nexuiz-2.0/data/ctfscoring-alien.cfg
   branches/nexuiz-2.0/data/ctfscoring-alpha.cfg
   branches/nexuiz-2.0/data/ctfscoring-nex242.cfg
   branches/nexuiz-2.0/data/ctfscoring-z.cfg
   branches/nexuiz-2.0/data/cvars.txt
   branches/nexuiz-2.0/data/cvars.txt.pl
   branches/nexuiz-2.0/data/defaultNexuiz.cfg
   branches/nexuiz-2.0/data/effectinfo.txt
   branches/nexuiz-2.0/data/nexuiz-credits.txt
   branches/nexuiz-2.0/data/particles/particlefont.tga
   branches/nexuiz-2.0/data/qcsrc/client/Main.qc
   branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.qc
   branches/nexuiz-2.0/data/qcsrc/client/mapvoting.qc
   branches/nexuiz-2.0/data/qcsrc/client/progs.src
   branches/nexuiz-2.0/data/qcsrc/client/sbar.qc
   branches/nexuiz-2.0/data/qcsrc/client/teamradar.qc
   branches/nexuiz-2.0/data/qcsrc/common/campaign_file.qc
   branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc
   branches/nexuiz-2.0/data/qcsrc/common/util.qc
   branches/nexuiz-2.0/data/qcsrc/common/util.qh
   branches/nexuiz-2.0/data/qcsrc/menu/gamecommand.qc
   branches/nexuiz-2.0/data/qcsrc/menu/menu.qc
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup_radar.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_singleplayer.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/keybinder.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/slider_resolution.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/weaponslist.c
   branches/nexuiz-2.0/data/qcsrc/menu/progs.src
   branches/nexuiz-2.0/data/qcsrc/server/arena.qc
   branches/nexuiz-2.0/data/qcsrc/server/builtins.qh
   branches/nexuiz-2.0/data/qcsrc/server/campaign.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_player.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/g_damage.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/keyhunt.qc
   branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
   branches/nexuiz-2.0/data/qcsrc/server/portals.qc
   branches/nexuiz-2.0/data/qcsrc/server/progs.src
   branches/nexuiz-2.0/data/qcsrc/server/race.qc
   branches/nexuiz-2.0/data/qcsrc/server/runematch.qc
   branches/nexuiz-2.0/data/qcsrc/server/scores_rules.qc
   branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc
   branches/nexuiz-2.0/data/qcsrc/server/t_items.qc
   branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc
   branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
   branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/turret_system_damage.qc
   branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_flac.qc
   branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_hellion.qc
   branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_hk.qc
   branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_mlrs.qc
   branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_plasma.qc
   branches/nexuiz-2.0/data/qcsrc/server/vote.qc
   branches/nexuiz-2.0/data/qcsrc/server/vote.qh
   branches/nexuiz-2.0/data/qcsrc/server/w_common.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_crylink.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_electro.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_grenadelauncher.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_hagar.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_laser.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_minstanex.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_porto.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_rocketlauncher.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_shotgun.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc
   branches/nexuiz-2.0/data/qcsrc/server/waypointsprites.qc
   branches/nexuiz-2.0/data/scripts/entities.def
   branches/nexuiz-2.0/data/weapons.cfg
Log:
r4678 | div0 | 2008-10-08 19:50:33 +0200 (Wed, 08 Oct 2008) | 2 lines
fix overtime msg
r4679 | div0 | 2008-10-08 21:49:49 +0200 (Wed, 08 Oct 2008) | 2 lines
wider radar dialogr4680 | div0 | 2008-10-09 08:31:51 +0200 (Thu, 09 Oct 2008) | 2 lines
more death types (now weapons know whether the hit was primary or secondary, whether it was splash damage or not, and whether the projectile bounced before the hit)
r4681 | div0 | 2008-10-09 10:00:18 +0200 (Thu, 09 Oct 2008) | 3 lines
g_ctf_fullbrightflags
g_balance_ctf_damageforcescale
r4682 | div0 | 2008-10-09 10:05:17 +0200 (Thu, 09 Oct 2008) | 2 lines
fix setsize calls. This should now fix flag going through bunker.
r4683 | div0 | 2008-10-09 10:54:48 +0200 (Thu, 09 Oct 2008) | 2 lines
fix shotgun effect
r4684 | div0 | 2008-10-09 11:28:25 +0200 (Thu, 09 Oct 2008) | 2 lines
defer droptofloor to after all entities are loaded. Fixes issues with q3skoredm1.
r4685 | div0 | 2008-10-09 12:49:20 +0200 (Thu, 09 Oct 2008) | 3 lines
cl_teamradar_foreground_alpha cvar
r4686 | div0 | 2008-10-09 12:52:03 +0200 (Thu, 09 Oct 2008) | 2 lines
fix typo in radar
r4687 | div0 | 2008-10-09 12:53:49 +0200 (Thu, 09 Oct 2008) | 2 lines
argh... last typo there
r4688 | div0 | 2008-10-09 13:26:45 +0200 (Thu, 09 Oct 2008) | 3 lines
- make portals easier to destruct (200 health instead of 300)
- fix bug that caused red portal to never regenerate
r4689 | div0 | 2008-10-09 13:29:03 +0200 (Thu, 09 Oct 2008) | 2 lines
make portal health/lifetime cvars
r4690 | div0 | 2008-10-09 15:51:13 +0200 (Thu, 09 Oct 2008) | 2 lines
"message2" for hurt triggers
r4691 | div0 | 2008-10-10 07:46:11 +0200 (Fri, 10 Oct 2008) | 2 lines
fix flag scoring config
r4692 | div0 | 2008-10-10 08:53:05 +0200 (Fri, 10 Oct 2008) | 2 lines
use g_ctf_personalscore* cvars if g_ctf_win_mode is 0 or 1 (caps scoring); this fixes the problems with [-z-]'s scoring system as it would be HIGHLY broken as only decider of a match (it would reward camping more than anything else)
r4693 | div0 | 2008-10-10 08:54:19 +0200 (Fri, 10 Oct 2008) | 2 lines
forgot this cvar. THERE IS NO LONGER g_ctf_win_mode 3, this functionality is now in g_ctf_ignore_frags!
r4694 | div0 | 2008-10-10 08:56:26 +0200 (Fri, 10 Oct 2008) | 2 lines
fix that cfg
r4695 | div0 | 2008-10-10 09:23:39 +0200 (Fri, 10 Oct 2008) | 2 lines
yet another scoring mode...
r4696 | div0 | 2008-10-10 10:36:48 +0200 (Fri, 10 Oct 2008) | 2 lines
support for announcer/male/impressive and announcer/male/headshot ;)
r4697 | div0 | 2008-10-10 10:57:11 +0200 (Fri, 10 Oct 2008) | 2 lines
don't kill impressive that easily :P
r4698 | div0 | 2008-10-10 11:18:35 +0200 (Fri, 10 Oct 2008) | 2 lines
tiny cleanup
r4699 | div0 | 2008-10-10 14:39:34 +0200 (Fri, 10 Oct 2008) | 2 lines
fix float logic for almost_in_bounds
r4700 | div0 | 2008-10-10 15:02:33 +0200 (Fri, 10 Oct 2008) | 2 lines
separated out the mortar trail and the hagar trail to be less ugly for the hagar
r4701 | div0 | 2008-10-10 15:09:34 +0200 (Fri, 10 Oct 2008) | 2 lines
added a script to make svn server support pk3s
r4702 | div0 | 2008-10-10 15:09:56 +0200 (Fri, 10 Oct 2008) | 2 lines
better name
r4703 | div0 | 2008-10-10 15:11:43 +0200 (Fri, 10 Oct 2008) | 2 lines
oops, forgot these
r4704 | div0 | 2008-10-10 15:25:10 +0200 (Fri, 10 Oct 2008) | 2 lines
fix missing CTF settings in server.cfg
r4705 | div0 | 2008-10-10 15:26:35 +0200 (Fri, 10 Oct 2008) | 2 lines
fix team radar FG alpha default
r4706 | esteel | 2008-10-10 15:41:56 +0200 (Fri, 10 Oct 2008) | 2 lines
made build-compat-pack.sh executable
r4707 | div0 | 2008-10-10 15:42:00 +0200 (Fri, 10 Oct 2008) | 2 lines
more visible vote/warmup naggers
r4708 | div0 | 2008-10-10 15:59:44 +0200 (Fri, 10 Oct 2008) | 2 lines
new teamradar alpha defaults, should look better and not be overwhtie
r4709 | morphed | 2008-10-10 16:22:06 +0200 (Fri, 10 Oct 2008) | 1 line
toned down hagar trail, more powerfull rocket explosion, tweaked fire particle textures
r4710 | div0 | 2008-10-10 16:45:22 +0200 (Fri, 10 Oct 2008) | 2 lines
hook is a mutator, why seta?
r4711 | div0 | 2008-10-10 17:01:53 +0200 (Fri, 10 Oct 2008) | 2 lines
ctf: always sort scoreboard by personal score
r4712 | div0 | 2008-10-10 17:21:05 +0200 (Fri, 10 Oct 2008) | 2 lines
fix fraglimit display for CTF
r4713 | div0 | 2008-10-10 17:30:48 +0200 (Fri, 10 Oct 2008) | 2 lines
correctly track player ID of last holding player
r4714 | div0 | 2008-10-10 17:38:57 +0200 (Fri, 10 Oct 2008) | 2 lines
fix func_bobbing
r4715 | div0 | 2008-10-10 17:55:33 +0200 (Fri, 10 Oct 2008) | 2 lines
oops :P forgot to un-setmodel when getting the modelindexes
r4716 | div0 | 2008-10-10 17:55:56 +0200 (Fri, 10 Oct 2008) | 2 lines
remove debug print too
r4717 | div0 | 2008-10-10 18:12:42 +0200 (Fri, 10 Oct 2008) | 2 lines
fix keyhunt crash with warmup
r4718 | div0 | 2008-10-10 18:19:49 +0200 (Fri, 10 Oct 2008) | 2 lines
use sound/weapons/minstanexfire.ogg
r4719 | div0 | 2008-10-10 18:25:04 +0200 (Fri, 10 Oct 2008) | 2 lines
credits fixes (Tenshihan, [-z-], Blub)
r4720 | div0 | 2008-10-10 19:02:44 +0200 (Fri, 10 Oct 2008) | 2 lines
irc_trigger
r4721 | div0 | 2008-10-10 21:00:58 +0200 (Fri, 10 Oct 2008) | 2 lines
allow flag dropping, but disabled by default. Also fix flag portal sound spam.
r4722 | div0 | 2008-10-11 07:18:44 +0200 (Sat, 11 Oct 2008) | 2 lines
[-z-]
r4723 | div0 | 2008-10-11 09:00:30 +0200 (Sat, 11 Oct 2008) | 3 lines
Experimental new tokenizer (should now be 1:1 compatible to the console parsing), used for about anything now.
Votes no longer get accidentally reformatted, e.g. "(foo)" to "( foo )".
r4724 | div0 | 2008-10-11 09:04:17 +0200 (Sat, 11 Oct 2008) | 2 lines
stop using the insane tokenizer for menu skin files
r4725 | div0 | 2008-10-11 10:04:21 +0200 (Sat, 11 Oct 2008) | 2 lines
credit tenshihan with full name
r4726 | div0 | 2008-10-11 13:27:10 +0200 (Sat, 11 Oct 2008) | 2 lines
forgot this
r4727 | div0 | 2008-10-11 14:02:58 +0200 (Sat, 11 Oct 2008) | 2 lines
add more cvars (new ones...)
r4728 | div0 | 2008-10-11 14:26:54 +0200 (Sat, 11 Oct 2008) | 2 lines
g_balance_teams_complain 0 now shuts off the message (no longer just 99999999999999)
r4729 | div0 | 2008-10-11 15:19:52 +0200 (Sat, 11 Oct 2008) | 2 lines
rcon2irc: add irc_local option. Probably broken.
r4730 | div0 | 2008-10-11 17:07:20 +0200 (Sat, 11 Oct 2008) | 2 lines
use DRAWFLAG_SCREEN for team radar now (warning: breaks on old engines that are after 2.4.2. SVN users, update your engines.)

Modified: branches/nexuiz-2.0/.patchsets
===================================================================
--- branches/nexuiz-2.0/.patchsets	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/.patchsets	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1,2 +1,2 @@
 master = svn://svn.icculus.org/nexuiz/trunk
-revisions_applied = 1-4676
+revisions_applied = 1-4730

Modified: branches/nexuiz-2.0/Docs/server/rcon2irc/rcon2irc-example.conf
===================================================================
--- branches/nexuiz-2.0/Docs/server/rcon2irc/rcon2irc-example.conf	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/Docs/server/rcon2irc/rcon2irc-example.conf	2008-10-11 15:11:15 UTC (rev 4731)
@@ -18,10 +18,14 @@
 # Extra plug-ins to load
 #plugins =
 
+# Alternate IRC trigger (can be used instead of nickname to send stuff to the server)
+#irc_trigger = nexnexnex
+
 # Tuning
 #dp_server_from_wan =
 #dp_listen = 141.2.16.23:27771
 #dp_status_delay = 30
+#irc_local = 141.2.16.23
 #irc_ping_delay = 120
 #irc_nickserv_identify = PRIVMSG NickServ :IDENTIFY %2$s
 #irc_nickserv_ghost = PRIVMSG NickServ :GHOST %1$s %2$s

Modified: branches/nexuiz-2.0/Docs/server/rcon2irc/rcon2irc.pl
===================================================================
--- branches/nexuiz-2.0/Docs/server/rcon2irc/rcon2irc.pl	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/Docs/server/rcon2irc/rcon2irc.pl	2008-10-11 15:11:15 UTC (rev 4731)
@@ -413,6 +413,7 @@
 	irc_user => undef,
 	irc_channel => undef,
 	irc_ping_delay => 120,
+	irc_trigger => "",
 
 	irc_nickserv_password => "",
 	irc_nickserv_identify => 'PRIVMSG NickServ :IDENTIFY %2$s',
@@ -430,6 +431,7 @@
 	dp_password => undef,
 	dp_status_delay => 30,
 	dp_server_from_wan => "",
+	irc_local => "",
 
 	plugins => "",
 );
@@ -642,7 +644,7 @@
 
 # Create the two channels to gateway between...
 
-$channels{irc} = new Channel::Line(new Connection::Socket(tcp => "" => $config{irc_server} => 6667));
+$channels{irc} = new Channel::Line(new Connection::Socket(tcp => $config{irc_local} => $config{irc_server} => 6667));
 $channels{dp} = new Channel::QW(my $dpsock = new Connection::Socket(udp => $config{dp_listen} => $config{dp_server} => 26000), $config{dp_password});
 $config{dp_listen} = $dpsock->sockname();
 print "Listening on $config{dp_listen}\n";
@@ -1052,7 +1054,7 @@
 	} ],
 
 	# chat: IRC channel -> Nexuiz server
-	[ irc => q{:([^! ]*)![^ ]* (?i:PRIVMSG) (?i:(??{$config{irc_channel}})) :(?i:(??{$store{irc_nick}}))(?: |: ?)(.*)} => sub {
+	[ irc => q{:([^! ]*)![^ ]* (?i:PRIVMSG) (?i:(??{$config{irc_channel}})) :(?i:(??{$store{irc_nick}}))(?: |: ?|, ?)(.*)} => sub {
 		my ($nick, $message) = @_;
 		$nick = color_dpfix $nick;
 			# allow the nickname to contain colors in DP format! Therefore, NO color_irc2dp on the nickname!
@@ -1062,6 +1064,22 @@
 		return 0;
 	} ],
 
+	(
+		length $config{irc_trigger}
+			?
+				[ irc => q{:([^! ]*)![^ ]* (?i:PRIVMSG) (?i:(??{$config{irc_channel}})) :(?i:(??{$config{irc_trigger}}))(?: |: ?|, ?)(.*)} => sub {
+					my ($nick, $message) = @_;
+					$nick = color_dpfix $nick;
+						# allow the nickname to contain colors in DP format! Therefore, NO color_irc2dp on the nickname!
+					$message = color_irc2dp $message;
+					$message =~ s/(["\\])/\\$1/g;
+					out dp => 0, "rcon2irc_say_as \"$nick on IRC\" \"$message\"";
+					return 0;
+				} ]
+			:
+				()
+	),
+
 	# irc: CTCP VERSION reply
 	[ irc => q{:([^! ]*)![^ ]* (?i:PRIVMSG) (?i:(??{$store{irc_nick}})) :\001VERSION( .*)?\001} => sub {
 		my ($nick) = @_;

Modified: branches/nexuiz-2.0/Docs/server/server.cfg
===================================================================
--- branches/nexuiz-2.0/Docs/server/server.cfg	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/Docs/server/server.cfg	2008-10-11 15:11:15 UTC (rev 4731)
@@ -26,11 +26,15 @@
 //timelimit_override -1        // global timelimit for all maps and gametypes
 //fraglimit_override -1        // global frag/point limit for all maps and gametypes
 //g_ctf_capture_limit -1       // frag/capture limit for CTF
+//capturelimit_override -1     // capture limit for CTF
 //g_domination_point_limit -1  // frag/point limit for DOM
 //g_runematch_point_limit -1   // frag/point limit for RUNE
 //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
+
 // TEAMS for key hunt (change this to 2, 3, 4 to set a fixed keyhunt style)
 //g_keyhunt_teams_override -1  // teams for KH
 

Copied: branches/nexuiz-2.0/data/build-compat-pack.sh (from rev 4730, trunk/data/build-compat-pack.sh)
===================================================================
--- branches/nexuiz-2.0/data/build-compat-pack.sh	                        (rev 0)
+++ branches/nexuiz-2.0/data/build-compat-pack.sh	2008-10-11 15:11:15 UTC (rev 4731)
@@ -0,0 +1,115 @@
+#!/bin/sh
+
+# list of files v2.4.2 clients need to play on svn servers
+
+COMPAT_FILES="
+	effectinfo.txt
+	gfx/aggressor_mini.tga
+	gfx/aneurysm_mini.tga
+	gfx/basementctf_mini.tga
+	gfx/bleach_mini.tga
+	gfx/bloodprisonctf_mini.tga
+	gfx/bloodprison_mini.tga
+	gfx/bluesky_mini.tga
+	gfx/dieselpower_mini.tga
+	gfx/dismal_mini.tga
+	gfx/final_rage_mini.tga
+	gfx/inv_weapon10.tga
+	gfx/inv_weapon9.tga
+	gfx/reslimed_mini.tga
+	gfx/runningman_1on1remix_mini.tga
+	gfx/runningmanctf_mini.tga
+	gfx/runningman_mini.tga
+	gfx/sb_kh_full.tga
+	gfx/sb_kh_outline.tga
+	gfx/silvercity_mini.tga
+	gfx/stormkeep_mini.tga
+	gfx/strength_mini.tga
+	gfx/teamradar_icon_1.tga
+	gfx/teamradar_icon_2.tga
+	gfx/teamradar_ping.tga
+	gfx/toxic_mini.tga
+	gfx/warfare_mini.tga
+	models/portal.md3
+	models/sprites/bluebase.tga
+	models/sprites/danger.tga
+	models/sprites/defend.tga
+	models/sprites/destroy.tga
+	models/sprites/flagcarrier.tga
+	models/sprites/helpme.tga
+	models/sprites/here.tga
+	models/sprites/keycarrier-blue.tga
+	models/sprites/keycarrier-finish.tga
+	models/sprites/keycarrier-friend.tga
+	models/sprites/keycarrier-pink.tga
+	models/sprites/keycarrier-red.tga
+	models/sprites/keycarrier-yellow.tga
+	models/sprites/key-dropped.tga
+	models/sprites/ons-cp-atck-blue.tga
+	models/sprites/ons-cp-atck-neut.tga
+	models/sprites/ons-cp-atck-red.tga
+	models/sprites/ons-cp-blue.tga
+	models/sprites/ons-cp-dfnd-blue.tga
+	models/sprites/ons-cp-dfnd-red.tga
+	models/sprites/ons-cp-neut.tga
+	models/sprites/ons-cp-red.tga
+	models/sprites/ons-gen-blue.tga
+	models/sprites/ons-gen-red.tga
+	models/sprites/ons-gen-shielded.tga
+	models/sprites/push.tga
+	models/sprites/race-checkpoint.sp2
+	models/sprites/race-checkpoint.tga
+	models/sprites/race-finish.sp2
+	models/sprites/race-finish.tga
+	models/sprites/redbase.tga
+	models/sprites/waypoint.tga
+	models/weapons/g_minstanex.md3
+	models/weapons/g_porto.md3
+	models/weapons/v_minstanex.md3
+	models/weapons/v_porto.md3
+	models/weapons/w_minstanex.zym
+	models/weapons/w_porto.zym
+	particles/particlefont.tga
+	sound/player/default.sounds
+	sound/player/torus/attack.ogg
+	sound/player/torus/coverme.ogg
+	sound/player/torus/death.ogg
+	sound/player/torus/drown.ogg
+	sound/player/torus/fall.ogg
+	sound/player/torus/flagseen.ogg
+	sound/player/torus/gasp.ogg
+	sound/player/torus/hooah.ogg
+	sound/player/torus/incoming.ogg
+	sound/player/torus/jump.ogg
+	sound/player/torus/letsgo.ogg
+	sound/player/torus/needhelp.ogg
+	sound/player/torus/pain100.ogg
+	sound/player/torus/pain25.ogg
+	sound/player/torus/pain50.ogg
+	sound/player/torus/pain75.ogg
+	sound/player/torus/taunt.ogg
+	sound/player/torus/teamshoot.ogg
+	sound/player/torus/waypoint.ogg
+	sound/porto/bounce.ogg
+	sound/porto/create.ogg
+	sound/porto/expire.ogg
+	sound/porto/explode.ogg
+	sound/porto/fire.ogg
+	sound/porto/unsupported.ogg
+	textures/nex_bump.tga
+	textures/nex_gloss.tga
+	textures/nex_glow.tga
+	textures/nex_pants.tga
+	textures/nex_shirt.tga
+	textures/nex.tga
+	textures/portalgun_gloss.tga
+	textures/portalgun_glow.tga
+	textures/portalgun_norm.tga
+	textures/portalgun.tga
+"
+
+rev=`svnversion`
+pack="zzz_svn-compat-$rev"
+echo "Support files to play on svn servers of revision $rev" > "$pack.txt"
+7za a -tzip -mx=9 "$pack.pk3" $COMPAT_FILES "$pack.txt"
+rm -f "$pack.txt"

Modified: branches/nexuiz-2.0/data/ctfscoring-ai.cfg
===================================================================
--- branches/nexuiz-2.0/data/ctfscoring-ai.cfg	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/ctfscoring-ai.cfg	2008-10-11 15:11:15 UTC (rev 4731)
@@ -15,3 +15,16 @@
 // failed (shot into void) (pickup kill drop)     0 (0 for enemy)
 // capture retry (kill drop pickup)               0 (0 for enemy)
 // suicide, then retake (suicidedrop pickup)      0 (0 for enemy)
+
+set g_ctf_personalscore_pickup_base                   0
+set g_ctf_personalscore_pickup_dropped_early          0
+set g_ctf_personalscore_pickup_dropped_late           0
+set g_ctf_personalscore_capture                      20
+set g_ctf_personalscore_kill                          0
+set g_ctf_personalpenalty_drop                        0
+set g_ctf_personalpenalty_suicidedrop                 0
+set g_ctf_personalpenalty_returned                    5
+set g_ctf_personalscore_return                        0
+set g_ctf_personalscore_return_rogue                 10
+set g_ctf_personalscore_return_by_killer              0
+set g_ctf_personalscore_return_rogue_by_killer       10

Modified: branches/nexuiz-2.0/data/ctfscoring-alien.cfg
===================================================================
--- branches/nexuiz-2.0/data/ctfscoring-alien.cfg	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/ctfscoring-alien.cfg	2008-10-11 15:11:15 UTC (rev 4731)
@@ -15,3 +15,16 @@
 // failed (shot into void) (pickup kill drop)     1 (1 for enemy)
 // capture retry (kill drop pickup)              -1 (1 for enemy)
 // suicide, then retake (suicidedrop pickup)     -1 (0 for enemy)
+
+set g_ctf_personalscore_pickup_base                   1
+set g_ctf_personalscore_pickup_dropped_early          1
+set g_ctf_personalscore_pickup_dropped_late           1
+set g_ctf_personalscore_capture                      30
+set g_ctf_personalscore_kill                          1
+set g_ctf_personalpenalty_drop                        2
+set g_ctf_personalpenalty_suicidedrop                 2
+set g_ctf_personalpenalty_returned                    0
+set g_ctf_personalscore_return                        5
+set g_ctf_personalscore_return_rogue                 10
+set g_ctf_personalscore_return_by_killer              6
+set g_ctf_personalscore_return_rogue_by_killer       11

Modified: branches/nexuiz-2.0/data/ctfscoring-alpha.cfg
===================================================================
--- branches/nexuiz-2.0/data/ctfscoring-alpha.cfg	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/ctfscoring-alpha.cfg	2008-10-11 15:11:15 UTC (rev 4731)
@@ -15,3 +15,16 @@
 // failed (shot into void) (pickup kill drop)     0 (0 for enemy)
 // capture retry (kill drop pickup)               0 (0 for enemy)
 // suicide, then retake (suicidedrop pickup)      0 (0 for enemy)
+
+set g_ctf_personalscore_pickup_base                   0
+set g_ctf_personalscore_pickup_dropped_early          0
+set g_ctf_personalscore_pickup_dropped_late           0
+set g_ctf_personalscore_capture                      20
+set g_ctf_personalscore_kill                          0
+set g_ctf_personalpenalty_drop                        0
+set g_ctf_personalpenalty_suicidedrop                 0
+set g_ctf_personalpenalty_returned                    0
+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_rogue_by_killer       10

Copied: branches/nexuiz-2.0/data/ctfscoring-div0.cfg (from rev 4730, trunk/data/ctfscoring-div0.cfg)
===================================================================
--- branches/nexuiz-2.0/data/ctfscoring-div0.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/ctfscoring-div0.cfg	2008-10-11 15:11:15 UTC (rev 4731)
@@ -0,0 +1,30 @@
+set g_ctf_flagscore_pickup_base                  -1
+set g_ctf_flagscore_pickup_dropped_early          2
+set g_ctf_flagscore_pickup_dropped_late           2
+set g_ctf_flagscore_capture                      25
+set g_ctf_flagscore_kill                          3
+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_rogue_by_killer       10
+// succeeded capture (pickup capture)            24 (0 for enemy)
+// failed capture (pickup kill drop return)      -4 (8 for enemy)
+// failed (shot into void) (pickup kill drop)    -4 (3 for enemy)
+// capture retry (kill drop pickup)               0 (3 for enemy)
+// suicide, then retake (suicidedrop pickup)      0 (0 for enemy)
+
+set g_ctf_personalscore_pickup_base                  -1
+set g_ctf_personalscore_pickup_dropped_early          2
+set g_ctf_personalscore_pickup_dropped_late           2
+set g_ctf_personalscore_capture                      25
+set g_ctf_personalscore_kill                          3
+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_rogue_by_killer       10

Modified: branches/nexuiz-2.0/data/ctfscoring-nex242.cfg
===================================================================
--- branches/nexuiz-2.0/data/ctfscoring-nex242.cfg	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/ctfscoring-nex242.cfg	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1,6 +1,6 @@
 set g_ctf_flagscore_pickup_base                   1
 set g_ctf_flagscore_pickup_dropped_early          1
-set g_ctf_flagscore_pickup_dropped_late           5
+set g_ctf_flagscore_pickup_dropped_late           1
 set g_ctf_flagscore_capture                      20
 set g_ctf_flagscore_kill                          1
 set g_ctf_flagpenalty_drop                        0
@@ -15,3 +15,16 @@
 // failed (shot into void) (pickup kill drop)     1 (1 for enemy)
 // capture retry (kill drop pickup)               1 (1 for enemy)
 // suicide, then retake (suicidedrop pickup)      0 (0 for enemy)
+
+set g_ctf_personalscore_pickup_base                   1
+set g_ctf_personalscore_pickup_dropped_early          1
+set g_ctf_personalscore_pickup_dropped_late           1
+set g_ctf_personalscore_capture                      20
+set g_ctf_personalscore_kill                          1
+set g_ctf_personalpenalty_drop                        0
+set g_ctf_personalpenalty_suicidedrop                 1
+set g_ctf_personalpenalty_returned                    0
+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_rogue_by_killer       10

Copied: branches/nexuiz-2.0/data/ctfscoring-z-lowdeposit.cfg (from rev 4730, trunk/data/ctfscoring-z-lowdeposit.cfg)
===================================================================
--- branches/nexuiz-2.0/data/ctfscoring-z-lowdeposit.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/ctfscoring-z-lowdeposit.cfg	2008-10-11 15:11:15 UTC (rev 4731)
@@ -0,0 +1,19 @@
+exec ctfscoring-ai.cfg // fall back to ai's scoring for flag scores, if g_ctf_win_mode is 2, as this system is highly broken in that mode
+
+set g_ctf_personalscore_pickup_base                  -1
+set g_ctf_personalscore_pickup_dropped_early          5
+set g_ctf_personalscore_pickup_dropped_late           9
+set g_ctf_personalscore_capture                      26
+set g_ctf_personalscore_kill                          5
+set g_ctf_personalpenalty_drop                        9
+set g_ctf_personalpenalty_suicidedrop                 9
+set g_ctf_personalpenalty_returned                    0
+set g_ctf_personalscore_return                        3
+set g_ctf_personalscore_return_rogue                 10
+set g_ctf_personalscore_return_by_killer              3
+set g_ctf_personalscore_return_rogue_by_killer       10
+// succeeded capture (pickup capture)            25 (0 for enemy)
+// failed capture (pickup kill drop return)     -10 (8 for enemy)
+// failed (shot into void) (pickup kill drop)   -10 (5 for enemy)
+// capture retry (kill drop pickup)          -1..-4 (5 for enemy)
+// suicide, then retake (suicidedrop pickup) -1..-4 (0 for enemy)

Modified: branches/nexuiz-2.0/data/ctfscoring-z.cfg
===================================================================
--- branches/nexuiz-2.0/data/ctfscoring-z.cfg	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/ctfscoring-z.cfg	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1,15 +1,17 @@
-set g_ctf_flagscore_pickup_base                  -5
-set g_ctf_flagscore_pickup_dropped_early          1
-set g_ctf_flagscore_pickup_dropped_late           5
-set g_ctf_flagscore_capture                      30
-set g_ctf_flagscore_kill                          5
-set g_ctf_flagpenalty_drop                        5
-set g_ctf_flagpenalty_suicidedrop                 5
-set g_ctf_flagpenalty_returned                    0
-set g_ctf_flagscore_return                        3
-set g_ctf_flagscore_return_rogue                 10
-set g_ctf_flagscore_return_by_killer              3
-set g_ctf_flagscore_return_rogue_by_killer       10
+exec ctfscoring-ai.cfg // fall back to ai's scoring for flag scores, if g_ctf_win_mode is 2, as this system is highly broken in that mode
+
+set g_ctf_personalscore_pickup_base                  -5
+set g_ctf_personalscore_pickup_dropped_early          1
+set g_ctf_personalscore_pickup_dropped_late           5
+set g_ctf_personalscore_capture                      30
+set g_ctf_personalscore_kill                          5
+set g_ctf_personalpenalty_drop                        5
+set g_ctf_personalpenalty_suicidedrop                 5
+set g_ctf_personalpenalty_returned                    0
+set g_ctf_personalscore_return                        3
+set g_ctf_personalscore_return_rogue                 10
+set g_ctf_personalscore_return_by_killer              3
+set g_ctf_personalscore_return_rogue_by_killer       10
 // succeeded capture (pickup capture)            25 (0 for enemy)
 // failed capture (pickup kill drop return)     -10 (8 for enemy)
 // failed (shot into void) (pickup kill drop)   -10 (5 for enemy)

Modified: branches/nexuiz-2.0/data/cvars.txt
===================================================================
--- branches/nexuiz-2.0/data/cvars.txt	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/cvars.txt	2008-10-11 15:11:15 UTC (rev 4731)
@@ -104,6 +104,8 @@
 "g_balance_crylink_secondary_shots" "TODO: describe me"
 "g_balance_crylink_secondary_speed" "TODO: describe me"
 "g_balance_crylink_secondary_spread" "TODO: describe me"
+"g_balance_ctf_damageforcescale" "TODO: describe me"
+"g_balance_ctf_delay_collect" "TODO: describe me"
 "g_balance_curse_empathy_minhealth" "TODO: describe me"
 "g_balance_curse_empathy_takedamage" "TODO: describe me"
 "g_balance_curse_slow_atkrate" "TODO: describe me"
@@ -257,6 +259,8 @@
 "g_balance_pause_health_regen_spawn" "TODO: describe me"
 "g_balance_pause_health_rot" "TODO: describe me"
 "g_balance_pause_health_rot_spawn" "TODO: describe me"
+"g_balance_portal_health" "TODO: describe me"
+"g_balance_portal_lifetime" "TODO: describe me"
 "g_balance_porto_primary_ammo" "TODO: describe me"
 "g_balance_porto_primary_lifetime" "TODO: describe me"
 "g_balance_porto_primary_refire" "TODO: describe me"
@@ -354,11 +358,13 @@
 "g_chat_nospectators" "TODO: describe me"
 "g_chat_teamcolors" "TODO: describe me"
 "g_cloaked" "TODO: describe me"
+"g_ctf_allow_drop" "TODO: describe me"
 "g_ctf_capture_limit" "TODO: describe me"
 "g_ctf_flag_returntime" "TODO: describe me"
 "g_ctf_flagcarrier_selfdamage" "TODO: describe me"
 "g_ctf_flagcarrier_selfforce" "TODO: describe me"
 "g_ctf_flagpenalty_drop" "TODO: describe me"
+"g_ctf_flagpenalty_returned" "TODO: describe me"
 "g_ctf_flagpenalty_suicidedrop" "TODO: describe me"
 "g_ctf_flagscore_capture" "TODO: describe me"
 "g_ctf_flagscore_kill" "TODO: describe me"
@@ -369,6 +375,20 @@
 "g_ctf_flagscore_return_by_killer" "TODO: describe me"
 "g_ctf_flagscore_return_rogue" "TODO: describe me"
 "g_ctf_flagscore_return_rogue_by_killer" "TODO: describe me"
+"g_ctf_fullbrightflags" "TODO: describe me"
+"g_ctf_ignore_frags" "TODO: describe me"
+"g_ctf_personalpenalty_drop" "TODO: describe me"
+"g_ctf_personalpenalty_returned" "TODO: describe me"
+"g_ctf_personalpenalty_suicidedrop" "TODO: describe me"
+"g_ctf_personalscore_capture" "TODO: describe me"
+"g_ctf_personalscore_kill" "TODO: describe me"
+"g_ctf_personalscore_pickup_base" "TODO: describe me"
+"g_ctf_personalscore_pickup_dropped_early" "TODO: describe me"
+"g_ctf_personalscore_pickup_dropped_late" "TODO: describe me"
+"g_ctf_personalscore_return" "TODO: describe me"
+"g_ctf_personalscore_return_by_killer" "TODO: describe me"
+"g_ctf_personalscore_return_rogue" "TODO: describe me"
+"g_ctf_personalscore_return_rogue_by_killer" "TODO: describe me"
 "g_ctf_respawn_delay" "TODO: describe me"
 "g_ctf_respawn_waves" "TODO: describe me"
 "g_ctf_win_mode" "TODO: describe me"
@@ -548,6 +568,7 @@
 "g_waypointsprite_minalpha" "TODO: describe me"
 "g_waypointsprite_minscale" "TODO: describe me"
 "g_waypointsprite_normdistance" "TODO: describe me"
+"g_waypointsprite_scale" "TODO: describe me"
 "g_waypointsprite_stuffbinds" "TODO: describe me"
 "g_waypointsprite_timealphaexponent" "TODO: describe me"
 "g_weapon_stay" "TODO: describe me"

Modified: branches/nexuiz-2.0/data/cvars.txt.pl
===================================================================
--- branches/nexuiz-2.0/data/cvars.txt.pl	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/cvars.txt.pl	2008-10-11 15:11:15 UTC (rev 4731)
@@ -71,7 +71,7 @@
 while(<DATA>)
 {
 	chomp;
-	if(/^\^7([a-z0-9_]*) is "(.*?)" \["(.*?)"\] (.*)$/)
+	if(/^(?:\^7)?([a-z0-9_]*) is "(.*?)" \["(.*?)"\] (.*)$/)
 	{
 		my ($cvar, $value, $default, $description) = ($1, $2, $3, $4);
 		if($cvar =~ /^$ignore_re$/)
@@ -94,7 +94,33 @@
 }
 
 __DATA__
-====== Log started (Mon Sep 29 13:10:47 2008) ======
+List made using:
+nexuiz-dedicated +sys_colortranslation 2 +sys_specialcharactertranslation 0 +cvarlist +quit
+
+Nexuiz Linux 21:05:53 Oct 10 2008 8527 debug
+Trying to load library... "libz.so.1" - loaded.
+Added packfile data/common-spog.pk3 (26 files)
+Trying to load library... "libcurl.so.4" "libcurl.so.3" - loaded.
+execing quake.rc
+execing default.cfg
+execing defaultNexuiz.cfg
+Warning: Could not expand $qport in alias if_dedicated
+execing physicsQBR.cfg
+execing newhook.cfg
+execing ctfscoring-nex242.cfg
+execing weapons.cfg
+execing normal.cfg
+Warning: Could not expand $r_showsurfaces
+Warning: Could not expand $gl_finish
+Warning: Could not expand $v_kicktime
+couldn't exec config.cfg
+execing config_update.cfg
+Warning: Could not expand $v_hwgamma in alias _update_configversion_0
+Warning: Could not expand $r_glsl_contrastboost in alias _update_configversion_0
+Warning: Could not expand $r_glsl_contrastboost in alias _update_0_r_glsl_cb_1
+Ignore the error message above, the check works fine otherwise 
+couldn't exec data/campaign.cfg
+couldn't exec autoexec.cfg
 ^7_alientrap_net_banlist is "" [""] custom cvar
 ^7_backup_con_chatvars_set is "0" ["0"] custom cvar
 ^7_cl_color is "102" ["102"] internal storage cvar for current player colors (changed by color command)
@@ -103,7 +129,6 @@
 ^7_cl_playerskin is "0" ["0"] internal storage cvar for current player skin in Nexuiz (changed by playerskin command)
 ^7_cl_rate is "20000" ["20000"] internal storage cvar for current rate (changed by rate command)
 ^7_supports_weaponpriority is "0" ["0"] custom cvar
-^7_sv_init is "0" ["1"] custom cvar
 ^7_update_0_have_r_glsl_cb is "1" ["1"] custom cvar
 ^7bot_ai_aimskill_blendrate is "2" ["2"] custom cvar
 ^7bot_ai_aimskill_firetolerance_distdegrees is "180" ["180"] custom cvar
@@ -163,6 +188,14 @@
 ^7cl_playerdetailreduction is "0" ["0"] custom cvar
 ^7cl_port is "0" ["0"] forces client to use chosen port number if not 0
 ^7cl_shownames is "1" ["1"] custom cvar
+^7cl_teamradar is "1" ["1"] custom cvar
+^7cl_teamradar_background_alpha is "0.4" ["0.4"] custom cvar
+^7cl_teamradar_foreground_alpha is "0.8" ["0.8"] custom cvar
+^7cl_teamradar_position is "0 0" ["0 0"] custom cvar
+^7cl_teamradar_rotation is "0" ["0"] custom cvar
+^7cl_teamradar_scale is "4096" ["4096"] custom cvar
+^7cl_teamradar_size is "128 128" ["128 128"] custom cvar
+^7cl_teamradar_zoommode is "0" ["0"] custom cvar
 ^7cl_weaponpriority is "10 9 8 11 7 6 5 4 3 2 1" ["10 9 8 11 7 6 5 4 3 2 1"] custom cvar
 ^7cl_weaponpriority0 is "9 8 4" ["9 8 4"] custom cvar
 ^7cl_weaponpriority1 is "7 6 5 1" ["7 6 5 1"] custom cvar
@@ -178,7 +211,7 @@
 ^7cl_zoomfactor is "5" ["5"] custom cvar
 ^7cl_zoomsensitivity is "0" ["0"] custom cvar
 ^7cl_zoomspeed is "3.5" ["3.5"] custom cvar
-^7cmdline is "/nexuiz/haggerCTF/Nexuiz/darkplaces/nexuiz-dedicated " ["/nexuiz/haggerCTF/Nexuiz/darkplaces/nexuiz-dedicated "] contains commandline the engine was launched with
+^7cmdline is "/nexuiz/haggerCTF/Nexuiz/darkplaces/nexuiz-dedicated +sys_colortranslation 2 +sys_specialcharactertranslation 0 +cvarlist +quit " ["/nexuiz/haggerCTF/Nexuiz/darkplaces/nexuiz-dedicated +sys_colortranslation 2 +sys_specialcharactertranslation 0 +cvarlist +quit "] contains commandline the engine was launched with
 ^7collision_endnudge is "0" ["0"] how much to bias collision trace end
 ^7collision_enternudge is "0" ["0"] how much to bias collision entry fraction
 ^7collision_impactnudge is "0.03125" ["0.03125"] how much to back off from the impact
@@ -222,7 +255,7 @@
 ^7developer_networking is "0" ["0"] prints all received and sent packets (recommended only for debugging)
 ^7edgefriction is "1" ["1"] how much you slow down when nearing a ledge you might fall off
 ^7ekg is "0" ["0"] custom cvar
-^7fraglimit is "30" ["0"] ends level if this many frags is reached by any player
+^7fraglimit is "0" ["0"] ends level if this many frags is reached by any player
 ^7fraglimit_override is "-1" ["-1"] custom cvar
 ^7fs_empty_files_in_pack_mark_deletions is "1" ["1"] if enabled, empty files in a pak/pk3 count as not existing but cancel the search in further packs, effectively allowing patch pak/pk3 files to 'delete' files
 ^7g_antilag is "1" ["1"] custom cvar
@@ -275,6 +308,8 @@
 ^7g_balance_crylink_secondary_shots is "7" ["7"] custom cvar
 ^7g_balance_crylink_secondary_speed is "7000" ["7000"] custom cvar
 ^7g_balance_crylink_secondary_spread is "0.08" ["0.08"] custom cvar
+^7g_balance_ctf_damageforcescale is "1" ["1"] custom cvar
+^7g_balance_ctf_delay_collect is "1.0" ["1.0"] custom cvar
 ^7g_balance_curse_empathy_minhealth is "20" ["20"] custom cvar
 ^7g_balance_curse_empathy_takedamage is "-0.4" ["-0.4"] custom cvar
 ^7g_balance_curse_slow_atkrate is "1.5" ["1.5"] custom cvar
@@ -428,6 +463,8 @@
 ^7g_balance_pause_health_regen_spawn is "0" ["0"] custom cvar
 ^7g_balance_pause_health_rot is "5" ["5"] custom cvar
 ^7g_balance_pause_health_rot_spawn is "10" ["10"] custom cvar
+^7g_balance_portal_health is "200" ["200"] custom cvar
+^7g_balance_portal_lifetime is "15" ["15"] custom cvar
 ^7g_balance_porto_primary_ammo is "25" ["25"] custom cvar
 ^7g_balance_porto_primary_lifetime is "30" ["30"] custom cvar
 ^7g_balance_porto_primary_refire is "1.5" ["1.5"] custom cvar
@@ -532,21 +569,37 @@
 ^7g_cloaked is "0" ["0"] custom cvar
 ^7g_configversion is "1" ["0"] custom cvar
 ^7g_ctf is "0" ["0"] custom cvar
+^7g_ctf_allow_drop is "0" ["0"] custom cvar
 ^7g_ctf_capture_limit is "-1" ["-1"] custom cvar
 ^7g_ctf_flag_returntime is "30" ["30"] custom cvar
 ^7g_ctf_flagcarrier_selfdamage is "1" ["1"] custom cvar
 ^7g_ctf_flagcarrier_selfforce is "1" ["1"] custom cvar
 ^7g_ctf_flagpenalty_drop is "0" ["0"] custom cvar
+^7g_ctf_flagpenalty_returned is "0" ["0"] custom cvar
 ^7g_ctf_flagpenalty_suicidedrop is "1" ["1"] custom cvar
 ^7g_ctf_flagscore_capture is "20" ["20"] custom cvar
 ^7g_ctf_flagscore_kill is "1" ["1"] custom cvar
 ^7g_ctf_flagscore_pickup_base is "1" ["1"] custom cvar
 ^7g_ctf_flagscore_pickup_dropped_early is "1" ["1"] custom cvar
-^7g_ctf_flagscore_pickup_dropped_late is "5" ["5"] custom cvar
+^7g_ctf_flagscore_pickup_dropped_late is "1" ["1"] custom cvar
 ^7g_ctf_flagscore_return is "5" ["5"] custom cvar
 ^7g_ctf_flagscore_return_by_killer is "5" ["5"] custom cvar
 ^7g_ctf_flagscore_return_rogue is "10" ["10"] custom cvar
 ^7g_ctf_flagscore_return_rogue_by_killer is "10" ["10"] custom cvar
+^7g_ctf_fullbrightflags is "1" ["1"] custom cvar
+^7g_ctf_ignore_frags is "0" ["0"] custom cvar
+^7g_ctf_personalpenalty_drop is "0" ["0"] custom cvar
+^7g_ctf_personalpenalty_returned is "0" ["0"] custom cvar
+^7g_ctf_personalpenalty_suicidedrop is "1" ["1"] custom cvar
+^7g_ctf_personalscore_capture is "20" ["20"] custom cvar
+^7g_ctf_personalscore_kill is "1" ["1"] custom cvar
+^7g_ctf_personalscore_pickup_base is "1" ["1"] custom cvar
+^7g_ctf_personalscore_pickup_dropped_early is "1" ["1"] custom cvar
+^7g_ctf_personalscore_pickup_dropped_late is "1" ["1"] custom cvar
+^7g_ctf_personalscore_return is "5" ["5"] custom cvar
+^7g_ctf_personalscore_return_by_killer is "5" ["5"] custom cvar
+^7g_ctf_personalscore_return_rogue is "10" ["10"] custom cvar
+^7g_ctf_personalscore_return_rogue_by_killer is "10" ["10"] custom cvar
 ^7g_ctf_respawn_delay is "0" ["0"] custom cvar
 ^7g_ctf_respawn_waves is "0" ["0"] custom cvar
 ^7g_ctf_win_mode is "2" ["2"] custom cvar
@@ -593,10 +646,10 @@
 ^7g_lms_start_ammo_shells is "50" ["50"] custom cvar
 ^7g_lms_start_armor is "100" ["100"] custom cvar
 ^7g_lms_start_health is "250" ["250"] custom cvar
-^7g_maplist is "silvercity soylent basement basementctf toxic skyway slimepit ruiner starship runningman bloodprison farewell darkzone strength aneurysm final_rage bloodprisonctf warfare dismal reslimed runningman_1on1remix stormkeep bluesky aggressor bleach dieselpower evilspace runningmanctf downer" ["aggressor aneurysm basement basementctf bleach bloodprison bloodprisonctf bluesky darkzone dieselpower dismal downer evilspace farewell final_rage reslimed ruiner runningman_1on1remix runningman runningmanctf silvercity skyway slimepit soylent starship stormkeep strength toxic warfare"] custom cvar
+^7g_maplist is "aggressor aneurysm basement basementctf bleach bloodprison bloodprisonctf bluesky darkzone dieselpower dismal downer evilspace farewell final_rage reslimed ruiner runningman_1on1remix runningman runningmanctf silvercity skyway slimepit soylent starship stormkeep strength toxic warfare" ["aggressor aneurysm basement basementctf bleach bloodprison bloodprisonctf bluesky darkzone dieselpower dismal downer evilspace farewell final_rage reslimed ruiner runningman_1on1remix runningman runningmanctf silvercity skyway slimepit soylent starship stormkeep strength toxic warfare"] custom cvar
 ^7g_maplist_check_waypoints is "0" ["0"] custom cvar
 ^7g_maplist_index is "0" ["0"] custom cvar
-^7g_maplist_mostrecent is "silvercity " [""] custom cvar
+^7g_maplist_mostrecent is "" [""] custom cvar
 ^7g_maplist_mostrecent_count is "3" ["3"] custom cvar
 ^7g_maplist_selectrandom is "0" ["0"] custom cvar
 ^7g_maplist_shuffle is "1" ["1"] custom cvar
@@ -737,6 +790,7 @@
 ^7g_waypointsprite_minalpha is "0.4" ["0.4"] custom cvar
 ^7g_waypointsprite_minscale is "1" ["1"] custom cvar
 ^7g_waypointsprite_normdistance is "512" ["512"] custom cvar
+^7g_waypointsprite_scale is "1" ["1"] custom cvar
 ^7g_waypointsprite_stuffbinds is "0" ["0"] custom cvar
 ^7g_waypointsprite_timealphaexponent is "1" ["1"] custom cvar
 ^7g_weapon_stay is "0" ["0"] custom cvar
@@ -775,7 +829,7 @@
 ^7joyyawsensitivity is "-1.8" ["-1.8"] custom cvar
 ^7lastlevel is "" [""] custom cvar
 ^7log_dest_udp is "" [""] UDP address to log messages to (in QW rcon compatible format); multiple destinations can be separated by spaces; DO NOT SPECIFY DNS NAMES HERE
-^7log_file is "x" [""] filename to log messages to
+^7log_file is "" [""] filename to log messages to
 ^7menu_cdtrack is "digital-pursuit" ["digital-pursuit"] custom cvar
 ^7menu_maxplayers is "8" ["8"] custom cvar
 ^7menu_mouse_absolute is "0" ["0"] custom cvar
@@ -1014,8 +1068,8 @@
 ^7sv_wateraccelerate is "-1" ["-1"] rate at which a player accelerates to sv_maxspeed while in the air, if less than 0 the sv_accelerate variable is used instead
 ^7sv_waterfriction is "-1" ["-1"] how fast you slow down, if less than 0 the sv_friction variable is used instead
 ^7sv_writepicture_quality is "10" ["10"] WritePicture quality offset (higher means better quality, but slower)
-^7sys_colortranslation is "1" ["1"] terminal console color translation (supported values: 0 = strip color codes, 1 = translate to ANSI codes, 2 = no translation)
-^7sys_specialcharactertranslation is "1" ["1"] terminal console conchars to ASCII translation (set to 0 if your conchars.tga is for an 8bit character set or if you want raw output)
+^7sys_colortranslation is "2" ["1"] terminal console color translation (supported values: 0 = strip color codes, 1 = translate to ANSI codes, 2 = no translation)
+^7sys_specialcharactertranslation is "0" ["1"] terminal console conchars to ASCII translation (set to 0 if your conchars.tga is for an 8bit character set or if you want raw output)
 ^7sys_ticrate is "0.05" ["0.05"] how long a server frame is in seconds, 0.05 is 20fps server rate, 0.1 is 10fps (can not be set higher than 0.1), 0 runs as many server frames as possible (makes games against bots a little smoother, overwhelms network players), 0.0138889 matches QuakeWorld physics
 ^7sys_useclockgettime is "0" ["0"] use POSIX clock_gettime function (which has issues if the system clock speed is far off, as it can't get fixed by NTP) for timing rather than gettimeofday (which has issues if the system time is stepped by ntpdate, or apparently on some Xen installations)
 ^7sys_usenoclockbutbenchmark is "0" ["0"] don't use ANY real timing, and simulate a clock (for benchmarking); the game then runs as fast as possible. Run a QC mod with bots that does some stuff, then does a quit at the end, to benchmark a server. NEVER do this on a public server.
@@ -1132,5 +1186,4 @@
 ^7v_kicktime is "$v_kicktime" ["$v_kicktime"] custom cvar
 ^7vid_x11_display is "" [""] custom cvar
 ^7welcome_message_time is "8" ["8"] custom cvar
-^71038 cvar(s)
-====== Log stopped (Mon Sep 29 13:10:51 2008) ======
+^71065 cvar(s)

Modified: branches/nexuiz-2.0/data/defaultNexuiz.cfg
===================================================================
--- branches/nexuiz-2.0/data/defaultNexuiz.cfg	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/defaultNexuiz.cfg	2008-10-11 15:11:15 UTC (rev 4731)
@@ -319,7 +319,7 @@
 
 alias clearmap	"disconnect"
 
-seta g_grappling_hook 0
+set g_grappling_hook 0
 set g_balance_grapplehook_health 130
 exec newhook.cfg
 
@@ -333,7 +333,8 @@
 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, 3: points only, but no frags included
+seta g_ctf_win_mode 2 // 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
 set g_spawn_furthest 0.5
@@ -389,6 +390,10 @@
 set g_ctf_flag_returntime 30
 set g_ctf_flagcarrier_selfdamage 1
 set g_ctf_flagcarrier_selfforce 1
+set g_ctf_fullbrightflags 1
+set g_ctf_allow_drop 0 // dropping allows circumventing carrierkill score, so enable this with care!
+set g_balance_ctf_delay_collect 1.0
+set g_balance_ctf_damageforcescale 1
                                                
 exec ctfscoring-nex242.cfg
 
@@ -1145,7 +1150,8 @@
 r_subdivisions_tolerance 1000000
 
 seta cl_teamradar 1
-seta cl_teamradar_background_alpha 0.25 // set to -1 to disable
+seta cl_teamradar_background_alpha 0.4 // set to -1 to disable
+seta cl_teamradar_foreground_alpha 0.8 // alpha of the map
 seta cl_teamradar_scale 4096
 seta cl_teamradar_rotation 0 // rotation mode: you set what points up. 0 = player, 1 = west, 2 = south, 3 = east, 4 = north
 seta cl_teamradar_size "128 128"

Modified: branches/nexuiz-2.0/data/effectinfo.txt
===================================================================
--- branches/nexuiz-2.0/data/effectinfo.txt	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/effectinfo.txt	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1241,10 +1241,54 @@
 
 
 
-// grenade/hagar trail
+// hagar trail
 // smoke
 effect TR_GRENADE
+trailspacing 6
+type alphastatic
+color 0x303030 0x000000
+tex 0 8
+size 1 2
+bounce 1
+sizeincrease 2
+alpha 100 200 280
+originjitter 1 1 1
+velocityjitter 1 1 1
+velocitymultiplier -0.02
+//gravity -0.11
+// fire
+effect TR_GRENADE
 notunderwater
+trailspacing 2
+type static
+color 0xffdf72 0x811200
+tex 48 55
+size 1 2
+sizeincrease -15
+alpha 100 144 988
+airfriction 8
+velocityjitter 32 32 32
+velocitymultiplier -1.0
+// bubbles
+effect TR_GRENADE
+underwater
+trailspacing 8
+type bubble
+tex 62 62
+color 0x404040 0x808080
+size 1 1
+alpha 256 256 256
+gravity -0.125
+bounce 1.5
+liquidfriction 4
+velocityjitter 16 16 16
+
+
+
+// mortar trail
+// smoke
+effect TR_KNIGHTSPIKE // used for MF_TRACER2
+notunderwater
 trailspacing 5
 type alphastatic
 color 0x303030 0x000000
@@ -1258,7 +1302,7 @@
 velocitymultiplier -0.02
 gravity -0.11
 //marker
-effect TR_GRENADE
+effect TR_KNIGHTSPIKE // used for MF_TRACER2
 type alphastatic
 color 0xFF0000 0xFF0000
 tex 62 62
@@ -1267,7 +1311,7 @@
 trailspacing 1
 alpha 256 256 720
 // bubbles
-effect TR_GRENADE
+effect TR_KNIGHTSPIKE // used for MF_TRACER2
 underwater
 trailspacing 16
 type bubble
@@ -2045,15 +2089,15 @@
 count 28
 type smoke
 tex 48 55
-color 0x8f0d00 0xfffde4
+color 0xea691b 0xeed05a
 size 33 44
-sizeincrease 45
+sizeincrease 55
 alpha 200 256 612
-bounce 1.5
+bounce 2.5
 airfriction 19
 liquidfriction 19
 originjitter 8 8 8
-velocityjitter 812 812 812
+velocityjitter 912 912 912
 // smoke
 effect rocket_explode
 type alphastatic
@@ -2087,9 +2131,9 @@
 count 64
 type spark
 tex 40 40
-color 0x903010 0xFFD030
-size 2 2
-sizeincrease 5
+color 0xffa800 0xffedaf
+size 1 1
+sizeincrease 2
 alpha 44 256 384
 gravity 1
 airfriction -1
@@ -2097,7 +2141,7 @@
 liquidfriction 0.8
 velocityoffset 0 0 80
 originjitter 16 16 16
-velocityjitter 284 284 384
+velocityjitter 224 224 324
 
 
 

Modified: branches/nexuiz-2.0/data/nexuiz-credits.txt
===================================================================
--- branches/nexuiz-2.0/data/nexuiz-credits.txt	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/nexuiz-credits.txt	2008-10-11 15:11:15 UTC (rev 4731)
@@ -10,7 +10,7 @@
 *Project Maintainer
 
 Rudolf "div0" Polzer
-* Programmer
+*Programmer
 
 
 
@@ -28,8 +28,17 @@
 Paul "Strahlemann" Evers
 *Level Designer
 
+Wolfgang "Blub\0" Bumiller
+*Programmer
 
+Tyler "-z-" Mulligan
+*Web Developer and Interaction Designer
 
+Michael "Tenshihan" Quinn
+*Sound FX
+
+
+
 **Past Team Members
 *In alphabetical order
 *(nickname or surname)
@@ -58,9 +67,6 @@
 Gottfried "Toddd" Hofmann
 *Sound FX
 
-Tenshihan
-*Sound FX
-
 Marko "Urre" Permanto
 *Bot Programmer
 
@@ -78,7 +84,6 @@
 Braden "meoblast001" Walters - Music
 Amos "torus" Dudley - Announcer voices
 William "Willis" Weilep - Master server host
-Tyler "-z-" Mulligan - Site Design
 "sev" - "Wicked" menu skins
 
 Qantourisc
@@ -124,6 +129,5 @@
 Netzwerg
 Ulrich Galbraith
 Christian Ice
-Wolfgang "Blub\0" Bumiller
 FruitieX
 Edward "Ed" Holness

Modified: branches/nexuiz-2.0/data/particles/particlefont.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/qcsrc/client/Main.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/Main.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/client/Main.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -253,7 +253,7 @@
 	float argc;
 	// Tokenize String
 	//argc = tokenize(strMessage);
-	argc = tokenizebyseparator(strMessage, " ");
+	argc = tokenize_sane(strMessage);
 	
 	// Acquire Command
 	local string strCmd;
@@ -305,7 +305,7 @@
 float GameCommand(string msg)
 {
 	float argc;
-	argc = tokenize(msg);
+	argc = tokenize_sane(msg);
 	string cmd;
 	cmd = argv(0);
 	if(cmd == "mv_download") {
@@ -879,7 +879,7 @@
 	{
 		if (!keys) 
 		{
-			n = tokenize(findkeysforcommand(command));
+			n = tokenize_insane(findkeysforcommand(command)); // uses '...' strings
 			for(j = 0; j < n; ++j)
 			{
 				k = stof(argv(j));

Modified: branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -168,7 +168,7 @@
 const float DRAWFLAG_ADDITIVE = 1;
 const float DRAWFLAG_MODULATE = 2;
 const float DRAWFLAG_2XMODULATE = 3;
-const float DRAWFLAG_NUMFLAGS = 4;
+const float DRAWFLAG_SCREEN = 4;
 const float DRAWFLAG_MIPMAP = 0x100; // only for R_BeginPolygon
 
 #define        SOLID_NOT                               0               // no interaction with other objects

Modified: branches/nexuiz-2.0/data/qcsrc/client/mapvoting.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/mapvoting.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/client/mapvoting.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -242,7 +242,7 @@
 	}
 	else
 	{
-		Cmd_MapVote_MapDownload(tokenize(strcat("mv_download ", ftos(id))));
+		Cmd_MapVote_MapDownload(tokenize_sane(strcat("mv_download ", ftos(id))));
 	}
 }
 

Modified: branches/nexuiz-2.0/data/qcsrc/client/progs.src
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/progs.src	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/client/progs.src	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1,14 +1,14 @@
 ../../csprogs.dat
 pre.qh
 
+../common/util-pre.qh
 Defs.qc
 csqc_constants.qc
 ../common/constants.qh
-
 csqc_builtins.qc
+../common/util.qh
 
 ../common/mapinfo.qh
-../common/util.qh
 interpolate.qh
 teamradar.qh
 waypointsprites.qh

Modified: branches/nexuiz-2.0/data/qcsrc/client/sbar.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/sbar.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/client/sbar.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -920,13 +920,26 @@
 		{
 			if(tl > 0)
 				str = strcat(str, " or");
-			str = strcat(str, " until ^3", ScoreString(scores_flags[ps_primary], fl));
-			if(scores_label[ps_primary] == "score")
-				str = strcat(str, " points^7");
-			else if(scores_label[ps_primary] == "fastest")
-				str = strcat(str, " is beaten^7");
+			if(teamplay)
+			{
+				str = strcat(str, " until ^3", ScoreString(teamscores_flags[ts_primary], fl));
+				if(teamscores_label[ts_primary] == "score")
+					str = strcat(str, " points^7");
+				else if(teamscores_label[ts_primary] == "fastest")
+					str = strcat(str, " is beaten^7");
+				else
+					str = strcat(str, " ", teamscores_label[ts_primary]);
+			}
 			else
-				str = strcat(str, " ", scores_label[ps_primary]);
+			{
+				str = strcat(str, " until ^3", ScoreString(scores_flags[ps_primary], fl));
+				if(scores_label[ps_primary] == "score")
+					str = strcat(str, " points^7");
+				else if(scores_label[ps_primary] == "fastest")
+					str = strcat(str, " is beaten^7");
+				else
+					str = strcat(str, " ", scores_label[ps_primary]);
+			}
 		}
 	}
 	
@@ -1383,15 +1396,26 @@
 			s = strcat("^1Press ^3", getcommandkey("jump", "+jump"), "^1 to join");
 		o = Sbar_DrawNoteLine(o, s);
 	}
+
+	string blinkcolor;
+	if(mod(time, 1) >= 0.5)
+		blinkcolor = "^1";
+	else
+		blinkcolor = "^3";
 		
+	if(warmup_stage)
+	{
+		s = "^2Currently in ^1warmup^2 stage!";
+		o = Sbar_DrawNoteLine(o, s);
+	}
 	if(ready_waiting)
 	{
 		if(ready_waiting_for_me)
 		{
 			if(warmup_stage) 
-				s = strcat("^2Press ^3", getcommandkey("ready", "ready"), "^2 to end warmup");
+				s = strcat(blinkcolor, "Press ^3", getcommandkey("ready", "ready"), blinkcolor, " to end warmup");
 			else
-				s = strcat("^2Press ^3", getcommandkey("ready", "ready"), "^2 once you are ready");
+				s = strcat(blinkcolor, "Press ^3", getcommandkey("ready", "ready"), blinkcolor, " once you are ready");
 		}
 		else
 		{
@@ -1402,6 +1426,11 @@
 		}
 		o = Sbar_DrawNoteLine(o, s);
 	}
+	else if(warmup_stage) 
+	{
+		s = strcat("^2Press ^3", getcommandkey("ready", "ready"), "^2 to end warmup");
+		o = Sbar_DrawNoteLine(o, s);
+	}
 	if(vote_waiting)
 	{
 		s = strcat("^2A vote has been called for ^1", vote_called_vote);
@@ -1409,13 +1438,13 @@
 
 		if(vote_waiting_for_me)
 		{
-			s = strcat("^2Press ^3", getcommandkey("vote yes", "vyes"), "^2 to accept");
+			s = strcat(blinkcolor, "Press ^3", getcommandkey("vote yes", "vyes"), blinkcolor, " to accept");
 			o = Sbar_DrawNoteLine(o, s);
 
-			s = strcat("^2Press ^3", getcommandkey("vote no", "vno"), "^2 to reject");
+			s = strcat(blinkcolor, "Press ^3", getcommandkey("vote no", "vno"), blinkcolor, " to reject");
 			o = Sbar_DrawNoteLine(o, s);
 
-			s = strcat("^2Press ^3", getcommandkey("vote abstain", "vabstain"), "^2 to abstain");
+			s = strcat(blinkcolor, "Press ^3", getcommandkey("vote abstain", "vabstain"), blinkcolor, " to abstain");
 			o = Sbar_DrawNoteLine(o, s);
 		}
 		else

Modified: branches/nexuiz-2.0/data/qcsrc/client/teamradar.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/teamradar.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/client/teamradar.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -43,27 +43,30 @@
 	return v;
 }
 
-void draw_teamradar_background(float a)
+void draw_teamradar_background(float bg, float fg)
 {
-	if(a <= 0)
-		return;
+	if(bg > 0)
+	{
+		R_BeginPolygon("", 0);
+		R_PolygonVertex('1 0 0' * (teamradar_origin2d_x - teamradar_size2d_x * 0.5) + '0 1 0' * (teamradar_origin2d_y - teamradar_size2d_y * 0.5), '0 0 0', '0 0 0', bg);
+		R_PolygonVertex('1 0 0' * (teamradar_origin2d_x + teamradar_size2d_x * 0.5) + '0 1 0' * (teamradar_origin2d_y - teamradar_size2d_y * 0.5), '0 0 0', '0 0 0', bg);
+		R_PolygonVertex('1 0 0' * (teamradar_origin2d_x + teamradar_size2d_x * 0.5) + '0 1 0' * (teamradar_origin2d_y + teamradar_size2d_y * 0.5), '0 0 0', '0 0 0', bg);
+		R_PolygonVertex('1 0 0' * (teamradar_origin2d_x - teamradar_size2d_x * 0.5) + '0 1 0' * (teamradar_origin2d_y + teamradar_size2d_y * 0.5), '0 0 0', '0 0 0', bg);
+		R_EndPolygon();
+	}
 
-	R_BeginPolygon("", 0);
-	R_PolygonVertex('1 0 0' * (teamradar_origin2d_x - teamradar_size2d_x * 0.5) + '0 1 0' * (teamradar_origin2d_y - teamradar_size2d_y * 0.5), '0 0 0', '0 0 0', a);
-	R_PolygonVertex('1 0 0' * (teamradar_origin2d_x + teamradar_size2d_x * 0.5) + '0 1 0' * (teamradar_origin2d_y - teamradar_size2d_y * 0.5), '0 0 0', '0 0 0', a);
-	R_PolygonVertex('1 0 0' * (teamradar_origin2d_x + teamradar_size2d_x * 0.5) + '0 1 0' * (teamradar_origin2d_y + teamradar_size2d_y * 0.5), '0 0 0', '0 0 0', a);
-	R_PolygonVertex('1 0 0' * (teamradar_origin2d_x - teamradar_size2d_x * 0.5) + '0 1 0' * (teamradar_origin2d_y + teamradar_size2d_y * 0.5), '0 0 0', '0 0 0', a);
-	R_EndPolygon();
-
-	if(csqc_flags & CSQC_FLAG_READPICTURE) // not 2.4.2
-		R_BeginPolygon(minimapname, DRAWFLAG_ADDITIVE | DRAWFLAG_MIPMAP);
-	else
-		R_BeginPolygon(minimapname, DRAWFLAG_ADDITIVE);
-	R_PolygonVertex(teamradar_texcoord_to_2dcoord(mi_pictexcoord0), yinvert(mi_pictexcoord0), '1 1 1', 1);
-	R_PolygonVertex(teamradar_texcoord_to_2dcoord(mi_pictexcoord1), yinvert(mi_pictexcoord1), '1 1 1', 1);
-	R_PolygonVertex(teamradar_texcoord_to_2dcoord(mi_pictexcoord2), yinvert(mi_pictexcoord2), '1 1 1', 1);
-	R_PolygonVertex(teamradar_texcoord_to_2dcoord(mi_pictexcoord3), yinvert(mi_pictexcoord3), '1 1 1', 1);
-	R_EndPolygon();
+	if(fg > 0)
+	{
+		if(csqc_flags & CSQC_FLAG_READPICTURE) // not 2.4.2
+			R_BeginPolygon(minimapname, DRAWFLAG_SCREEN | DRAWFLAG_MIPMAP);
+		else
+			R_BeginPolygon(minimapname, DRAWFLAG_ADDITIVE);
+		R_PolygonVertex(teamradar_texcoord_to_2dcoord(mi_pictexcoord0), yinvert(mi_pictexcoord0), '1 1 1', fg);
+		R_PolygonVertex(teamradar_texcoord_to_2dcoord(mi_pictexcoord1), yinvert(mi_pictexcoord1), '1 1 1', fg);
+		R_PolygonVertex(teamradar_texcoord_to_2dcoord(mi_pictexcoord2), yinvert(mi_pictexcoord2), '1 1 1', fg);
+		R_PolygonVertex(teamradar_texcoord_to_2dcoord(mi_pictexcoord3), yinvert(mi_pictexcoord3), '1 1 1', fg);
+		R_EndPolygon();
+	}
 }
 
 void(vector coord3d, vector pangles, vector rgb) draw_teamradar_player =
@@ -118,6 +121,7 @@
 
 float cl_teamradar_scale;
 float cl_teamradar_background_alpha;
+float cl_teamradar_foreground_alpha;
 float cl_teamradar_rotation;
 vector cl_teamradar_size;
 vector cl_teamradar_position;
@@ -127,6 +131,7 @@
 {
 	cl_teamradar_scale = cvar("cl_teamradar_scale");
 	cl_teamradar_background_alpha = cvar("cl_teamradar_background_alpha");
+	cl_teamradar_foreground_alpha = cvar("cl_teamradar_foreground_alpha");
 	cl_teamradar_rotation = cvar("cl_teamradar_rotation");
 	cl_teamradar_size = stov(cvar_string("cl_teamradar_size"));
 	cl_teamradar_position = stov(cvar_string("cl_teamradar_position"));
@@ -135,7 +140,8 @@
 	// others default to 0
 	// match this to defaultNexuiz.cfg!
 	if(!cl_teamradar_scale) cl_teamradar_scale = 4096;
-	if(!cl_teamradar_background_alpha) cl_teamradar_background_alpha = 0.25;
+	if(!cl_teamradar_background_alpha) cl_teamradar_background_alpha = 0.4;
+	if(!cl_teamradar_foreground_alpha) cl_teamradar_foreground_alpha = 0.8;
 	if(!cl_teamradar_size_x) cl_teamradar_size_x = 128;
 	if(!cl_teamradar_size_y) cl_teamradar_size_y = cl_teamradar_size_x;
 
@@ -234,7 +240,7 @@
 		teamradar_size2d_y
 	);
 
-	draw_teamradar_background(cl_teamradar_background_alpha);
+	draw_teamradar_background(cl_teamradar_background_alpha, cl_teamradar_foreground_alpha);
 	for(tm = world; (tm = findflags(tm, teamradar_icon, 0xFFFFFF)); )
 		draw_teamradar_icon(tm.origin, tm.teamradar_icon, tm.teamradar_time, tm.teamradar_color, tm.alpha);
 	for(tm = world; (tm = find(tm, classname, "entcs_receiver")); )

Modified: branches/nexuiz-2.0/data/qcsrc/common/campaign_file.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/campaign_file.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/common/campaign_file.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -31,7 +31,7 @@
 				continue; // comment
 			if(lineno >= offset)
 			{
-				entlen = tokenize(l);
+				entlen = tokenize_insane(l); // using insane tokenizer for CSV
 
 #define CAMPAIGN_GETARG0                  if(i >= entlen)
 #define CAMPAIGN_GETARG1 CAMPAIGN_GETARG0     error("syntax error in campaign file: line has not enough fields");

Modified: branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -49,7 +49,7 @@
 	float argc;
 	float i, j, f, n;
 	string s, s2;
-	argc = tokenize(command);
+	argc = tokenize_sane(command);
 	if(argv(0) == "help")
 	{
 		print("  rpn EXPRESSION... - a RPN calculator.\n");
@@ -441,8 +441,8 @@
 					// s s2 union
 					s2 = rpn_pop();
 					s = rpn_get();
-					f = tokenize(s);
-					f2 = tokenize(strcat(s, " ", s2));
+					f = tokenize_sane(s);
+					f2 = tokenize_sane(strcat(s, " ", s2));
 					// tokens 0..(f-1) represent s
 					// tokens f..f2 represent s2
 					// UNION: add all tokens to s that are in s2 but not in s
@@ -459,13 +459,13 @@
 					if(substring(s, 0, 1) == " ")
 						s = substring(s, 1, 99999);
 					rpn_set(s);
-					tokenize(command);
+					tokenize_sane(command);
 				} else if(rpncmd == "intersection") {
 					// s s2 intersection
 					s2 = rpn_pop();
 					s = rpn_get();
-					f = tokenize(s);
-					f2 = tokenize(strcat(s, " ", s2));
+					f = tokenize_sane(s);
+					f2 = tokenize_sane(strcat(s, " ", s2));
 					// tokens 0..(f-1) represent s
 					// tokens f..f2 represent s2
 					// INTERSECTION: keep only the tokens from s that are also in s2
@@ -481,13 +481,13 @@
 					if(substring(s, 0, 1) == " ")
 						s = substring(s, 1, 99999);
 					rpn_set(s);
-					tokenize(command);
+					tokenize_sane(command);
 				} else if(rpncmd == "difference") {
 					// s s2 difference
 					s2 = rpn_pop();
 					s = rpn_get();
-					f = tokenize(s);
-					f2 = tokenize(strcat(s, " ", s2));
+					f = tokenize_sane(s);
+					f2 = tokenize_sane(strcat(s, " ", s2));
 					// tokens 0..(f-1) represent s
 					// tokens f..f2 represent s2
 					// DIFFERENCE: keep only the tokens from s that are not in s2
@@ -502,11 +502,11 @@
 					if(substring(s, 0, 1) == " ")
 						s = substring(s, 1, 99999);
 					rpn_set(s);
-					tokenize(command);
+					tokenize_sane(command);
 				} else if(rpncmd == "shuffle") {
 					// s shuffle
 					s = rpn_get();
-					f = tokenize(s);
+					f = tokenize_sane(s);
 
 					for(i = 0; i < f - 1; ++i) {
 						// move a random item from i..f-1 to position i
@@ -518,13 +518,13 @@
 						for(j = i; j < f; ++j)
 							if(j != f2)
 								s = strcat(s, " ", argv(j));
-						f = tokenize(s);
+						f = tokenize_sane(s);
 					}
 
 					if(substring(s, 0, 1) == " ")
 						s = substring(s, 1, 99999);
 					rpn_set(s);
-					tokenize(command);
+					tokenize_sane(command);
 					} else if(rpncmd == "fexists_assert") {
 					s = rpn_pop();
 					if(!rpn_error)

Copied: branches/nexuiz-2.0/data/qcsrc/common/util-pre.qh (from rev 4730, trunk/data/qcsrc/common/util-pre.qh)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/util-pre.qh	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/common/util-pre.qh	2008-10-11 15:11:15 UTC (rev 4731)
@@ -0,0 +1,3 @@
+#define tokenize DO_NOT_DEFINE_THIS_MONSTER_tokenize
+#define tokenizebyseparator DO_NOT_DEFINE_THIS_MONSTER_tokenizebyseparator
+#define argv DO_NOT_DEFINE_THIS_MONSTER_argv

Modified: branches/nexuiz-2.0/data/qcsrc/common/util.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/util.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/common/util.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -646,7 +646,7 @@
 	string neworder;
 	float i, n, w;
 
-	n = tokenize(order);
+	n = tokenize_sane(order);
 	for(i = 0; i < n; ++i)
 	{
 		w = stof(argv(i));
@@ -656,7 +656,7 @@
 
 	if(complete)
 	{
-		n = tokenize(neworder);
+		n = tokenize_sane(neworder);
 		for(w = to; w >= from; --w)
 		{
 			for(i = 0; i < n; ++i)
@@ -675,7 +675,7 @@
 	string s;
 	float w, n;
 
-	n = tokenize(order);
+	n = tokenize_sane(order);
 
 	if(i >= 0 && i < n && j >= 0 && j < n && i != j)
 	{
@@ -875,7 +875,7 @@
 {
 	// undo what cvar_settemp did
 	float n, i;
-	n = tokenize(cvar_string("settemp_list"));
+	n = tokenize_sane(cvar_string("settemp_list"));
 	for(i = 0; i < n - 3; i += 3)
 		cvar_set(argv(i + 1), cvar_string(argv(i + 2)));
 	cvar_set("settemp_list", "0");
@@ -893,5 +893,162 @@
 
 float almost_in_bounds(float a, float b, float c)
 {
-	return almost_equals(b, median(a, b, c));
+	float eps;
+	eps = (max(a, -a) + max(c, -c)) * 0.001;
+	return b == median(a - eps, b, c + eps);
 }
+
+
+
+#ifdef MENUQC
+float (string s) _tokenize_builtin = #58;
+string (float argnum) _argv_builtin = #59;
+float (string s, string sep) _tokenizebyseparator_builtin = #479;
+#else
+float (string s) _tokenize_builtin = #441;
+string (float argnum) _argv_builtin = #442;
+float (string s, string sep) _tokenizebyseparator_builtin = #479;
+#endif
+
+float MAX_TOKENS = 256;
+string _argv_sane_buffer[MAX_TOKENS];
+float _argv_sane_startpos[MAX_TOKENS];
+float _argv_sane_endpos[MAX_TOKENS];
+float _argc_sane;
+
+string _argv_sane(float i)
+{
+	// Perl-ish -1 for the last argument
+	if(i < 0)
+		i = _argc_sane + i;
+	return _argv_sane_buffer[i];
+}
+
+float _argv_start_index_sane(float i)
+{
+	// Perl-ish -1 for the last argument
+	if(i < 0)
+		i = _argc_sane + i;
+	return _argv_sane_startpos[i];
+}
+
+float _argv_end_index_sane(float i)
+{
+	// Perl-ish -1 for the last argument
+	if(i < 0)
+		i = _argc_sane + i;
+	return _argv_sane_endpos[i];
+}
+
+string TOKENIZE_SANE_WHITESPACE_CHARS = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
+string TOKENIZE_SANE_COMMENT_BREAKERS = "\x0d\x0a";
+// change this if DP changes its type to "char"!
+
+float _tokenize_sane(string s)
+{
+	// This MUST match COM_ParseToken_Console!
+	string com_token, tmp;
+	float data;
+	float end;
+	float i;
+	
+	_argc_sane = 0;
+	data = 0;
+	end = strlen(s);
+
+	for(i = 0; i < MAX_TOKENS; ++i)
+	{
+		if(_argv_sane_buffer[i])
+			strunzone(_argv_sane_buffer[i]);
+		_argv_sane_buffer[i] = string_null;
+		_argv_sane_startpos[i] = 0;
+	}
+
+	for(;;)
+	{
+		// skip whitespace
+		for(; data < end && strstrofs(TOKENIZE_SANE_WHITESPACE_CHARS, substring(s, data, 1), 0) >= 0; ++data)
+			;
+		if(data == end)
+			break;
+
+		if(substring(s, data, 2) == "//")
+		{
+			// comment
+
+			// Any call to the tokenizer ALREADY assumes it's a single line, so we can safely abort if we see a comment.
+			/*
+			data += 2;
+			while(data < end && strstrofs(TOKENIZE_SANE_COMMENT_BREAKERS, substring(s, data, 1), 0) >= 0)
+				++data;
+			continue; // go to skipwhite again
+			*/
+
+			// I'd like to simply put a "break" here, but then fteqcc says this function has unreachable code
+			return _argc_sane;
+		}
+		else if(substring(s, data, 1) == "\"")
+		{
+			// quoted string
+			com_token = "";
+			_argv_sane_startpos[_argc_sane] = data;
+			for(++data; data < end && substring(s, data, 1) != "\""; ++data)
+			{
+				// allow escaped " and \ case
+				tmp = substring(s, data, 2);
+				if(tmp == "\\\"" || tmp == "\\\\")
+					++data;
+				com_token = strcat(com_token, substring(s, data, 1));
+			}
+			if(substring(s, data, 1) == "\"")
+				++data;
+			_argv_sane_endpos[_argc_sane] = data;
+			_argv_sane_buffer[_argc_sane] = strzone(com_token);
+			++_argc_sane;
+		}
+		else
+		{
+			// regular word
+			com_token = "";
+			_argv_sane_startpos[_argc_sane] = data;
+			for(; data < end && strstrofs(TOKENIZE_SANE_WHITESPACE_CHARS, substring(s, data, 1), 0) < 0; ++data)
+				com_token = strcat(com_token, substring(s, data, 1));
+			_argv_sane_endpos[_argc_sane] = data;
+			_argv_sane_buffer[_argc_sane] = strzone(com_token);
+			++_argc_sane;
+		}
+	}
+
+	return _argc_sane;
+}
+
+
+
+var void(void) func_null;
+
+// "sane" tokenizer
+// matching the console 1:1
+
+float tokenize_sane(string s)
+{
+	argv = _argv_sane;
+	argv_start_index = _argv_start_index_sane;
+	argv_end_index = _argv_end_index_sane;
+	return _tokenize_sane(s);
+}
+
+float tokenize_insane(string s)
+{
+	argv = _argv_builtin;
+	argv_start_index = func_null;
+	argv_end_index = func_null;
+	return _tokenize_builtin(s);
+}
+
+float tokenizebyseparator(string s, string sep)
+{
+	argv = _argv_builtin;
+	argv_start_index = func_null;
+	argv_end_index = func_null;
+	return _tokenizebyseparator_builtin(s, sep);
+}

Modified: branches/nexuiz-2.0/data/qcsrc/common/util.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/util.qh	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/common/util.qh	2008-10-11 15:11:15 UTC (rev 4731)
@@ -105,3 +105,14 @@
 
 float almost_equals(float a, float b);
 float almost_in_bounds(float a, float b, float c);
+
+#undef tokenize
+#undef tokenizebyseparator
+#undef argv
+
+var string(float) argv;
+var float(float) argv_start_index;
+var float(float) argv_end_index;
+float tokenize_sane(string s);
+float tokenize_insane(string s);
+float tokenizebyseparator(string s, string sep);

Modified: branches/nexuiz-2.0/data/qcsrc/menu/gamecommand.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/gamecommand.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/menu/gamecommand.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -34,7 +34,7 @@
 void GameCommand(string theCommand)
 {
 	float argc;
-	argc = tokenize(theCommand);
+	argc = tokenize_sane(theCommand);
 
 	if(argv(0) == "help" || argc == 0)
 	{

Modified: branches/nexuiz-2.0/data/qcsrc/menu/menu.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/menu.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/menu/menu.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -82,8 +82,11 @@
 	}
 	draw_currentSkin = strzone(draw_currentSkin);
 	while((s = fgets(fh)))
-		if(tokenize(s) == 2)
-			Skin_ApplySetting(argv(0), argv(1));
+	{
+		n = tokenize_sane(s);
+		if(n >= 2)
+			Skin_ApplySetting(argv(0), substring(s, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)));
+	}
 	fclose(fh);
 
 	glob = search_begin(strcat(draw_currentSkin, "/*.tga"), TRUE, TRUE);

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup_radar.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup_radar.c	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup_radar.c	2008-10-11 15:11:15 UTC (rev 4731)
@@ -5,8 +5,8 @@
 	METHOD(NexuizRadarDialog, showNotify, void(entity))
 	ATTRIB(NexuizRadarDialog, title, string, "Radar & Waypoints")
 	ATTRIB(NexuizRadarDialog, color, vector, SKINCOLOR_DIALOG_RADAR)
-	ATTRIB(NexuizRadarDialog, intendedWidth, float, 0.6)
-	ATTRIB(NexuizRadarDialog, rows, float, 17)
+	ATTRIB(NexuizRadarDialog, intendedWidth, float, 0.7)
+	ATTRIB(NexuizRadarDialog, rows, float, 18)
 	ATTRIB(NexuizRadarDialog, columns, float, 4)
 ENDCLASS(NexuizRadarDialog)
 #endif
@@ -85,6 +85,10 @@
 		me.TDempty(me, 1);
 	me.TR(me);
 		me.TDempty(me, 0.2);
+		me.TD(me, 1, 0.8, e = makeNexuizTextLabel(0, "Foreground:"));
+		me.TD(me, 1, 3, makeNexuizSlider(0.1, 1.0, 0.01, "cl_teamradar_foreground_alpha"));
+	me.TR(me);
+		me.TDempty(me, 0.2);
 		sl = makeNexuizSlider(0.1, 1.0, 0.01, "cl_teamradar_background_alpha");
 		me.TD(me, 1, 0.8, e = makeNexuizSliderCheckBox(-1, 1, sl, "Background:"));
 		me.TD(me, 1, 3, sl);

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_singleplayer.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_singleplayer.c	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_singleplayer.c	2008-10-11 15:11:15 UTC (rev 4731)
@@ -28,7 +28,7 @@
 	{
 		if(substring(s, 0, 4) == "set ")
 			s = substring(s, 4, strlen(s) - 4);
-		n = tokenize(s);
+		n = tokenize_sane(s);
 		if(argv(0) == "bot_number")
 			cvar_set("bot_number", argv(1));
 		else if(argv(0) == "skill")

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/keybinder.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/keybinder.c	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/keybinder.c	2008-10-11 15:11:15 UTC (rev 4731)
@@ -50,7 +50,7 @@
 		return;
 	while((s = fgets(fh)))
 	{
-		if(tokenize(s) != 2)
+		if(tokenize_sane(s) != 2)
 			continue;
 		Nexuiz_KeyBinds_Functions[Nexuiz_KeyBinds_Count] = strzone(argv(0));
 		Nexuiz_KeyBinds_Descriptions[Nexuiz_KeyBinds_Count] = strzone(argv(1));
@@ -116,7 +116,7 @@
 	if(func == "")
 		return;
 
-	n = tokenize(findkeysforcommand(func));
+	n = tokenize_insane(findkeysforcommand(func)); // uses '...' strings
 	nvalid = 0;
 	for(j = 0; j < n; ++j)
 	{
@@ -186,7 +186,7 @@
 	if(func == "")
 		return;
 
-	n = tokenize(findkeysforcommand(func));
+	n = tokenize_insane(findkeysforcommand(func)); // uses '...' strings
 	for(j = 0; j < n; ++j)
 	{
 		k = stof(argv(j));
@@ -300,7 +300,7 @@
 	draw_Text(me.realUpperMargin * eY + extraMargin * eX, descr, me.realFontSize, theColor, theAlpha, 0);
 	if(func != "")
 	{
-		n = tokenize(findkeysforcommand(func));
+		n = tokenize_insane(findkeysforcommand(func)); // uses '...' strings
 		s = "";
 		for(j = 0; j < n; ++j)
 		{

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c	2008-10-11 15:11:15 UTC (rev 4731)
@@ -103,7 +103,7 @@
 	else
 	{
 		s = "";
-		n = tokenize(cvar_string("g_maplist"));
+		n = tokenize_sane(cvar_string("g_maplist"));
 		for(i = 0; i < n; ++i)
 			if(argv(i) != bspname)
 				s = strcat(s, " ", argv(i));
@@ -212,7 +212,7 @@
 	s = "0";
 	for(i = 1; i < MapInfo_count; i *= 2)
 		s = strcat(s, s);
-	n = tokenize(cvar_string("g_maplist"));
+	n = tokenize_sane(cvar_string("g_maplist"));
 	for(i = 0; i < n; ++i)
 	{
 		j = MapInfo_FindName(argv(i));

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/slider_resolution.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/slider_resolution.c	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/slider_resolution.c	2008-10-11 15:11:15 UTC (rev 4731)
@@ -47,7 +47,7 @@
 {
 	if(me.value >= 0 || me.value < me.nValues)
 	{
-		tokenize(me.getIdentifier(me));
+		tokenize_sane(me.getIdentifier(me));
 		cvar_set("vid_width", argv(0));
 		cvar_set("vid_height", argv(1));
 		cvar_set("vid_conwidth", argv(2));

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -36,7 +36,7 @@
 	me.saveCvars_Multi(me);
 	s = cvar_string(me.cvarName);
 
-	n = tokenize(me.cvarNames_Multi);
+	n = tokenize_sane(me.cvarNames_Multi);
 	for(i = 0; i < n; ++i)
 		cvar_set(argv(i), s);
 }
@@ -193,7 +193,7 @@
 	local float argc;
 	while(strlen((s = getextresponse())))
 	{
-		argc = tokenize(s);
+		argc = tokenize_sane(s);
 		Item_Nex_ExtResponseSystem_Parse(argc);
 	}
 }

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/weaponslist.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/weaponslist.c	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/weaponslist.c	2008-10-11 15:11:15 UTC (rev 4731)
@@ -40,7 +40,7 @@
 		print("AUTOFIXED\n");
 		cvar_set("cl_weaponpriority", t);
 	}
-	me.nItems = tokenize(t);
+	me.nItems = tokenize_sane(t);
 	drawListBox(me);
 }
 void WeaponsList_MoveUp_Click(entity box, entity me)
@@ -99,7 +99,7 @@
 {
 	float n, i;
 	string s;
-	n = tokenize(cvar_string("cl_weaponpriority"));
+	n = tokenize_sane(cvar_string("cl_weaponpriority"));
 	s = "";
 	for(i = 0; i < n; ++i)
 		s = strcat(s, WeaponName(stof(argv(i))), ", ");

Modified: branches/nexuiz-2.0/data/qcsrc/menu/progs.src
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/progs.src	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/menu/progs.src	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1,14 +1,15 @@
 ../../menu.dat
 
 config.qh
+../common/util-pre.qh
 msys.qh
 mbuiltin.qh
+../common/util.qh
 
 oo/base.h
 
 ../common/constants.qh
 ../common/mapinfo.qh
-../common/util.qh
 ../common/campaign_common.qh
 
 gamecommand.qh

Modified: branches/nexuiz-2.0/data/qcsrc/server/arena.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/arena.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/arena.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -64,11 +64,6 @@
 				DropAllRunes(self.owner);
 			rune_respawn();
 		}
-		else if(self.classname == "sprite_waypoint")
-		{
-			if(self.health | g_keyhunt)
-				WaypointSprite_Kill(self);
-		}
 		else if(self.classname == "dom_controlpoint")
 		{
 			dom_controlpoint_setup();
@@ -114,6 +109,14 @@
 		}
 	}
 
+	// Waypoints come LAST (keyhunt keys reference them)
+	for(self = world; (self = nextent(self)); )
+		if(self.classname == "sprite_waypoint")
+		{
+			if(self.health | g_keyhunt)
+				WaypointSprite_Kill(self);
+		}
+
 	// Moving the player reset code here since the player-reset depends
 	// on spawnpoint entities which have to be reset first --blub
 	FOR_EACH_CLIENT(self) {

Modified: branches/nexuiz-2.0/data/qcsrc/server/builtins.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/builtins.qh	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/builtins.qh	2008-10-11 15:11:15 UTC (rev 4731)
@@ -13,7 +13,7 @@
 float	vlen (vector v)									= #12;
 float	vectoyaw (vector v)								= #13;
 entity	spawn (void)									= #14;
-void	remove (entity e)								= #15;
+void	remove_builtin (entity e)								= #15;
 void	traceline (vector v1, vector v2, float nomonst, entity forent)			= #16;
 entity	checkclient (void)								= #17;
 entity	find (entity start, .string fld, string match)					= #18;
@@ -32,7 +32,7 @@
 void	eprint (entity e)								= #31;
 float	walkmove (float yaw, float dist)						= #32;
 
-float	droptofloor ()						= #34;
+float	droptofloor_builtin ()						= #34;
 void	lightstyle (float style, string value)						= #35;
 float	rint (float v)									= #36;
 float	floor (float v)									= #37;

Modified: branches/nexuiz-2.0/data/qcsrc/server/campaign.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/campaign.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/campaign.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -76,7 +76,7 @@
 	{
 		while((l = fgets(fh)))
 		{
-			len = tokenize(l);
+			len = tokenize_sane(l);
 			if(len != 3)
 				continue;
 			if(argv(0) != "set")

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -2368,4 +2368,6 @@
 	*/
 
 	Arena_Warmup();
+
+	//pointparticles(particleeffectnum("machinegun_impact"), self.origin + self.view_ofs + '0 0 7', '0 0 0', 1);
 }

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -74,7 +74,7 @@
 	if (animfile < 0)
 		return '0 1 2';
 	line = fgets(animfile);
-	c = tokenize(line);
+	c = tokenize_sane(line);
 	if (c != 3)
 	{
 		animparseerror = TRUE;
@@ -413,7 +413,7 @@
 					else
 						player_setanim(self.anim_pain2, FALSE, TRUE, TRUE);
 
-					if(deathtype != WEP_LASER || attacker != self || self.health < 2 * cvar("g_balance_laser_primary_damage") * cvar("g_balance_selfdamagepercent") + 1)
+					if(deathtype >= DEATH_SPECIAL_START || deathtype & DEATH_WEAPONMASK != WEP_LASER || attacker != self || self.health < 2 * cvar("g_balance_laser_primary_damage") * cvar("g_balance_selfdamagepercent") + 1)
 					// exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two
 					{
 						if(self.health > 75) // TODO make a "gentle" version?
@@ -496,7 +496,7 @@
 		// throw a weapon
 		SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon);
 		// print an obituary message
-		Obituary (attacker, self, deathtype);
+		Obituary (attacker, inflictor, self, deathtype);
 		race_PreDie();
 		DropAllRunes(self);
 		if(self == attacker)
@@ -802,7 +802,7 @@
 void PrecacheGlobalSound(string samplestring)
 {
 	float n, i;
-	tokenize(samplestring);
+	tokenize_sane(samplestring);
 	n = stof(argv(1));
 	if(n > 0)
 	{
@@ -824,7 +824,7 @@
 		return;
 	while((s = fgets(fh)))
 	{
-		if(tokenize(s) != 3)
+		if(tokenize_sane(s) != 3)
 		{
 			dprint("Invalid sound info line: ", s, "\n");
 			continue;
@@ -868,7 +868,7 @@
 		return;
 	while((s = fgets(fh)))
 	{
-		if(tokenize(s) != 3)
+		if(tokenize_sane(s) != 3)
 			continue;
 		field = GetPlayerSoundSampleField(argv(0));
 		if(GetPlayerSoundSampleField_notFound)
@@ -903,7 +903,7 @@
 	if(sample == "")
 		return;
 
-	tokenize(sample);
+	tokenize_sane(sample);
 	n = stof(argv(1));
 	if(n > 0)
 		sample = strcat(argv(0), ftos(ceil(random() * n)), ".wav"); // randomization

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -9,7 +9,7 @@
 float W_GetCycleWeapon(entity pl, string weaponorder, float dir, float imp, float complain)
 {
 	float n, i, weaponwant, first_valid, prev_valid, switchtonext, switchtolast;
-	n = tokenize(weaponorder);
+	n = tokenize_sane(weaponorder);
 	switchtonext = switchtolast = 0;
 	first_valid = prev_valid = 0;
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -225,7 +225,7 @@
 	local string cmd;
 	local float i;
 
-	tokenize(s);
+	tokenize_sane(s);
 
 	if(GameCommand_Vote(s, self)) {
 		return;
@@ -342,7 +342,7 @@
 	} else if(argv(0) == "maplist") {
 		local float n, j;
 		local string col;
-		n = tokenize(cvar_string("g_maplist"));
+		n = tokenize_sane(cvar_string("g_maplist"));
 		sprint(self, "^7Maps in list: ");
 		for(i = 0, j = 0; i < n; ++i)
 		{
@@ -371,10 +371,10 @@
 	} else if(argv(0) == "voice") {
 		VoiceMessage(argv(1));
 	} else if(argv(0) == "say") {
-		Say(self, FALSE, substring(s, 4, strlen(s) - 4));
+		Say(self, FALSE, substring(s, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)));
 		//clientcommand(self, formatmessage(s));
 	} else if(argv(0) == "say_team") {
-		Say(self, TRUE, substring(s, 9, strlen(s) - 9));
+		Say(self, TRUE, substring(s, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)));
 		//clientcommand(self, formatmessage(s));
 	} else if(argv(0) == "info") {
 		cmd = cvar_string(strcat("sv_info_", argv(1)));

Modified: branches/nexuiz-2.0/data/qcsrc/server/constants.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/constants.qh	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/constants.qh	2008-10-11 15:11:15 UTC (rev 4731)
@@ -163,6 +163,7 @@
 
 // Deathtypes (weapon deathtypes are the IT_* constants below)
 // NOTE: when adding death types, please add an explanation to Docs/spamlog.txt too.
+float	DEATH_SPECIAL_START     = 10000;
 float	DEATH_FALL				= 10000;
 float	DEATH_TELEFRAG				= 10001;
 float	DEATH_DROWN				= 10002;
@@ -180,6 +181,12 @@
 float	DEATH_MIRRORDAMAGE		= 10014;
 float   DEATH_TURRET            = 10100;
 
+float	DEATH_WEAPONMASK        = 0xFF;
+float	DEATH_HITTYPEMASK		= 0xF00; // which is WAY below 10000 used for normal deaths
+float	HITTYPE_SECONDARY = 0x100;
+float	HITTYPE_SPLASH = 0x200;
+float	HITTYPE_BOUNCE = 0x400;
+
 vector	PL_VIEW_OFS				= '0 0 35';
 vector	PL_MIN					= '-16 -16 -24';
 vector	PL_MAX					= '16 16 45';

Modified: branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1,6 +1,8 @@
 .entity sprite;
 entity ctf_worldflaglist; // CTF flags in the map
 .entity ctf_worldflagnext;
+.float dropperid;
+.float ctf_droptime;
 
 .float next_take_time;			// the next time a player can pick up a flag (time + blah)
 								/// I used this, in part, to fix the looping score bug. - avirox
@@ -11,6 +13,14 @@
 
 #define FLAG_CARRY_POS '-15 0 7'
 
+float ctf_score_value(string parameter)
+{
+	if(g_ctf_win_mode != 2)
+		return cvar(strcat("g_ctf_personal", parameter));
+	else
+		return cvar(strcat("g_ctf_flag", parameter));
+}
+
 void FakeTimeLimit(entity e, float t)
 {
 	msg_entity = e;
@@ -51,17 +61,15 @@
 	self.mangle = self.angles;
 	self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
 	//self.effects = self.effects | EF_DIMLIGHT;
-	if(!self.noalign)
+	if(self.noalign)
 	{
+		self.dropped_origin = self.origin;
+	}
+	else
+	{
+		droptofloor();
 		self.movetype = MOVETYPE_TOSS;
-		if (!droptofloor())
-		{
-			dprint("Flag fell out of level at ", vtos(self.origin), "\n");
-			remove(self);
-			return;
-		}
 	}
-	self.oldorigin = self.origin;
 };
 
 void LogCTF(string mode, float flagteam, entity actor)
@@ -79,12 +87,13 @@
 void RegenFlag(entity e)
 {
 	setattachment(e, world, "");
+	e.damageforcescale = 0;
 	e.movetype = MOVETYPE_NONE;
 	if(!self.noalign)
 		e.movetype = MOVETYPE_TOSS;
 	e.solid = SOLID_TRIGGER;
 	// TODO: play a sound here
-	setorigin(e, e.oldorigin);
+	setorigin(e, e.dropped_origin);
 	e.angles = e.mangle;
 	e.cnt = FLAG_BASE;
 	e.owner = world;
@@ -130,17 +139,19 @@
 	bprint(p.netname, "^7 lost the ", e.netname, "\n");
 
 	if(penalty_receiver)
-		UpdateFrags(penalty_receiver, -cvar("g_ctf_flagpenalty_suicidedrop"));
+		UpdateFrags(penalty_receiver, -ctf_score_value("penalty_suicidedrop"));
 	else
-		UpdateFrags(p, -cvar("g_ctf_flagpenalty_drop"));
+		UpdateFrags(p, -ctf_score_value("penalty_drop"));
 	PlayerScore_Add(p, SP_CTF_DROPS, +1);
 	e.playerid = attacker.playerid;
+	e.ctf_droptime = time;
 	
 	WaypointSprite_Ping(p.waypointsprite_attachedforcarrier);
 	WaypointSprite_DetachCarrier(p);
 	LogCTF("dropped", p.team, p);
 
 	setattachment(e, world, "");
+	e.damageforcescale = cvar("g_balance_ctf_damageforcescale");
 
 	if (p.flagcarried == e)
 		p.flagcarried = world;
@@ -230,6 +241,10 @@
 		DropFlag(self, world, world);
 		return;
 	}
+
+	if(cvar("g_ctf_allow_drop"))
+	if(e.BUTTON_USE)
+		DropFlag(self, e, world);
 };
 
 void FlagTouch()
@@ -289,7 +304,7 @@
 		PlayerTeamScore_Add(other, SP_CTF_CAPS, ST_CTF_CAPS, 1);
 		LogCTF("capture", other.flagcarried.team, other);
 		// give credit to the individual player
-		UpdateFrags(other, cvar("g_ctf_flagscore_capture"));
+		UpdateFrags(other, ctf_score_value("score_capture"));
 
 		sound (other, CHAN_AUTO, self.noise2, VOL_BASE, ATTN_NONE);
 		WaypointSprite_DetachCarrier(other);
@@ -319,7 +334,8 @@
 		self.cnt = FLAG_CARRY;
 		self.angles = '0 0 0';
 		bprint(other.netname, "^7 got the ", self.netname, "\n");
-		UpdateFrags(other, cvar("g_ctf_flagscore_pickup_base"));
+		UpdateFrags(other, ctf_score_value("score_pickup_base"));
+		self.dropperid = other.playerid;
 		PlayerScore_Add(other, SP_CTF_PICKUPS, 1);
 		LogCTF("steal", self.team, other);
 		sound (other, CHAN_AUTO, self.noise, VOL_BASE, ATTN_NONE);
@@ -348,36 +364,36 @@
 
 			// punish the player who last had it
 			FOR_EACH_PLAYER(player)
-				if(player.playerid == self.playerid)
-					PlayerScore_Add(player, SP_SCORE, -cvar("g_ctf_flagpenalty_returned"));
+				if(player.playerid == self.dropperid)
+					PlayerScore_Add(player, SP_SCORE, -ctf_score_value("penalty_returned"));
 
 			// punish the team who was last carrying it
 			if(self.team == COLOR_TEAM1)
-				TeamScore_AddToTeam(COLOR_TEAM2, ST_SCORE, -cvar("g_ctf_flagpenalty_returned"));
+				TeamScore_AddToTeam(COLOR_TEAM2, ST_SCORE, -ctf_score_value("penalty_returned"));
 			else
-				TeamScore_AddToTeam(COLOR_TEAM1, ST_SCORE, -cvar("g_ctf_flagpenalty_returned"));
+				TeamScore_AddToTeam(COLOR_TEAM1, ST_SCORE, -ctf_score_value("penalty_returned"));
 
 			// reward the player who returned it
 			if(other.playerid == self.playerid) // is this the guy who killed the FC last?
 			{
 				if (other.team == COLOR_TEAM1 || other.team == COLOR_TEAM2)
-					UpdateFrags(other, cvar("g_ctf_flagscore_return_by_killer"));
+					UpdateFrags(other, ctf_score_value("score_return_by_killer"));
 				else
-					UpdateFrags(other, cvar("g_ctf_flagscore_return_rogue_by_killer"));
+					UpdateFrags(other, ctf_score_value("score_return_rogue_by_killer"));
 			}
 			else
 			{
 				if (other.team == COLOR_TEAM1 || other.team == COLOR_TEAM2)
-					UpdateFrags(other, cvar("g_ctf_flagscore_return"));
+					UpdateFrags(other, ctf_score_value("score_return"));
 				else
-					UpdateFrags(other, cvar("g_ctf_flagscore_return_rogue"));
+					UpdateFrags(other, ctf_score_value("score_return_rogue"));
 			}
 			PlayerScore_Add(other, SP_CTF_RETURNS, 1);
 			LogCTF("return", self.team, other);
 			sound (other, CHAN_AUTO, self.noise1, VOL_BASE, ATTN_NONE);
 			ReturnFlag(self);
 		}
-		else if (!other.flagcarried)
+		else if (!other.flagcarried && (other.playerid != self.dropperid || time > self.ctf_droptime + cvar("g_balance_ctf_delay_collect")))
 		{
 			// pick up
 			self.solid = SOLID_NOT;
@@ -390,9 +406,10 @@
 			float f;
 			f = bound(0, (self.pain_finished - time) / cvar("g_ctf_flag_returntime"), 1);
 			//print("factor is ", ftos(f), "\n");
-			f = cvar("g_ctf_flagscore_pickup_dropped_late") * (1-f)
-			  + cvar("g_ctf_flagscore_pickup_dropped_early") * f;
+			f = ctf_score_value("score_pickup_dropped_late") * (1-f)
+			  + ctf_score_value("score_pickup_dropped_early") * f;
 			f = floor(f + 0.5);
+			self.dropperid = other.playerid;
 			//print("score is ", ftos(f), "\n");
 
 			UpdateFrags(other, f);
@@ -407,6 +424,7 @@
 			self.movetype = MOVETYPE_NONE;	// flag must have MOVETYPE_NONE here, otherwise it will drop through the floor...
 			setorigin(self, FLAG_CARRY_POS);
 			setattachment(self, other, "");
+			self.damageforcescale = 0;
 			WaypointSprite_AttachCarrier("flagcarrier", other);
 			WaypointSprite_UpdateTeamRadar(other.waypointsprite_attachedforcarrier, RADARICON_FLAGCARRIER, '1 1 0');
 		}
@@ -539,7 +557,8 @@
 	precache_sound (self.noise1);
 	precache_sound (self.noise2);
 	precache_sound (self.noise3);
-	setsize(self, '-16 -16 -37', '16 16 37');
+	//setsize(self, '-16 -16 -37', '16 16 37');
+	setsize(self, PL_MIN + '0 0 -13', PL_MAX + '0 0 -13');
 	setorigin(self, self.origin + '0 0 37');
 	self.nextthink = time + 0.2; // start after doors etc
 	self.think = place_flag;
@@ -549,9 +568,9 @@
 	//if(!self.glow_size)
 	//	self.glow_size = 50;
 
-	self.effects = self.effects | EF_FULLBRIGHT | EF_LOWPRECISION;
-	if(!self.noalign)
-		droptofloor();
+	self.effects = self.effects | EF_LOWPRECISION;
+	if(cvar("g_ctf_fullbrightflags"))
+		self.effects |= EF_FULLBRIGHT;
 
 	waypoint_spawnforitem(self);
 
@@ -622,7 +641,8 @@
 	precache_sound (self.noise1);
 	precache_sound (self.noise2);
 	precache_sound (self.noise3);
-	setsize(self, '-16 -16 -37', '16 16 37');
+	//setsize(self, '-16 -16 -37', '16 16 37');
+	setsize(self, PL_MIN + '0 0 -13', PL_MAX + '0 0 -13');
 	setorigin(self, self.origin + '0 0 37');
 	self.nextthink = time + 0.2; // start after doors etc
 	self.think = place_flag;
@@ -632,9 +652,9 @@
 	//if(!self.glow_size)
 	//	self.glow_size = 50;
 
-	self.effects = self.effects | EF_FULLBRIGHT | EF_LOWPRECISION;
-	if(!self.noalign)
-		droptofloor();
+	self.effects = self.effects | EF_LOWPRECISION;
+	if(cvar("g_ctf_fullbrightflags"))
+		self.effects |= EF_FULLBRIGHT;
 
 	waypoint_spawnforitem(self);
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/defs.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2008-10-11 15:11:15 UTC (rev 4731)
@@ -16,12 +16,15 @@
 
 // Globals
 
+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;
 float g_cloaked, g_footsteps, g_jump_grunt, g_grappling_hook, g_laserguided_missile, g_midair, g_minstagib, g_nixnex, g_nixnex_with_laser, g_norecoil, g_rocketarena, g_vampire, g_minstagib_invis_alpha;
 float g_warmup_limit;
 float g_warmup_allguns;
 float g_warmup_allow_timeout;
 float g_ctf_win_mode;
+float g_ctf_ignore_frags;
 float g_race_qualifying;
 float inWarmupStage;
 float g_pickup_respawntime_short;
@@ -208,12 +211,13 @@
 float WR_CHECKAMMO2	    = 4; // checks ammo for weapon
 float WR_AIM		    = 5; // runs bot aiming code for this weapon
 float WR_PRECACHE	    = 6; // precaches models/sounds used by this weapon
-float WR_SUICIDEMESSAGE = 7; // sets w_deathtypestring or leaves it alone
+float WR_SUICIDEMESSAGE = 7; // sets w_deathtypestring or leaves it alone (and may inspect w_deathtype for details)
 float WR_KILLMESSAGE    = 8; // sets w_deathtypestring or leaves it alone
 
 void weapon_defaultspawnfunc(float wpn);
 
 string w_deathtypestring;
+float w_deathtype;
 
 void(entity client, string s) centerprint_builtin = #73;
 .vector dest1, dest2;
@@ -241,7 +245,6 @@
 .float vote_next;
 .float vote_vote;
 void VoteThink();
-string VoteParse();
 float VoteAllowed(string vote);
 void VoteReset();
 void VoteAccept();
@@ -494,3 +497,9 @@
 .float stat_game_starttime;
 
 void W_Porto_Remove (entity p);
+
+.float projectiledeathtype;
+
+.string message2;
+
+vector railgun_start, railgun_end; // filled by FireRailgunBullet, used by damage code for head shot

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1,8 +1,11 @@
-
 float checkrules_firstblood;
 
 float yoda;
+float damage_goodhits;
+float damage_gooddamage;
+float headshot;
 
+
 float IsDifferentTeam(entity a, entity b)
 {
 	if(teams_matter)
@@ -93,7 +96,7 @@
 	}
 	else if(g_ctf)
 	{
-		if(g_ctf_win_mode == 3)
+		if(g_ctf_ignore_frags)
 			f = 0;
 	}
 
@@ -146,7 +149,7 @@
 	GameLogEcho(s);
 }
 
-void Obituary (entity attacker, entity targ, float deathtype)
+void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
 {
 	string	s, a;
 	float p;
@@ -209,10 +212,11 @@
 				if (targ.killcount > 2)
 					bprint ("^1",s,"^1 ended it all with a ",ftos(targ.killcount)," scoring spree\n");
 			} else {
-				if(deathtype >= WEP_FIRST && deathtype <= WEP_LAST)
+				if(deathtype < DEATH_SPECIAL_START && deathtype & DEATH_WEAPONMASK >= WEP_FIRST && deathtype & DEATH_WEAPONMASK <= WEP_LAST)
 				{
 					w_deathtypestring = "couldn't resist the urge to self-destruct";
-					weapon_action(deathtype, WR_SUICIDEMESSAGE);
+					w_deathtype = deathtype;
+					weapon_action(deathtype & DEATH_WEAPONMASK, WR_SUICIDEMESSAGE);
 					bprint("^1", s, "^1 ", w_deathtypestring, "\n");
 				}
 				else if (deathtype == DEATH_KILL)
@@ -289,10 +293,11 @@
 				if(sv_gentle) {
 					bprint ("^1",s, "^1 needs a restart thanks to ", a, "\n");
 				} else {
-					if(deathtype >= WEP_FIRST && deathtype <= WEP_LAST)
+					if(deathtype < DEATH_SPECIAL_START && deathtype & DEATH_WEAPONMASK >= WEP_FIRST && deathtype & DEATH_WEAPONMASK <= WEP_LAST)
 					{
 						w_deathtypestring = "was blasted by";
-						weapon_action(deathtype, WR_KILLMESSAGE);
+						w_deathtype = deathtype;
+						weapon_action(deathtype & DEATH_WEAPONMASK, WR_KILLMESSAGE);
 						p = strstrofs(w_deathtypestring, "#", 0);
 						if(p < 0)
 							bprint("^1", s, "^1 ", w_deathtypestring, " ", a, "\n");
@@ -313,8 +318,14 @@
 						bprint ("^1",s, "^1 was shot into space by ", a, "\n");
 					else if (deathtype == DEATH_SWAMP)
 						bprint ("^1",s, "^1 was conserved by ", a, "\n");
-					else if (deathtype == DEATH_HURTTRIGGER)
-						bprint ("^1",s, "^1 was thrown into a world of hurt by ", a, "\n");
+					else if (deathtype == DEATH_HURTTRIGGER && attacker.message2 != "")
+					{
+						p = strstrofs(inflictor.message2, "#", 0);
+						if(p < 0)
+							bprint("^1", s, "^1 ", inflictor.message2, " ", a, "\n");
+						else
+							bprint("^1", s, "^1 ", substring(inflictor.message2, 0, p), a, "^1", substring(inflictor.message2, p+1, strlen(inflictor.message2) - (p+1)), "\n");
+					}
                     else if(deathtype == DEATH_TURRET)
                         bprint ("^1",s, "^1 was pushed into the line of fire by ^1", a, "\n");
 					else
@@ -322,10 +333,9 @@
 				}
 				if(g_ctf && targ.flagcarried)
 				{
-					//GiveFrags(attacker, targ, cvar("g_ctf_flagscore_kill"));
-					UpdateFrags(attacker, cvar("g_ctf_flagscore_kill"));
+					UpdateFrags(attacker, ctf_score_value("score_kill"));
 					PlayerScore_Add(attacker, SP_CTF_FCKILLS, 1);
-					GiveFrags(attacker, targ, 0);
+					GiveFrags(attacker, targ, 0); // for logging
 				}
 				else
 					GiveFrags(attacker, targ, 1);
@@ -562,13 +572,6 @@
 			attacker.lms_traveled_distance = cvar("g_lms_campcheck_distance");
 		}
 
-		if(targ != attacker)
-		if(!targ.deadflag)
-		if(damage > 0)
-		if(targ.classname == "player")
-		if(attacker)
-			attacker.hitsound += 1;
-
 		if (g_minstagib)
 		{
 			if ((deathtype == DEATH_FALL)  ||
@@ -586,12 +589,6 @@
 				damage = 0;
 				targ.hitsound += 1;
 			}
-			else if (deathtype == WEP_MINSTANEX && targ.items & IT_STRENGTH)
-			{
-				if(clienttype(attacker) == CLIENTTYPE_REAL)
-					if(IsDifferentTeam(targ, attacker))
-						yoda = 1;
-			}
 			if (deathtype == WEP_LASER)
 			{
 				damage = 0;
@@ -606,12 +603,6 @@
 					attacker = targ;
 				}
 			}
-		} else {
-			if (!targ.deadflag)
-				if(targ.takedamage == DAMAGE_AIM)
-					if(IsFlying(targ))
-						if(IsDifferentTeam(targ, attacker))
-							yoda = 1;
 		}
 
 		// apply strength multiplier
@@ -678,6 +669,37 @@
 			else if (targ.runes & CURSE_VULNER)
 				damage = damage * cvar("g_balance_curse_vulner_takedamage");
 		}
+
+		// count the damage
+		if(attacker)
+		if(targ.classname == "player")
+		if(IsDifferentTeam(targ, attacker))
+		if(!targ.deadflag)
+		if(targ.takedamage == DAMAGE_AIM)
+		if(damage > 0)
+		{
+			attacker.hitsound += 1;
+
+			damage_goodhits += 1;
+			damage_gooddamage += damage;
+
+			if(!g_minstagib)
+			if(IsFlying(targ))
+				yoda = 1;
+
+			if(g_minstagib)
+			if(targ.items & IT_STRENGTH)
+				yoda = 1;
+
+			// HEAD SHOT:
+			// find height of hit on player axis
+			// if above view_ofs and below maxs, and also in the middle half of the bbox, it is head shot
+			vector headmins, headmaxs;
+			headmins = targ.origin + '0.5 0 0' * targ.mins_x + '0 0.5 0' * targ.mins_y + '0 0 1' * targ.view_ofs_z;
+			headmaxs = targ.origin + '0.5 0 0' * targ.maxs_x + '0 0.5 0' * targ.maxs_y + '0 0 1' * targ.maxs_z;
+			if(trace_hits_box(railgun_start, railgun_end, headmins, headmaxs))
+				headshot = 1;
+		}
 	}
 
 	// apply push
@@ -771,7 +793,7 @@
 	return nearest;
 }
 
-float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity ignore, float forceintensity, float deathtype)
+float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity ignore, float forceintensity, float deathtype, entity directhitentity)
 // Returns total damage applies to creatures
 {
 	entity	targ;
@@ -829,7 +851,10 @@
 							{
 								if(targ.iscreature)
 									total_damage_to_creatures += finaldmg;
-								Damage (targ, inflictor, attacker, finaldmg, deathtype, nearest, force);
+								if(targ == directhitentity)
+									Damage (targ, inflictor, attacker, finaldmg, deathtype, nearest, force);
+								else
+									Damage (targ, inflictor, attacker, finaldmg, deathtype | HITTYPE_SPLASH, nearest, force);
 								break;
 							}
 							nearest_x = targ.mins_x + random() * targ.size_x;

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_triggers.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_triggers.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_triggers.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -402,7 +402,9 @@
 	if (!self.dmg)
 		self.dmg = 1000;
 	if (!self.message)
-		self.message = "was in the wrong place.";
+		self.message = "was in the wrong place";
+	if (!self.message2)
+		self.message2 = "was thrown into a world of hurt by";
 
 	if(!trigger_hurt_first)
 		trigger_hurt_first = self;
@@ -411,55 +413,6 @@
 	trigger_hurt_last = self;
 };
 
-float trace_hits_box_a0, trace_hits_box_a1;
-
-float trace_hits_box_1d(float end, float thmi, float thma)
-{
-	if(end == 0)
-	{
-		// just check if x is in range
-		if(0 < thmi)
-			return FALSE;
-		if(0 > thma)
-			return FALSE;
-	}
-	else
-	{
-		// do the trace with respect to x
-		// 0 -> end has to stay in thmi -> thma
-		trace_hits_box_a0 = max(trace_hits_box_a0, min(thmi / end, thma / end));
-		trace_hits_box_a1 = min(trace_hits_box_a1, max(thmi / end, thma / end));
-		if(trace_hits_box_a0 > trace_hits_box_a1)
-			return FALSE;
-	}
-	return TRUE;
-}
-
-float trace_hits_box(vector start, vector end, vector thmi, vector thma)
-{
-	end -= start;
-	thmi -= start;
-	thma -= start;
-	// now it is a trace from 0 to end
-
-	trace_hits_box_a0 = 0;
-	trace_hits_box_a1 = 1;
-
-	if(!trace_hits_box_1d(end_x, thmi_x, thma_x))
-		return FALSE;
-	if(!trace_hits_box_1d(end_y, thmi_y, thma_y))
-		return FALSE;
-	if(!trace_hits_box_1d(end_z, thmi_z, thma_z))
-		return FALSE;
-
-	return TRUE;
-}
-
-float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma)
-{
-	return trace_hits_box(start, end, thmi - ma, thma - mi);
-}
-
 float tracebox_hits_trigger_hurt(vector start, vector mi, vector ma, vector end)
 {
 	entity th;
@@ -923,6 +876,8 @@
 			self.colormod = '1 0 0';
 	if(!self.message)
 		self.message = "saw the light";
+	if (!self.message2)
+		self.message2 = "was pushed into a laser by";
 	self.think = misc_laser_think;
 	self.nextthink = time;
 	InitializeEntity(self, misc_laser_init, INITPRIO_FINDTARGET);

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -168,7 +168,7 @@
 		return;
 	while((s = fgets(fh)))
 	{
-		n = tokenize(s);
+		n = tokenize_sane(s);
 		if(n < 1)
 			continue;
 		if(argv(0) == "//")
@@ -208,6 +208,8 @@
 		error("world already spawned - you may have EXACTLY ONE worldspawn!");
 	world_already_spawned = TRUE;
 
+	remove = remove_safely; // during spawning, watch what you remove!
+
 	compressShortVector_init();
 
 	local entity head;
@@ -361,7 +363,7 @@
 		{
 			while((s = fgets(fd)))
 			{
-				l = tokenize(s);
+				l = tokenize_sane(s);
 				if(l < 2)
 					continue;
 				if(argv(0) == "cd")
@@ -1620,7 +1622,7 @@
 		{
 			checkrules_overtimewarning = TRUE;
 			//announceall("announcer/robotic/1minuteremains.wav");
-			if(!g_race_qualifying)
+			if(g_race && !g_race_qualifying)
 				bcenterprint("^3Everyone, finish your lap! The race is over!");
 			else
 				bcenterprint("^3Now playing ^1OVERTIME^3!\n\n^3Keep fragging until we have a ^1winner^3!");

Modified: branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -420,7 +420,7 @@
 	fh = fopen("effectinfo.txt", FILE_READ);
 	while((s = fgets(fh)))
 	{
-		tokenize(s);
+		tokenize_sane(s);
 		if(argv(0) == "effect")
 		{
 			if(db_get(d, argv(1)) != "1")
@@ -456,7 +456,7 @@
 	float argc;
 	entity client;
 	float entno;
-	argc = tokenize(command);
+	argc = tokenize_sane(command);
 
 	if(argv(0) == "help" || argc == 0)
 	{

Modified: branches/nexuiz-2.0/data/qcsrc/server/ipban.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ipban.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/ipban.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -55,7 +55,7 @@
 		Ban_Delete(i);
 	ban_count = 0;
 	ban_loaded = TRUE;
-	n = tokenize(cvar_string("g_banned_list"));
+	n = tokenize_sane(cvar_string("g_banned_list"));
 	if(stof(argv(0)) == 1)
 	{
 		ban_count = (n - 1) / 2;
@@ -207,7 +207,7 @@
 	float entno;
 	float masksize;
 
-	argc = tokenize(command);
+	argc = tokenize_sane(command);
 	if(argv(0) == "help")
 	{
 		print("  kickban # n m p - kickban player n for m seconds, using mask size p (1 to 4)\n");

Modified: branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -976,6 +976,9 @@
 	kh_key_carried = kh_key_dropped;
 #endif
 
+	kh_controller.model = "";
+	kh_controller.modelindex = 0;
+
 	addstat(STAT_KH_KEYS, AS_INT, kh_state);
 
 	ScoreRules_kh(kh_teams);

Modified: branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1,4 +1,7 @@
+var void remove(entity e);
 void objerror(string s);
+void droptofloor();
+.vector dropped_origin;
 
 void() spawnfunc_info_player_deathmatch; // needed for the other spawnpoints
 void() spawnpoint_use;
@@ -960,14 +963,16 @@
 }
 
 .float announcetime;
-void announce(entity player, string msg)
+float announce(entity player, string msg)
 {
 	if(time > player.announcetime)
 	if(clienttype(player) == CLIENTTYPE_REAL)
 	{
 		player.announcetime = time + 0.3;
 		play2(player, msg);
+		return TRUE;
 	}
+	return FALSE;
 }
 
 void play2team(float t, string filename)
@@ -1092,7 +1097,9 @@
 	precache_sound ("announcer/male/25kills.wav");
 	precache_sound ("announcer/male/30kills.wav");
 	precache_sound ("announcer/male/botlike.wav");
-	precache_sound ("announcer/male/yoda.wav");
+	precache_sound ("announcer/male/yoda.ogg");
+	precache_sound ("announcer/male/headshot.ogg");
+	precache_sound ("announcer/male/impressive.ogg");
 
 	// announcer sounds - robotic
 	precache_sound ("announcer/robotic/prepareforbattle.wav");
@@ -1212,6 +1219,7 @@
 #define INITPRIO_GAMETYPE_FALLBACK  1
 #define INITPRIO_CVARS              5
 #define INITPRIO_FINDTARGET        10
+#define INITPRIO_DROPTOFLOOR       20
 #define INITPRIO_SETLOCATION       90
 #define INITPRIO_LINKDOORS         91
 #define INITPRIO_LAST              99
@@ -1258,6 +1266,12 @@
 	objerror_builtin(s);
 }
 
+void remove_safely(entity e)
+{
+	make_safe_for_remove(e);
+	remove_builtin(e);
+}
+
 void InitializeEntity(entity e, void(void) func, float order)
 {
 	entity prev, cur;
@@ -1307,7 +1321,7 @@
 		{
 			entity e_old;
 			e_old = self.enemy;
-			remove(self);
+			remove_builtin(self);
 			self = e_old;
 		}
 		dprint("Delayed initialization: ", self.classname, "\n");
@@ -1518,3 +1532,86 @@
 	e.effects = EF_NODEPTHTEST | EF_LOWPRECISION;
 }
 
+void adaptor_think2touch()
+{
+	entity o;
+	o = other;
+	other = world;
+	self.touch();
+	other = o;
+}
+
+void adaptor_think2use()
+{
+	entity o, a;
+	o = other;
+	a = activator;
+	activator = world;
+	other = world;
+	self.use();
+	other = o;
+	activator = a;
+}
+
+// deferred dropping
+void DropToFloor_Handler()
+{
+	droptofloor_builtin();
+	self.dropped_origin = self.origin;
+}
+
+void droptofloor()
+{
+	InitializeEntity(self, DropToFloor_Handler, INITPRIO_DROPTOFLOOR);
+}
+
+
+
+float trace_hits_box_a0, trace_hits_box_a1;
+
+float trace_hits_box_1d(float end, float thmi, float thma)
+{
+	if(end == 0)
+	{
+		// just check if x is in range
+		if(0 < thmi)
+			return FALSE;
+		if(0 > thma)
+			return FALSE;
+	}
+	else
+	{
+		// do the trace with respect to x
+		// 0 -> end has to stay in thmi -> thma
+		trace_hits_box_a0 = max(trace_hits_box_a0, min(thmi / end, thma / end));
+		trace_hits_box_a1 = min(trace_hits_box_a1, max(thmi / end, thma / end));
+		if(trace_hits_box_a0 > trace_hits_box_a1)
+			return FALSE;
+	}
+	return TRUE;
+}
+
+float trace_hits_box(vector start, vector end, vector thmi, vector thma)
+{
+	end -= start;
+	thmi -= start;
+	thma -= start;
+	// now it is a trace from 0 to end
+
+	trace_hits_box_a0 = 0;
+	trace_hits_box_a1 = 1;
+
+	if(!trace_hits_box_1d(end_x, thmi_x, thma_x))
+		return FALSE;
+	if(!trace_hits_box_1d(end_y, thmi_y, thma_y))
+		return FALSE;
+	if(!trace_hits_box_1d(end_z, thmi_z, thma_z))
+		return FALSE;
+
+	return TRUE;
+}
+
+float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma)
+{
+	return trace_hits_box(start, end, thmi - ma, thma - mi);
+}

Modified: branches/nexuiz-2.0/data/qcsrc/server/portals.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/portals.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/portals.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -199,8 +199,9 @@
 
 	// reset fade counter
 	teleporter.portal_wants_to_vanish = 0;
-	teleporter.fade_time = time + 15;
-	teleporter.enemy.health = 300;
+	teleporter.fade_time = time + cvar("g_balance_portal_lifetime");
+	teleporter.health = cvar("g_balance_portal_health");
+	teleporter.enemy.health = cvar("g_balance_portal_health");
 
 	return 1;
 }
@@ -592,10 +593,11 @@
 	portal.angles = ang;
 	portal.think = Portal_Think;
 	portal.nextthink = 0;
-	portal.fade_time = time + 15;
-	portal.portal_activatetime = time + 0.1;
+	portal.portal_activatetime = time + 1.1;
 	portal.event_damage = Portal_Damage;
-	portal.health = 300;
+	portal.health = 200;
+	portal.fade_time = time + cvar("g_balance_portal_lifetime");
+	portal.health = cvar("g_balance_portal_health");
 	setmodel(portal, "models/portal.md3");
 	portal.modelindex_lod0 = portal.modelindex;
 	portal.customizeentityforclient = Portal_Customize;

Modified: branches/nexuiz-2.0/data/qcsrc/server/progs.src
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/progs.src	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/progs.src	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1,12 +1,13 @@
 ../../progs.dat // output filename
 
+../common/util-pre.qh
 sys.qh
 builtins.qh
 constants.qh
 ../common/constants.qh
 defs.qh		// Should rename this, it has fields and globals
-
 extensions.qh
+../common/util.qh
 
 //// tZork Turrets ////
 tturrets/include/turret_tturrets_early.qh
@@ -14,7 +15,6 @@
 campaign.qh
 ../common/campaign_common.qh
 ../common/mapinfo.qh
-../common/util.qh
 ../common/util.qc
 
 portals.qh

Modified: branches/nexuiz-2.0/data/qcsrc/server/race.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/race.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/race.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -420,6 +420,8 @@
 
 	if(!self.message)
 		self.message = "went backwards";
+	if (!self.message2)
+		self.message2 = "was pushed backwards by";
 	
 	self.race_checkpoint = self.cnt;
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/runematch.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/runematch.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/runematch.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -39,8 +39,8 @@
 		return;
 	}
 
+	setsize(self, '0 0 -35', '0 0 0');
 	droptofloor();
-	setorigin(self, self.origin + '0 0 35');
 }
 
 string RuneName(float r)

Modified: branches/nexuiz-2.0/data/qcsrc/server/scores_rules.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/scores_rules.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/scores_rules.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -4,7 +4,7 @@
 // NOTE: SP_ constants may not be >= MAX_SCORE; ST_constants may not be >= MAX_TEAMSCORE
 // scores that should be in all modes:
 float ScoreRules_teams;
-void ScoreRules_basics(float teams, float sprio, float score_enabled)
+void ScoreRules_basics(float teams, float sprio, float stprio, float score_enabled)
 {
 	float i;
 	for(i = 0; i < MAX_SCORE; ++i)
@@ -15,7 +15,7 @@
 	ScoreRules_teams = teams;
 
 	if(score_enabled)
-		ScoreInfo_SetLabel_TeamScore  (ST_SCORE,        "score",     sprio);
+		ScoreInfo_SetLabel_TeamScore  (ST_SCORE,        "score",     stprio);
 
 	if not(independent_players)
 		ScoreInfo_SetLabel_PlayerScore(SP_KILLS,        "kills",     0);
@@ -38,10 +38,10 @@
 	if(teamplay)
 	{
 		CheckAllowedTeams(world);
-		ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), SFL_SORT_PRIO_PRIMARY, TRUE);
+		ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, TRUE);
 	}
 	else
-		ScoreRules_basics(0, SFL_SORT_PRIO_PRIMARY, TRUE);
+		ScoreRules_basics(0, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, TRUE);
 	ScoreRules_basics_end();
 }
 
@@ -60,23 +60,23 @@
 	{
 		case 0: // caps only
 			sp_caps = SFL_SORT_PRIO_PRIMARY;
+			sp_score = SFL_SORT_PRIO_SECONDARY;
 			break;
 		case 1: // caps, then score
 			sp_caps = SFL_SORT_PRIO_PRIMARY;
 			sp_score = SFL_SORT_PRIO_SECONDARY;
 			break;
 		case 2: // score only
-		case 3: // score only, no frags
 		default:
+			sp_caps = SFL_SORT_PRIO_SECONDARY; // looks better ;)
 			sp_score = SFL_SORT_PRIO_PRIMARY;
-			sp_caps = SFL_SORT_PRIO_SECONDARY; // looks better ;)
 			break;
 	}
 
 	CheckAllowedTeams(world);
-	ScoreRules_basics(2 + (c3>=0), sp_score, TRUE); // NOTE this assumes that the rogue team is team 3
+	ScoreRules_basics(2 + (c3>=0), SFL_SORT_PRIO_PRIMARY, sp_score, TRUE); // NOTE this assumes that the rogue team is team 3
 	ScoreInfo_SetLabel_TeamScore  (ST_CTF_CAPS,     "caps",      sp_caps);
-	ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPS,     "caps",      sp_caps);
+	ScoreInfo_SetLabel_PlayerScore(SP_CTF_CAPS,     "caps",      SFL_SORT_PRIO_SECONDARY);
 	ScoreInfo_SetLabel_PlayerScore(SP_CTF_PICKUPS,  "pickups",   0);
 	ScoreInfo_SetLabel_PlayerScore(SP_CTF_FCKILLS,  "fckills",   0);
 	ScoreInfo_SetLabel_PlayerScore(SP_CTF_RETURNS,  "returns",   0);
@@ -97,7 +97,7 @@
 	else
 		sp_score = SFL_SORT_PRIO_PRIMARY;
 	CheckAllowedTeams(world);
-	ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), sp_score, TRUE);
+	ScoreRules_basics(((c4>=0) ? 4 : (c3>=0) ? 3 : 2), sp_score, sp_score, TRUE);
 	ScoreInfo_SetLabel_TeamScore  (ST_DOM_TICKS,    "ticks",     sp_domticks);
 	ScoreInfo_SetLabel_PlayerScore(SP_DOM_TICKS,    "ticks",     sp_domticks);
 	ScoreInfo_SetLabel_PlayerScore(SP_DOM_TAKES,    "takes",     0);
@@ -109,7 +109,7 @@
 #define SP_LMS_RANK 5
 void ScoreRules_lms()
 {
-	ScoreRules_basics(0, 0, FALSE);
+	ScoreRules_basics(0, 0, 0, FALSE);
 	ScoreInfo_SetLabel_PlayerScore(SP_LMS_LIVES,    "lives",     SFL_SORT_PRIO_SECONDARY);
 	ScoreInfo_SetLabel_PlayerScore(SP_LMS_RANK,     "rank",      SFL_LOWER_IS_BETTER | SFL_RANK | SFL_SORT_PRIO_PRIMARY | SFL_ALLOW_HIDE);
 	ScoreRules_basics_end();
@@ -125,7 +125,7 @@
 #define SP_KH_LOSSES 9
 void ScoreRules_kh(float teams)
 {
-	ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, TRUE);
+	ScoreRules_basics(teams, SFL_SORT_PRIO_PRIMARY, SFL_SORT_PRIO_PRIMARY, TRUE);
 	ScoreInfo_SetLabel_TeamScore  (ST_KH_CAPS,      "caps",      SFL_SORT_PRIO_SECONDARY);
 	ScoreInfo_SetLabel_PlayerScore(SP_KH_CAPS,      "caps",      SFL_SORT_PRIO_SECONDARY);
 	ScoreInfo_SetLabel_PlayerScore(SP_KH_PUSHES,    "pushes",    0);
@@ -143,7 +143,7 @@
 #define SP_RACE_TIME 5
 void ScoreRules_race()
 {
-	ScoreRules_basics(race_teams, 0, FALSE);
+	ScoreRules_basics(race_teams, 0, 0, FALSE);
 	if(race_teams)
 	{
 		ScoreInfo_SetLabel_TeamScore(  ST_RACE_LAPS,    "laps",      SFL_SORT_PRIO_PRIMARY);

Modified: branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -133,6 +133,8 @@
 entity SelectSpawnPoint (float anypoint);
 void StartFrame (void)
 {
+	remove = remove_builtin; // not during spawning!
+
 	dprint_load(); // load dprint status from cvar
 
 	if(RedirectionThink())

Modified: branches/nexuiz-2.0/data/qcsrc/server/t_items.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_items.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_items.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -613,7 +613,7 @@
 	if(self.classname != "droppedweapon" && self.classname != "replacedweapon")
 	{
 		s = cvar_string(strcat("g_weaponreplace_", ftos(wpn)));
-		t = tokenize(s);
+		t = tokenize_sane(s);
 		if(t >= 2)
 		{
 			self.team = --internalteam;
@@ -1128,7 +1128,7 @@
 	precache_sound("misc/powerup.wav");
 	precache_sound("weapons/weaponpickup.wav");
 
-	n = tokenize(self.netname);
+	n = tokenize_sane(self.netname);
 	for(i = 0; i < n; ++i)
 	{
 		if(argv(i) == "unlimited_ammo") self.items |= IT_UNLIMITED_AMMO;

Modified: branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -163,7 +163,9 @@
         self.dmg = 10000;
 
     if(self.dmg && (!self.message))
-		self.message = "was in the wrong place.";
+		self.message = "was squished";
+    if(self.dmg && (!self.message2))
+		self.message2 = "was squished by";
 
 	if (self.sounds == 1)
 	{
@@ -334,7 +336,9 @@
 		self.avelocity = '0 1 0' * self.speed;
 
     if(self.dmg & (!self.message))
-        self.message = " was in the wrong place.";
+        self.message = " was squished";
+    if(self.dmg && (!self.message2))
+		self.message2 = "was squished by";
 
 
     if(self.dmg && (!self.dmgtime))
@@ -358,7 +362,7 @@
 	local vector v;
 	self.nextthink = time + 0.1;
 	// calculate sinewave using makevectors
-	makevectors((time * self.owner.cnt + self.owner.phase) * '0 1 0');
+	makevectors((time * self.owner.cnt + self.owner.phase * 360) * '0 1 0');
 	v = self.owner.destvec + self.owner.movedir * v_forward_y;
 	// * 10 so it will arrive in 0.1 sec
 	self.owner.velocity = (v - self.owner.origin) * 10;
@@ -399,7 +403,9 @@
 	// damage when blocked
 	self.blocked = bobbing_blocked;
 	if(self.dmg & (!self.message))
-		self.message = " was in the wrong place.";
+		self.message = " was squished";
+    if(self.dmg && (!self.message2))
+		self.message2 = "was squished by";
 	if(self.dmg && (!self.dmgtime))
 		self.dmgtime = 0.25;
 	self.dmgtime2 = time;
@@ -808,7 +814,7 @@
 
 	self.owner.attack_finished_single = time + 2;
 
-	if (self.owner.message != "")
+	if (!self.dmg && self.owner.message != "")
 	{
 		if (other.flags & FL_CLIENT)
 			centerprint (other, self.owner.message);
@@ -996,11 +1002,11 @@
     if(self.spawnflags & 8)
         self.dmg = 10000;
 
-    if(self.dmg & (!self.message))
-		self.message = "was in the wrong place.";
+    if(self.dmg && (!self.message))
+		self.message = "was squished";
+    if(self.dmg && (!self.message2))
+		self.message2 = "was squished by";
 
-
-
 	if (self.sounds > 0)
 	{
 		precache_sound ("plats/medplat1.wav");

Modified: branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -227,7 +227,8 @@
 		gamemode_name = "Capture the Flag";
 		ActivateTeamplay();
 		g_ctf_win_mode = cvar("g_ctf_win_mode");
-		if(g_ctf_win_mode >= 2)
+		g_ctf_ignore_frags = cvar("g_ctf_ignore_frags");
+		if(g_ctf_win_mode == 2)
 			fraglimit_override = cvar("g_ctf_capture_limit");
 		else
 			fraglimit_override = cvar("capturelimit_override");
@@ -1213,6 +1214,7 @@
 	}
 	else
 	{
+		if(cvar("g_balance_teams_complain"))
 		if(howmany_toomany < cvar("g_balance_teams_complain"))
 			return;
 		if(time < lastRebalanceInfo + 90)

Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/turret_system_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/turret_system_damage.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/system/turret_system_damage.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -193,7 +193,7 @@
 
 
 // Go boom
-    RadiusDamage (self,self, min(self.ammo,50),min(self.ammo,50) * 0.25,250,world,min(self.ammo,50)*5,0);
+    RadiusDamage (self,self, min(self.ammo,50),min(self.ammo,50) * 0.25,250,world,min(self.ammo,50)*5,0,world);
 
 // Setup respawn
     self.nextthink      = time + self.respawntime;

Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_flac.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_flac.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_flac.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -52,7 +52,7 @@
 
     self.event_damage = SUB_Null;
 
-    ftmp = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET);
+    ftmp = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
 
 #ifdef TURRET_DEBUG
     self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;

Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_hellion.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_hellion.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_hellion.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -160,7 +160,7 @@
     WriteCoord (MSG_BROADCAST, org2_z);
 
     self.event_damage = SUB_Null;
-    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET);
+    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
 
 #ifdef TURRET_DEBUG
     self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;

Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_hk.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_hk.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_hk.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -367,7 +367,7 @@
     WriteCoord (MSG_BROADCAST, org2_z);
 
     self.event_damage = SUB_Null;
-    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET);
+    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
 
 #ifdef TURRET_DEBUG
     self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;

Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_mlrs.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_mlrs.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_mlrs.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -61,11 +61,11 @@
 #ifdef TURRET_DEBUG
     float d;
 
-    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET);
+    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
     self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
     self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
 #else
-    RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET);
+    RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
 #endif
 
     // Target dead, get another is still targeting the same.

Modified: branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_plasma.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_plasma.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/tturrets/units/turret_unit_plasma.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -85,11 +85,11 @@
 #ifdef TURRET_DEBUG
     float d;
 
-    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET);
+    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
     self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
     self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
 #else
-    RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET);
+    RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
 #endif
     sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", 1, ATTN_NORM);
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/vote.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/vote.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/vote.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -14,11 +14,11 @@
 entity GetKickVoteVictim(string vote, string cmd, entity caller)
 {
 	float tokens;
-	float i, n, t;
+	float n, t;
 	string ns;
 	entity e;
 
-	tokens = tokenize(vote);
+	tokens = tokenize_sane(vote);
 	ns = "";
 
 	if(tokens >= 2)
@@ -37,10 +37,7 @@
 
 	if(ns != "")
 	{
-		GetKickVoteVictim_reason = "";
-		for(i = t; i < tokens; ++i)
-			GetKickVoteVictim_reason = strcat(GetKickVoteVictim_reason, argv(i), " ");
-		GetKickVoteVictim_reason = substring(GetKickVoteVictim_reason, 0, strlen(GetKickVoteVictim_reason) - 1);
+		GetKickVoteVictim_reason = substring(vote, argv_start_index(t), argv_end_index(-1) - argv_start_index(t));
 
 		n = stof(ns);
 		if(ns == ftos(n)) if(n >= 1) if(n <= maxclients)
@@ -58,8 +55,57 @@
 	return world;
 }
 
+string RemapVote_display;
+string RemapVote_vote;
+float RemapVote(string vote, string cmd, entity e)
+{
+	float vote_argc;
+	entity victim;
+	vote_argc = tokenize_sane(vote);
+
+	print(">>", vote, "<<\n");
+
+	if(!VoteAllowed(argv(0)))
+	{
+		return FALSE;
+	}
+
+	// VoteAllowed tokenizes!
+	vote_argc = tokenize_sane(vote);
+
+	// remap chmap to gotomap (forces intermission)
+	if(vote_argc < 2)
+		if(argv(0) == "chmap" || argv(0) == "gotomap" || argv(0) == "kick" || argv(0) == "kickban") // won't work without arguments
+			return FALSE;
+	if(argv(0) == "chmap")
+		vote = strcat("gotomap ", substring(vote, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)));
+	if(argv(0) == "gotomap")
+	{
+		if(!(vote = ValidateMap(substring(vote, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)), e)))
+			return FALSE;
+		vote = strcat("gotomap ", vote);
+		vote_argc = tokenize_sane(vote); // ValidateMap may have done some stuff to it
+	}
+
+	// make kick and kickban votes a bit nicer (and reject them if formatted badly)
+	if(argv(0) == "kick" || argv(0) == "kickban")
+	{
+		if(!(victim = GetKickVoteVictim(vote, cmd, e)))
+			return FALSE;
+		RemapVote_vote = GetKickVoteVictim_newcommand;
+		RemapVote_display = strcat("^1", vote, " (^7", victim.netname, "^1): ", GetKickVoteVictim_reason);
+	}
+	else
+	{
+		RemapVote_vote = vote;
+		RemapVote_display = strzone(strcat("^1", vote));
+	}
+
+	return TRUE;
+}
+
 float GameCommand_Vote(string s, entity e) {
-	local entity victim;
+	tokenize_sane(s);
 	if(argv(0) == "help") {
 		print_to(e, "  vote COMMANDS ARGUMENTS. See 'vote help' for more info.");
 		return TRUE;
@@ -86,7 +132,7 @@
 					print_to(e, "^1There is already a vote called.");
 				} else {
 					local string vote;
-					vote = VoteParse();
+					vote = VoteParse(s);
 					if(vote == "") {
 						print_to(e, "^1Your vote is empty. See help for more info.");
 					} else if(e
@@ -94,37 +140,9 @@
 							print_to(e, strcat("^1You have to wait ^2", ftos(e.vote_next - time), "^1 seconds before you can again call a vote."));
 					} else if(VoteCheckNasty(vote)) {
 						print_to(e, "Syntax error in command. See help for more info.");
-					} else if(VoteAllowed(strcat1(argv(2)))) { // strcat seems to be necessary
-						// remap chmap to gotomap (forces intermission)
-						if(vote == "chmap" || vote == "gotomap") // won't work without arguments
-							return TRUE;
-						if(substring(vote, 0, 6) == "chmap ")
-							vote = strcat("gotomap ", substring(vote, 6, strlen(vote) - 6));
-						if(substring(vote, 0, 8) == "gotomap ")
-						{
-							if(!(vote = ValidateMap(substring(vote, 8, strlen(vote) - 8), e)))
-								return TRUE;
-							vote = strcat("gotomap ", vote);
-						}
-
-						// make kick and kickban votes a bit nicer (and reject them if formatted badly)
-						if(substring(vote, 0, 5) == "kick " || substring(vote, 0, 8) == "kickban ")
-						{
-							if(!(victim = GetKickVoteVictim(vote, "vcall", e)))
-								return TRUE;
-							vote = GetKickVoteVictim_newcommand;
-							votecalledvote_display = strzone(strcat("^1", vote, " (^7", victim.netname, "^1): ", GetKickVoteVictim_reason));
-						}
-						else if(vote == "kick" || vote == "kickban")
-						{
-							print_to(e, strcat("Usage: ", vote, " #playernumber (as in \"status\")\n"));
-							return TRUE;
-						}
-						else
-						{
-							votecalledvote_display = strzone(strcat("^1", vote));
-						}
-						votecalledvote = strzone(vote);
+					} else if(RemapVote(vote, "vcall", e)) {
+						votecalledvote = strzone(RemapVote_vote);
+						votecalledvote_display = strzone(RemapVote_display);
 						votecalled = TRUE;
 						votecalledmaster = FALSE;
 						votefinished = time + cvar("sv_vote_timeout");
@@ -183,41 +201,17 @@
 			}
 		} else if(argv(1) == "do") {
 			if(!e || e.vote_master) {
-				local string dovote, dovote_display;
-				dovote = VoteParse();
+				local string dovote;
+				dovote = VoteParse(s);
 				if(dovote == "") {
 					print_to(e, "^1Your command was empty. See help for more info.");
 				} else if(VoteCheckNasty(dovote)) {
 					print_to(e, "Syntax error in command. See help for more info.");
-				} else if(VoteAllowed(strcat1(argv(2)))) { // strcat seems to be necessary
-					if(dovote == "chmap" || dovote == "gotomap") // won't work without arguments
-						return TRUE;
-					if(substring(dovote, 0, 6) == "chmap ")
-						dovote = strcat("gotomap ", substring(dovote, 6, strlen(dovote) - 6));
-					if(substring(dovote, 0, 8) == "gotomap ")
-					{
-						if(!(dovote = ValidateMap(substring(dovote, 8, strlen(dovote) - 8), e)))
-							return TRUE;
-						dovote = strcat("gotomap ", dovote);
-					}
-
-					dovote_display = dovote;
-					if(substring(dovote, 0, 5) == "kick " || substring(dovote, 0, 8) == "kickban ")
-					{
-						if(!(victim = GetKickVoteVictim(dovote, "vdo", e)))
-							return TRUE;
-						dovote = GetKickVoteVictim_newcommand;
-						dovote_display = strcat("^1", dovote, " (^7", victim.netname, "^1): ", GetKickVoteVictim_reason);
-					}
-					else if(dovote == "kick" || dovote == "kickban")
-					{
-						print_to(e, strcat("Usage: ", dovote, " #playernumber (as in \"status\")\n"));
-						return TRUE;
-					}
-					bprint("\{1}^2* ^3", VoteNetname(e), "^2 used his ^3master^2 status to do \"^2", dovote_display, "^2\".\n");
+				} else if(RemapVote(dovote, "vdo", e)) { // strcat seems to be necessary
+					bprint("\{1}^2* ^3", VoteNetname(e), "^2 used his ^3master^2 status to do \"^2", RemapVote_display, "^2\".\n");
 					if(cvar("sv_eventlog"))
-						GameLogEcho(strcat(":vote:vdo:", ftos(e.playerid), ":", dovote_display));
-					localcmd(strcat(dovote, "\n"));
+						GameLogEcho(strcat(":vote:vdo:", ftos(e.playerid), ":", RemapVote_display));
+					localcmd(strcat(RemapVote_vote, "\n"));
 				} else {
 					print_to(e, "^1This command is not ok. See help for more info.");
 				}
@@ -378,21 +372,12 @@
 	}
 }
 
-string VoteParse() {
-	local float index;
-	index = 3;
-	local string vote;
-	vote = argv(2);
-	while(argv(index) != "") {
-		vote = strcat(vote, " ", argv(index));
-		++index;
-	}
-
-	return vote;
+string VoteParse(string all) {
+	return substring(all, argv_start_index(2), argv_end_index(-1) - argv_start_index(2));
 }
 
 float VoteAllowed(string votecommand) {
-	tokenize(cvar_string("sv_vote_commands"));
+	tokenize_sane(cvar_string("sv_vote_commands"));
 	local float index;
 	index = 0;
 	while(argv(index) != "") {

Modified: branches/nexuiz-2.0/data/qcsrc/server/vote.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/vote.qh	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/vote.qh	2008-10-11 15:11:15 UTC (rev 4731)
@@ -8,7 +8,7 @@
 string VoteNetname(entity e);
 string ValidateMap(string m, entity e);
 void VoteThink();
-string VoteParse();
+string VoteParse(string s);
 float VoteAllowed(string votecommand);
 void VoteReset();
 void VoteAccept();

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_common.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_common.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_common.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -28,6 +28,9 @@
 	local entity ent, endent;
 	local float endq3surfaceflags;
 	//local entity explosion;
+	
+	railgun_start = start;
+	railgun_end = end;
 
 	dir = normalize(end - start);
 	force = dir * bforce;
@@ -141,7 +144,7 @@
 	{
 		if (trace_ent.solid == SOLID_BSP && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
 		{
-			if (dtype == WEP_SHOTGUN)
+			if (dtype < DEATH_SPECIAL_START && (dtype & DEATH_WEAPONMASK) == WEP_SHOTGUN)
 				pointparticles(particleeffectnum("shotgun_impact"), trace_endpos, trace_plane_normal * 1000, 1);
 			else
 				pointparticles(particleeffectnum("machinegun_impact"), trace_endpos, trace_plane_normal * 1000, 1);

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_crylink.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_crylink.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_crylink.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -20,7 +20,7 @@
 		f = cvar("g_balance_crylink_primary_bouncedamagefactor");
 	if(self.alpha)
 		f *= self.alpha;
-	RadiusDamage (self, self.realowner, cvar("g_balance_crylink_primary_damage") * f, cvar("g_balance_crylink_primary_edgedamage") * f, cvar("g_balance_crylink_primary_radius"), world, cvar("g_balance_crylink_primary_force") * f, WEP_CRYLINK);
+	RadiusDamage (self, self.realowner, cvar("g_balance_crylink_primary_damage") * f, cvar("g_balance_crylink_primary_edgedamage") * f, cvar("g_balance_crylink_primary_radius"), world, cvar("g_balance_crylink_primary_force") * f, self.projectiledeathtype, other);
 	if (finalhit)
 	{
 		remove (self);
@@ -29,6 +29,7 @@
 	self.cnt = self.cnt - 1;
 	self.angles = vectoangles(self.velocity);
 	self.owner = world;
+	self.projectiledeathtype |= HITTYPE_BOUNCE;
 	//self.scale = 1 + self.cnt;
 }
 
@@ -49,7 +50,7 @@
 		f = cvar("g_balance_crylink_secondary_bouncedamagefactor");
 	if(self.alpha)
 		f *= self.alpha;
-	RadiusDamage (self, self.realowner, cvar("g_balance_crylink_secondary_damage") * f, cvar("g_balance_crylink_secondary_edgedamage") * f, cvar("g_balance_crylink_secondary_radius"), world, cvar("g_balance_crylink_secondary_force") * f, WEP_CRYLINK);
+	RadiusDamage (self, self.realowner, cvar("g_balance_crylink_secondary_damage") * f, cvar("g_balance_crylink_secondary_edgedamage") * f, cvar("g_balance_crylink_secondary_radius"), world, cvar("g_balance_crylink_secondary_force") * f, self.projectiledeathtype, other);
 	if (finalhit)
 	{
 		remove (self);
@@ -58,6 +59,7 @@
 	self.cnt = self.cnt - 1;
 	self.angles = vectoangles(self.velocity);
 	self.owner = world;
+	self.projectiledeathtype |= HITTYPE_BOUNCE;
 //	self.scale = 1 + 1 * self.cnt;
 }
 
@@ -84,6 +86,7 @@
 
 		proj.movetype = MOVETYPE_BOUNCEMISSILE;
 		proj.solid = SOLID_BBOX;
+		proj.projectiledeathtype = WEP_CRYLINK;
 		//proj.gravity = 0.001;
 
 		setmodel (proj, "models/plasmatrail.mdl"); // precision set below
@@ -148,6 +151,7 @@
 
 		proj.movetype = MOVETYPE_BOUNCEMISSILE;
 		proj.solid = SOLID_BBOX;
+		proj.projectiledeathtype = WEP_CRYLINK | HITTYPE_SECONDARY;
 		//proj.gravity = 0.001;
 
 		setmodel (proj, "models/plasmatrail.mdl"); // precision set below
@@ -191,7 +195,7 @@
 	trailparticles(world, particleeffectnum("lightning_beam", w_shotorg, trace_endpos);
 
 	if (trace_fraction < 1)
-		Damage(trace_ent, self, self, cvar("g_balance_crylink_primary_damage"), WEP_CRYLINK, trace_endpos, '0 0 0');
+		Damage(trace_ent, self, self, cvar("g_balance_crylink_primary_damage"), WEP_CRYLINK | HITTYPE_SECONDARY, trace_endpos, '0 0 0');
 }
 */
 
@@ -239,7 +243,18 @@
 		return self.ammo_cells >= cvar("g_balance_crylink_primary_ammo");
 	else if (req == WR_CHECKAMMO2)
 		return self.ammo_cells >= cvar("g_balance_crylink_secondary_ammo");
-	// else if (req == WR_SUICIDEMESSAGE) // TODO
-	// else if (req == WR_KILLMESSAGE) // TODO
+	else if (req == WR_SUICIDEMESSAGE)
+	{
+		w_deathtypestring = "succeeded at self-destructing himself with the Crylink";
+	}
+	else if (req == WR_KILLMESSAGE)
+	{
+		if(w_deathtype & HITTYPE_BOUNCE)
+			w_deathtypestring = "could not hide from #'s Crylink"; // unchecked: SPLASH (SECONDARY can't be)
+		else if(w_deathtype & HITTYPE_SPLASH)
+			w_deathtypestring = "was too close to #'s Crylink"; // unchecked: SECONDARY
+		else
+			w_deathtypestring = "took a close look at #'s Crylink"; // unchecked: SECONDARY
+	}
 	return TRUE;
 };

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_electro.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_electro.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_electro.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -8,12 +8,12 @@
 	if (self.movetype == MOVETYPE_BOUNCE)
 	{
 		pointparticles(particleeffectnum("electro_ballexplode"), org2, '0 0 0', 1);
-		RadiusDamage (self, self.owner, cvar("g_balance_electro_secondary_damage"), cvar("g_balance_electro_secondary_edgedamage"), cvar("g_balance_electro_secondary_radius"), world, cvar("g_balance_electro_secondary_force"), WEP_ELECTRO);
+		RadiusDamage (self, self.owner, cvar("g_balance_electro_secondary_damage"), cvar("g_balance_electro_secondary_edgedamage"), cvar("g_balance_electro_secondary_radius"), world, cvar("g_balance_electro_secondary_force"), self.projectiledeathtype, other);
 	}
 	else
 	{
 		pointparticles(particleeffectnum("electro_impact"), org2, '0 0 0', 1);
-		RadiusDamage (self, self.owner, cvar("g_balance_electro_primary_damage"), cvar("g_balance_electro_primary_edgedamage"), cvar("g_balance_electro_primary_radius"), world, cvar("g_balance_electro_primary_force"), WEP_ELECTRO);
+		RadiusDamage (self, self.owner, cvar("g_balance_electro_primary_damage"), cvar("g_balance_electro_primary_edgedamage"), cvar("g_balance_electro_primary_radius"), world, cvar("g_balance_electro_primary_force"), self.projectiledeathtype, other);
 	}
 	sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
 
@@ -29,7 +29,7 @@
 	sound (self, CHAN_PROJECTILE, "weapons/electro_impact_combo.wav", VOL_BASE, ATTN_NORM);
 
 	self.event_damage = SUB_Null;
-	RadiusDamage (self, self.owner, cvar("g_balance_electro_combo_damage"), cvar("g_balance_electro_combo_edgedamage"), cvar("g_balance_electro_combo_radius"), world, cvar("g_balance_electro_combo_force"), WEP_ELECTRO);
+	RadiusDamage (self, self.owner, cvar("g_balance_electro_combo_damage"), cvar("g_balance_electro_combo_edgedamage"), cvar("g_balance_electro_combo_radius"), world, cvar("g_balance_electro_combo_force"), WEP_ELECTRO | HITTYPE_BOUNCE, other); // use THIS type for a combo because primary can't bounce
 	remove (self);
 }
 
@@ -51,6 +51,7 @@
 					announce(o, "announcer/male/electrobitch.ogg");
 	} else {
 		sound (self, CHAN_PROJECTILE, "weapons/electro_bounce.wav", VOL_BASE, ATTN_NORM);
+		self.projectiledeathtype |= HITTYPE_BOUNCE;
 	}
 }
 
@@ -104,9 +105,11 @@
 	proj.owner = self;
 	proj.bot_dodge = TRUE;
 	proj.bot_dodgerating = cvar("g_balance_electro_primary_damage");
-	proj.think = W_Plasma_Explode;
+	proj.use = W_Plasma_Explode;
+	proj.think = adaptor_think2use;
 	proj.nextthink = time + cvar("g_balance_electro_primary_lifetime");
 	proj.solid = SOLID_BBOX;
+	proj.projectiledeathtype = WEP_ELECTRO;
 	setorigin(proj, w_shotorg);
 
 	if not(self.items & IT_UNLIMITED_AMMO)
@@ -136,11 +139,13 @@
 	proj = spawn ();
 	proj.classname = "plasma";
 	proj.owner = self;
-	proj.think = W_Plasma_Explode;
+	proj.use = W_Plasma_Explode;
+	proj.think = adaptor_think2use;
 	proj.bot_dodge = TRUE;
 	proj.bot_dodgerating = cvar("g_balance_electro_secondary_damage");
 	proj.nextthink = time + cvar("g_balance_electro_secondary_lifetime");
 	proj.solid = SOLID_BBOX;
+	proj.projectiledeathtype = WEP_ELECTRO | HITTYPE_SECONDARY;
 	setorigin(proj, w_shotorg);
 
 	if not(self.items & IT_UNLIMITED_AMMO)
@@ -231,7 +236,30 @@
 	else if (req == WR_CHECKAMMO2)
 		return self.ammo_cells >= cvar("g_balance_electro_secondary_ammo");
 	else if (req == WR_SUICIDEMESSAGE)
-		w_deathtypestring = "played with plasma";
-	// else if (req == WR_KILLMESSAGE) // TODO
+	{
+		if(w_deathtype & HITTYPE_SECONDARY)
+			w_deathtypestring = "could not remember where he put plasma";
+		else
+			w_deathtypestring = "played with plasma";
+	}
+	else if (req == WR_KILLMESSAGE)
+	{
+		if(w_deathtype & HITTYPE_SECONDARY)
+		{
+			if(w_deathtype & HITTYPE_SPLASH) // unchecked: BOUNCE
+				w_deathtypestring = "just noticed #'s blue ball";
+			else // unchecked: BOUNCE
+				w_deathtypestring = "got in touch with #'s blue ball";
+		}
+		else
+		{
+			if(w_deathtype & HITTYPE_BOUNCE) // combo
+				w_deathtypestring = "felt the electrifying air of #'s combo";
+			else if(w_deathtype & HITTYPE_SPLASH)
+				w_deathtypestring = "got too close to #'s blue beam";
+			else
+				w_deathtypestring = "was blasted by #'s blue beam";
+		}
+	}
 	return TRUE;
 };

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_grenadelauncher.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_grenadelauncher.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_grenadelauncher.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -6,7 +6,7 @@
 	sound (self, CHAN_PROJECTILE, "weapons/grenade_impact.wav", VOL_BASE, ATTN_NORM);
 
 	self.event_damage = SUB_Null;
-	RadiusDamage (self, self.owner, cvar("g_balance_grenadelauncher_primary_damage"), cvar("g_balance_grenadelauncher_primary_edgedamage"), cvar("g_balance_grenadelauncher_primary_radius"), world, cvar("g_balance_grenadelauncher_primary_force"), WEP_GRENADE_LAUNCHER);
+	RadiusDamage (self, self.owner, cvar("g_balance_grenadelauncher_primary_damage"), cvar("g_balance_grenadelauncher_primary_edgedamage"), cvar("g_balance_grenadelauncher_primary_radius"), world, cvar("g_balance_grenadelauncher_primary_force"), self.projectiledeathtype, other);
 
 	remove (self);
 }
@@ -19,7 +19,7 @@
 	sound (self, CHAN_PROJECTILE, "weapons/grenade_impact.wav", VOL_BASE, ATTN_NORM);
 
 	self.event_damage = SUB_Null;
-	RadiusDamage (self, self.owner, cvar("g_balance_grenadelauncher_secondary_damage"), cvar("g_balance_grenadelauncher_secondary_edgedamage"), cvar("g_balance_grenadelauncher_secondary_radius"), world, cvar("g_balance_grenadelauncher_secondary_force"), WEP_GRENADE_LAUNCHER);
+	RadiusDamage (self, self.owner, cvar("g_balance_grenadelauncher_secondary_damage"), cvar("g_balance_grenadelauncher_secondary_edgedamage"), cvar("g_balance_grenadelauncher_secondary_radius"), world, cvar("g_balance_grenadelauncher_secondary_force"), self.projectiledeathtype, other);
 
 	remove (self);
 }
@@ -42,7 +42,7 @@
 		return;
 	}
 	if (other.takedamage == DAMAGE_AIM)
-		self.think ();
+		self.use ();
 	else
 	{
 		float r;
@@ -59,6 +59,7 @@
 			sound (self, CHAN_PROJECTILE, "weapons/grenade_bounce5.wav", VOL_BASE, ATTN_NORM);
 		else
 			sound (self, CHAN_PROJECTILE, "weapons/grenade_bounce6.wav", VOL_BASE, ATTN_NORM);
+		self.projectiledeathtype |= HITTYPE_BOUNCE;
 	}
 }
 
@@ -91,13 +92,15 @@
 	gren.movetype = MOVETYPE_BOUNCE;
 	gren.solid = SOLID_BBOX;
 	gren.effects = EF_LOWPRECISION;
-	gren.modelflags = MF_GRENADE;
+	gren.modelflags = MF_TRACER2;
+	gren.projectiledeathtype = WEP_GRENADE_LAUNCHER;
 	setmodel(gren, "models/grenademodel.md3"); // precision set above
 	setsize(gren, '0 0 0', '0 0 0');
 	setorigin(gren, w_shotorg);
 
 	gren.nextthink = time + cvar("g_balance_grenadelauncher_primary_lifetime");
-	gren.think = W_Grenade_Explode;
+	gren.think = adaptor_think2use;
+	gren.use = W_Grenade_Explode;
 	gren.touch = W_Grenade_Touch1;
 	gren.velocity = w_shotdir * cvar("g_balance_grenadelauncher_primary_speed") + v_up * cvar("g_balance_grenadelauncher_primary_speed_up");
 	W_SetupProjectileVelocity(gren);
@@ -126,13 +129,15 @@
 	gren.movetype = MOVETYPE_BOUNCE;
 	gren.solid = SOLID_BBOX;
 	gren.effects = EF_LOWPRECISION;
-	gren.modelflags = MF_GRENADE;
+	gren.modelflags = MF_TRACER2;
+	gren.projectiledeathtype = WEP_GRENADE_LAUNCHER | HITTYPE_SECONDARY;
 	setmodel(gren, "models/grenademodel.md3"); // precision set above
 	setsize(gren, '0 0 -3', '0 0 -3');
 	setorigin(gren, w_shotorg);
 
 	gren.nextthink = time + cvar("g_balance_grenadelauncher_secondary_lifetime");
-	gren.think = W_Grenade_Explode2;
+	gren.think = adaptor_think2use;
+	gren.use = W_Grenade_Explode2;
 	gren.touch = W_Grenade_Touch2;
 	gren.takedamage = DAMAGE_YES;
 	gren.health = cvar("g_balance_grenadelauncher_secondary_health");
@@ -212,8 +217,21 @@
 	else if (req == WR_CHECKAMMO2)
 		return self.ammo_rockets >= cvar("g_balance_grenadelauncher_secondary_ammo");
 	else if (req == WR_SUICIDEMESSAGE)
-		w_deathtypestring = "detonated";
+	{
+		if(w_deathtype & HITTYPE_SECONDARY)
+			w_deathtypestring = "tried out his own grenade";
+		else
+			w_deathtypestring = "detonated";
+	}
 	else if (req == WR_KILLMESSAGE)
-		w_deathtypestring = "was blasted by";
+	{
+		if(w_deathtype & HITTYPE_SPLASH)
+			if(w_deathtype & HITTYPE_BOUNCE) // (must be secondary then)
+				w_deathtypestring = "didn't see #'s grenade";
+			else // unchecked: SECONDARY
+				w_deathtypestring = "almost dodged #'s grenade";
+		else // unchecked: SECONDARY, BOUNCE
+			w_deathtypestring = "ate #'s grenade";
+	}
 	return TRUE;
 };

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_hagar.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_hagar.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_hagar.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -13,7 +13,7 @@
 		sound (self, CHAN_PROJECTILE, "weapons/hagexp3.wav", VOL_BASE, ATTN_NORM);
 
 	self.event_damage = SUB_Null;
-	RadiusDamage (self, self.realowner, cvar("g_balance_hagar_primary_damage"), cvar("g_balance_hagar_primary_edgedamage"), cvar("g_balance_hagar_primary_radius"), world, cvar("g_balance_hagar_primary_force"), WEP_HAGAR);
+	RadiusDamage (self, self.realowner, cvar("g_balance_hagar_primary_damage"), cvar("g_balance_hagar_primary_edgedamage"), cvar("g_balance_hagar_primary_radius"), world, cvar("g_balance_hagar_primary_force"), self.projectiledeathtype, other);
 
 	remove (self);
 }
@@ -33,7 +33,7 @@
 		sound (self, CHAN_PROJECTILE, "weapons/hagexp3.wav", VOL_BASE, ATTN_NORM);
 
 	self.event_damage = SUB_Null;
-	RadiusDamage (self, self.realowner, cvar("g_balance_hagar_secondary_damage"), cvar("g_balance_hagar_secondary_edgedamage"), cvar("g_balance_hagar_secondary_radius"), world, cvar("g_balance_hagar_secondary_force"), WEP_HAGAR);
+	RadiusDamage (self, self.realowner, cvar("g_balance_hagar_secondary_damage"), cvar("g_balance_hagar_secondary_edgedamage"), cvar("g_balance_hagar_secondary_radius"), world, cvar("g_balance_hagar_secondary_force"), self.projectiledeathtype, other);
 
 	remove (self);
 }
@@ -48,7 +48,7 @@
 	if (other == self.owner)
 		return;
 
-	self.think ();
+	self.use ();
 }
 
 void W_Hagar_Touch2 (void)
@@ -60,12 +60,13 @@
 	}
 
 	if(self.cnt > 0 || other.takedamage == DAMAGE_AIM) {
-		self.think();
+		self.use();
 	} else {
 		self.cnt++;
 		pointparticles(particleeffectnum("hagar_bounce"), self.origin, self.velocity, 1);
 		self.angles = vectoangles (self.velocity);
 		self.owner = world;
+		self.projectiledeathtype |= HITTYPE_BOUNCE;
 	}
 }
 
@@ -93,10 +94,12 @@
 	missile.bot_dodge = TRUE;
 	missile.bot_dodgerating = cvar("g_balance_hagar_primary_damage");
 	missile.touch = W_Hagar_Touch;
-	missile.think = W_Hagar_Explode;
+	missile.use = W_Hagar_Explode;
+	missile.think = adaptor_think2use;
 	missile.nextthink = time + cvar("g_balance_hagar_primary_lifetime");
 	missile.solid = SOLID_BBOX;
 	missile.scale = 0.4; // BUG: the model is too big
+	missile.projectiledeathtype = WEP_HAGAR;
 	setorigin (missile, w_shotorg);
 	setmodel (missile, "models/hagarmissile.mdl"); // precision set below
 	setsize (missile, '0 0 0', '0 0 0');
@@ -133,10 +136,12 @@
 	missile.bot_dodgerating = cvar("g_balance_hagar_secondary_damage");
 	missile.touch = W_Hagar_Touch2;
 	missile.cnt = 0;
-	missile.think = W_Hagar_Explode;
+	missile.use = W_Hagar_Explode;
+	missile.think = adaptor_think2use;
 	missile.nextthink = time + cvar("g_balance_hagar_secondary_lifetime");
 	missile.solid = SOLID_BBOX;
 	missile.scale = 0.4; // BUG: the model is too big
+	missile.projectiledeathtype = WEP_HAGAR | HITTYPE_SECONDARY;
 	setorigin (missile, w_shotorg);
 	setmodel (missile, "models/hagarmissile.mdl"); // precision set below
 	setsize (missile, '0 0 0', '0 0 0');
@@ -203,8 +208,14 @@
 		return self.ammo_rockets >= cvar("g_balance_hagar_primary_ammo");
 	else if (req == WR_CHECKAMMO2)
 		return self.ammo_rockets >= cvar("g_balance_hagar_secondary_ammo");
-	// else if (req == WR_SUICIDEMESSAGE) // TODO
+	else if (req == WR_SUICIDEMESSAGE)
+		w_deathtypestring = "played with tiny rockets";
 	else if (req == WR_KILLMESSAGE)
-		w_deathtypestring = "was pummeled by";
+	{
+		if(w_deathtype & HITTYPE_BOUNCE) // must be secondary; unchecked: SPLASH
+			w_deathtypestring = "hoped #'s missiles wouldn't bounce";
+		else // unchecked: SPLASH, SECONDARY
+			w_deathtypestring = "was pummeled by";
+	}
 	return TRUE;
 };

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_laser.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_laser.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_laser.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -24,9 +24,9 @@
 
 	self.event_damage = SUB_Null;
 	if (self.dmg)
-		RadiusDamage (self, self.owner, cvar("g_balance_laser_secondary_damage"), cvar("g_balance_laser_secondary_edgedamage"), cvar("g_balance_laser_secondary_radius"), world, cvar("g_balance_laser_secondary_force"), WEP_LASER);
+		RadiusDamage (self, self.owner, cvar("g_balance_laser_secondary_damage"), cvar("g_balance_laser_secondary_edgedamage"), cvar("g_balance_laser_secondary_radius"), world, cvar("g_balance_laser_secondary_force"), self.projectiledeathtype, other);
 	else
-		RadiusDamage (self, self.owner, cvar("g_balance_laser_primary_damage"), cvar("g_balance_laser_primary_edgedamage"), cvar("g_balance_laser_primary_radius"), world, cvar("g_balance_laser_primary_force"), WEP_LASER);
+		RadiusDamage (self, self.owner, cvar("g_balance_laser_primary_damage"), cvar("g_balance_laser_primary_edgedamage"), cvar("g_balance_laser_primary_radius"), world, cvar("g_balance_laser_primary_force"), self.projectiledeathtype, other);
 	sound (self, CHAN_PROJECTILE, "weapons/laserimpact.wav", VOL_BASE, ATTN_NORM);
 
 	remove (self);
@@ -51,6 +51,9 @@
 
 	missile.movetype = MOVETYPE_FLY;
 	missile.solid = SOLID_BBOX;
+	missile.projectiledeathtype = WEP_LASER;
+	if(issecondary)
+		missile.projectiledeathtype |= HITTYPE_SECONDARY;
 
 	setmodel (missile, "models/laser.mdl"); // precision set below
 	setsize (missile, '0 0 0', '0 0 0');
@@ -133,7 +136,11 @@
 		return TRUE;
 	else if (req == WR_CHECKAMMO2)
 		return TRUE;
-	// else if (req == WR_SUICIDEMESSAGE) // TODO
-	// else if (req == WR_KILLMESSAGE) // TODO
+	else if (req == WR_SUICIDEMESSAGE)
+		w_deathtypestring = "lasered himself to hell";
+	else if (req == WR_KILLMESSAGE)
+	{
+		w_deathtypestring = "was lasered to death by"; // unchecked: SPLASH
+	}
 	return TRUE;
 };

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_minstanex.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_minstanex.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_minstanex.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -1,3 +1,5 @@
+.float minstanex_lasthit;
+
 void W_MinstaNex_Attack (void)
 {
 	float flying;
@@ -3,14 +5,31 @@
 	flying = IsFlying(self); // do this BEFORE to make the trace values from FireRailgunBullet last
 
-	W_SetupShot (self, '25 8 -4', TRUE, 5, "weapons/nexfire.wav");
+	W_SetupShot (self, '25 8 -4', TRUE, 5, "weapons/minstanexfire.wav");
 
 	yoda = 0;
+	damage_goodhits = 0;
+	headshot = 0;
 	FireRailgunBullet (w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, 10000, 800, WEP_MINSTANEX);
 
-	if(!g_minstagib)
-	if(yoda)
-	if(flying)
-		announce(self, "announcer/male/yoda.ogg");
+	if(g_minstagib)
+	{
+		if(yoda)
+			announce(self, "announcer/male/yoda.ogg");
+	}
+	else
+	{
+		if(yoda && flying)
+			announce(self, "announcer/male/yoda.ogg");
+		if(headshot)
+			announce(self, "announcer/male/headshot.ogg");
+		if(damage_goodhits && self.minstanex_lasthit)
+		{
+			if(announce(self, "announcer/male/impressive.ogg"))
+				damage_goodhits = 0; // only every second time
+		}
+	}
 
+	self.minstanex_lasthit = damage_goodhits;
+
 	pointparticles(particleeffectnum("nex_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
 
@@ -142,12 +161,15 @@
 		precache_model ("models/weapons/g_minstanex.md3");
 		precache_model ("models/weapons/v_minstanex.md3");
 		precache_model ("models/weapons/w_minstanex.zym");
-		precache_sound ("weapons/nexfire.wav");
+		precache_sound ("weapons/minstanexfire.wav");
 		precache_sound ("weapons/neximpact.wav");
 		w_laser(WR_PRECACHE);
 	}
 	else if (req == WR_SETUP)
+	{
 		weapon_setup(WEP_MINSTANEX);
+		self.minstanex_lasthit = 0;
+	}
 	else if (req == WR_CHECKAMMO1)
 	{
 		if (g_minstagib)

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_nex.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -8,8 +8,7 @@
 	yoda = 0;
 	FireRailgunBullet (w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, cvar("g_balance_nex_damage"), cvar("g_balance_nex_force"), WEP_NEX);
 
-	if(yoda)
-	if(flying)
+	if(yoda && flying)
 		announce(self, "announcer/male/yoda.ogg");
 
 	pointparticles(particleeffectnum("nex_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_porto.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_porto.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_porto.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -274,6 +274,6 @@
 	else if (req == WR_SUICIDEMESSAGE)
 		w_deathtypestring = "did the impossible";
 	else if (req == WR_KILLMESSAGE)
-		w_deathtypestring = "felt # doing the impossible";
+		w_deathtypestring = "felt # doing the impossible to him";
 	return TRUE;
 };

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_rocketlauncher.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_rocketlauncher.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_rocketlauncher.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -12,7 +12,7 @@
 
 	//effect (org2, "models/sprites/rockexpl.spr", 0, 12, 35);
 	self.event_damage = SUB_Null;
-	RadiusDamage (self, self.owner, cvar("g_balance_rocketlauncher_damage"), cvar("g_balance_rocketlauncher_edgedamage"), cvar("g_balance_rocketlauncher_radius"), world, cvar("g_balance_rocketlauncher_force"), WEP_ROCKET_LAUNCHER);
+	RadiusDamage (self, self.owner, cvar("g_balance_rocketlauncher_damage"), cvar("g_balance_rocketlauncher_edgedamage"), cvar("g_balance_rocketlauncher_radius"), world, cvar("g_balance_rocketlauncher_force"), self.projectiledeathtype, other);
 
 	if (self.owner.weapon == WEP_ROCKET_LAUNCHER)
 	{
@@ -89,6 +89,8 @@
 			: (vlen(NearestPointOnBox(self.owner, self.origin) - self.origin) > cvar("g_balance_rocketlauncher_radius")) // safety device
 		)
 		{
+			other = world;
+			self.projectiledeathtype |= HITTYPE_BOUNCE;
 			W_Rocket_Explode ();
 		}
 		else
@@ -105,6 +107,8 @@
 	self.nextthink = time;
 	if (time > self.cnt)
 	{
+		other = world;
+		self.projectiledeathtype |= HITTYPE_BOUNCE;
 		W_Rocket_Explode ();
 		return;
 	}
@@ -238,6 +242,7 @@
 
 	missile.movetype = MOVETYPE_FLY;
 	missile.solid = SOLID_BBOX;
+	missile.projectiledeathtype = WEP_ROCKET_LAUNCHER;
 	setmodel (missile, "models/rocket.md3"); // precision set below
 	setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
 
@@ -435,6 +440,13 @@
 	else if (req == WR_SUICIDEMESSAGE)
 		w_deathtypestring = "exploded";
 	else if (req == WR_KILLMESSAGE)
-		w_deathtypestring = "almost dodged #'s rocket";
+	{
+		if(w_deathtype & HITTYPE_BOUNCE) // (remote detonation)
+			w_deathtypestring = "got too close to #'s rocket";
+		else if(w_deathtype & HITTYPE_SPLASH)
+			w_deathtypestring = "almost dodged #'s rocket";
+		else
+			w_deathtypestring = "ate #'s rocket";
+	}
 	return TRUE;
 };

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_shotgun.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_shotgun.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_shotgun.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -58,7 +58,7 @@
 
 	W_SetupShot (self, '25 8 -8', TRUE, 5, "weapons/shotgun_fire.wav");
 	for (sc = 0;sc < bullets;sc = sc + 1)
-		fireBullet (w_shotorg, w_shotdir, spread, d, f, WEP_SHOTGUN, sc < 3);
+		fireBullet (w_shotorg, w_shotdir, spread, d, f, WEP_SHOTGUN | HITTYPE_SECONDARY, sc < 3);
 	if not(self.items & IT_UNLIMITED_AMMO)
 		self.ammo_shells = self.ammo_shells - cvar("g_balance_shotgun_secondary_ammo");
 
@@ -144,6 +144,8 @@
 	else if (req == WR_SUICIDEMESSAGE)
 		w_deathtypestring = "did the impossible";
 	else if (req == WR_KILLMESSAGE)
-		w_deathtypestring = "was gunned by";
+	{
+		w_deathtypestring = "was gunned by"; // unchecked: SECONDARY
+	}
 	return TRUE;
 };

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -11,7 +11,7 @@
 };
 
 .float uzi_bulletcounter;
-void W_Uzi_Attack (void)
+void W_Uzi_Attack (float deathtype)
 {
 	local entity flash, flash2;
 
@@ -34,9 +34,9 @@
 	ATTACK_FINISHED(self) = time + cvar("g_balance_uzi_first_refire");
 
 	if (self.uzi_bulletcounter == 1)
-		fireBullet (w_shotorg, w_shotdir, cvar("g_balance_uzi_first_spread"), cvar("g_balance_uzi_first_damage"), cvar("g_balance_uzi_first_force"), WEP_UZI, TRUE);
+		fireBullet (w_shotorg, w_shotdir, cvar("g_balance_uzi_first_spread"), cvar("g_balance_uzi_first_damage"), cvar("g_balance_uzi_first_force"), deathtype, TRUE);
 	else
-		fireBullet (w_shotorg, w_shotdir, cvar("g_balance_uzi_sustained_spread"), cvar("g_balance_uzi_sustained_damage"), cvar("g_balance_uzi_sustained_force"), WEP_UZI, (self.uzi_bulletcounter & 3) == 0);
+		fireBullet (w_shotorg, w_shotdir, cvar("g_balance_uzi_sustained_spread"), cvar("g_balance_uzi_sustained_damage"), cvar("g_balance_uzi_sustained_force"), deathtype, (self.uzi_bulletcounter & 3) == 0);
 
 	pointparticles(particleeffectnum("uzi_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
 
@@ -91,7 +91,7 @@
 		}
 		ATTACK_FINISHED(self) = time + cvar("g_balance_uzi_refire");
 		self.uzi_bulletcounter = self.uzi_bulletcounter + 1;
-		W_Uzi_Attack();
+		W_Uzi_Attack(WEP_UZI);
 		weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), uzi_fire1_02);
 	}
 	else
@@ -115,14 +115,14 @@
 		if (weapon_prepareattack(0, cvar("g_balance_uzi_refire")))
 		{
 			self.uzi_bulletcounter = 1;
-			W_Uzi_Attack();
+			W_Uzi_Attack(WEP_UZI);
 			weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), uzi_fire1_02);
 		}
 		if (self.BUTTON_ATCK2)
 		if (weapon_prepareattack(1, cvar("g_balance_uzi_refire")))
 		{
 			self.uzi_bulletcounter = 1;
-			W_Uzi_Attack();
+			W_Uzi_Attack(WEP_UZI | HITTYPE_SECONDARY);
 			weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), w_ready);
 		}
 	}
@@ -150,6 +150,11 @@
 	else if (req == WR_SUICIDEMESSAGE)
 		w_deathtypestring = "did the impossible";
 	else if (req == WR_KILLMESSAGE)
-		w_deathtypestring = "was riddled full of holes by";
+	{
+		if(w_deathtype & HITTYPE_SECONDARY)
+			w_deathtypestring = "was sniped by";
+		else
+			w_deathtypestring = "was riddled full of holes by";
+	}
 	return TRUE;
 };

Modified: branches/nexuiz-2.0/data/qcsrc/server/waypointsprites.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/waypointsprites.qc	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/qcsrc/server/waypointsprites.qc	2008-10-11 15:11:15 UTC (rev 4731)
@@ -168,9 +168,6 @@
 	WriteCoord(MSG_ENTITY, self.origin_y);
 	WriteCoord(MSG_ENTITY, self.origin_z);
 
-	if(self.model == "key-dropped")
-		print("flags: ", ftos(sendflags), "\n");
-
 	if(sendflags & 1)
 	{
 		WriteByte(MSG_ENTITY, self.team);

Modified: branches/nexuiz-2.0/data/scripts/entities.def
===================================================================
--- branches/nexuiz-2.0/data/scripts/entities.def	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/scripts/entities.def	2008-10-11 15:11:15 UTC (rev 4731)
@@ -51,6 +51,7 @@
 dmg: damage a player who gets crushed by it receives
 dmgtime: interval to apply dmg to a player who is s in the way
 message: death message when a player gets crushed
+message2: death message when someone gets pushed into this (default: "was thrown into a world of hurt by"). The # character is replaced by the attacker name if present (and it instead does not get appended to the end)
 -------- SPAWNFLAGS --------
 X_AXIS: entity will bob along the X axis.
 Y_AXIS: entity will bob along the Y axis.
@@ -71,7 +72,8 @@
 Normal sliding door entity. By default, the door will activate when player walks close to it or when damage is inflicted to it.
 If DOOR_DONT_LINK is not set, the door will be linked with all doors it touches.
 -------- KEYS --------
-message: is printed when the door is touched if it is a trigger door and it hasn't been fired yet
+message: is printed when the door is touched if it is a trigger door and it hasn't been fired yet, or death message if dmg is set
+message2: death message when someone gets pushed into this (default: "was thrown into a world of hurt by"). The # character is replaced by the attacker name if present (and it instead does not get appended to the end)
 angle: determines the opening direction
 targetname: if set, no touch field will be spawned and a remote button or trigger field activates the door.
 health: if set, door must be shot open
@@ -97,7 +99,8 @@
 t_width: override WIDTH to move back (or height if going down)
 t_length: override LENGTH to move sideways
 dmg: damage to inflict when blocked (2 default)
-message: text to display when activating the door
+message: text to display when activating the door, or death message if dmg is set
+message2: death message when someone gets pushed into this (default: "was thrown into a world of hurt by"). The # character is replaced by the attacker name if present (and it instead does not get appended to the end)
 noise1: sound when opening backwards or closing
 noise2: sound when opening sideways
 noise3: sound when stopping
@@ -140,6 +143,7 @@
 sound1: platform starts moving sound
 sound2: platform stop sound
 message: kill message, when someone gets killed by this plat
+message2: death message when someone gets pushed into this (default: "was thrown into a world of hurt by"). The # character is replaced by the attacker name if present (and it instead does not get appended to the end)
 -------- SPAWNFLAGS --------
 CRUSH: crush players hit by the platform instantly
 -------- NOTES --------
@@ -163,6 +167,7 @@
 dmg: Do this much dmg every .dmgtime interval when blocked
 dmgtime: See above. (0.25s default)
 message: kill message when crushed by this
+message2: death message when someone gets pushed into this (default: "was thrown into a world of hurt by"). The # character is replaced by the attacker name if present (and it instead does not get appended to the end)
 -------- SPAWNFLAGS --------
 X_AXIS: rotate around the X axis
 Y_AXIS: rotate around the Y axis
@@ -736,7 +741,8 @@
 Has the useful effect of automatically returning flags, keys and runes when they touch it.
 -------- KEYS --------
 dmg: amount of damage to deal (default: 1000)
-message: kill message when someone gets killed by this (default: "was in the wrong place.")
+message: kill message when someone gets killed by this (default: "was in the wrong place")
+message2: kill message when someone gets pushed into this (default: "was thrown into a world of hurt by"). The # character is replaced by the attacker name if present (and it instead does not get appended to the end)
 */
 
 /*QUAKED trigger_impulse (.5 .5 .5) ? 
@@ -955,6 +961,7 @@
 -------- KEYS --------
 cnt: Number of the checkpoint. 0 for finish line, and at least two other checkpoints have to exist. They MUST be touched in sequential order!
 message: Death message, when touching checkpoints in the wrong order.
+message2: Death message when someone gets pushed into this (default: "was thrown into a world of hurt by"). The # character is replaced by the attacker name if present (and it instead does not get appended to the end)
 targetname: Name of the checkpoint. info_player_race can target this to assign a spawn to a checkpoint. Also used for triggering a checkpoint by an event.
 target: when the checkpoint is passed, these entities are triggered. Useful for forcing items in certain areas using trigger_items
 -------- SPAWNFLAGS --------

Copied: branches/nexuiz-2.0/data/sound/weapons/minstanexfire.ogg (from rev 4730, trunk/data/sound/weapons/minstanexfire.ogg)
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/weapons.cfg
===================================================================
--- branches/nexuiz-2.0/data/weapons.cfg	2008-10-11 15:07:20 UTC (rev 4730)
+++ branches/nexuiz-2.0/data/weapons.cfg	2008-10-11 15:11:15 UTC (rev 4731)
@@ -223,3 +223,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




More information about the nexuiz-commits mailing list