r4789 - in branches/nexuiz-2.0: . Docs/server data data/gfx data/maps data/maps/bloodprisonctf data/models/turrets data/qcsrc/client data/qcsrc/common data/qcsrc/menu/nexuiz data/qcsrc/server data/scripts data/sound/announcer/male data/sound/misc

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Mon Oct 20 09:27:34 EDT 2008


Author: div0
Date: 2008-10-20 09:27:34 -0400 (Mon, 20 Oct 2008)
New Revision: 4789

Added:
   branches/nexuiz-2.0/data/models/turrets/aabody_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/aabody_norm.tga
   branches/nexuiz-2.0/data/models/turrets/aagun_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/aagun_norm.tga
   branches/nexuiz-2.0/data/models/turrets/base_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/base_norm.tga
   branches/nexuiz-2.0/data/models/turrets/basedestroyed_norm.tga
   branches/nexuiz-2.0/data/models/turrets/mgbody_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/mgbody_norm.tga
   branches/nexuiz-2.0/data/models/turrets/mggun_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/mggun_norm.tga
   branches/nexuiz-2.0/data/models/turrets/mlrs_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/mlrs_norm.tga
   branches/nexuiz-2.0/data/models/turrets/phaserbody_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/phaserbody_norm.tga
   branches/nexuiz-2.0/data/models/turrets/phasermag_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/phasermag_norm.tga
   branches/nexuiz-2.0/data/models/turrets/plasmabody_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/plasmabody_norm.tga
   branches/nexuiz-2.0/data/models/turrets/plasmagun_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/plasmagun_norm.tga
   branches/nexuiz-2.0/data/models/turrets/reactor_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/reactor_norm.tga
   branches/nexuiz-2.0/data/models/turrets/rlbody_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/rlbody_norm.tga
   branches/nexuiz-2.0/data/models/turrets/rldouble_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/rldouble_norm.tga
   branches/nexuiz-2.0/data/models/turrets/rlgun_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/rlgun_norm.tga
   branches/nexuiz-2.0/data/models/turrets/rocket_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/rocket_norm.tga
   branches/nexuiz-2.0/data/models/turrets/tesla_gloss.tga
   branches/nexuiz-2.0/data/models/turrets/tesla_norm.tga
   branches/nexuiz-2.0/data/qcsrc/server/g_hook.qh
   branches/nexuiz-2.0/data/sound/announcer/male/airshot.ogg
   branches/nexuiz-2.0/data/sound/announcer/male/headshot.ogg
   branches/nexuiz-2.0/data/sound/announcer/male/impressive.ogg
   branches/nexuiz-2.0/data/sound/misc/typehit.wav
Removed:
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0016.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0017.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0018.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0019.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0020.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0021.tga
Modified:
   branches/nexuiz-2.0/.patchsets
   branches/nexuiz-2.0/Docs/server/server.cfg
   branches/nexuiz-2.0/data/build-compat-pack.sh
   branches/nexuiz-2.0/data/defaultNexuiz.cfg
   branches/nexuiz-2.0/data/gfx/sb_playercolor_base.tga
   branches/nexuiz-2.0/data/gfx/sb_playercolor_pants.tga
   branches/nexuiz-2.0/data/gfx/sb_playercolor_shirt.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf.bsp
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0000.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0001.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0002.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0003.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0004.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0005.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0006.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0007.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0008.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0009.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0010.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0011.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0012.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0013.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0014.tga
   branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0015.tga
   branches/nexuiz-2.0/data/maps/dismal.mapinfo
   branches/nexuiz-2.0/data/nexuiz-credits.txt
   branches/nexuiz-2.0/data/qcsrc/client/main.qh
   branches/nexuiz-2.0/data/qcsrc/client/sbar.qc
   branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc
   branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc
   branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qh
   branches/nexuiz-2.0/data/qcsrc/common/util.qc
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_create.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc
   branches/nexuiz-2.0/data/qcsrc/server/antilag.qc
   branches/nexuiz-2.0/data/qcsrc/server/antilag.qh
   branches/nexuiz-2.0/data/qcsrc/server/bots.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/cl_weaponsystem.qc
   branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
   branches/nexuiz-2.0/data/qcsrc/server/constants.qh
   branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
   branches/nexuiz-2.0/data/qcsrc/server/defs.qh
   branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
   branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc
   branches/nexuiz-2.0/data/qcsrc/server/g_subs.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/miscfunctions.qc
   branches/nexuiz-2.0/data/qcsrc/server/progs.src
   branches/nexuiz-2.0/data/qcsrc/server/runematch.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/target_spawn.qc
   branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
   branches/nexuiz-2.0/data/qcsrc/server/vote.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_common.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_minstanex.qc
   branches/nexuiz-2.0/data/scripts/entities.def
Log:
r4752 | morphed | 2008-10-14 18:45:21 +0200 (Tue, 14 Oct 2008) | 1 line
normal maps and gloss maps for turrets
r4753 | div0 | 2008-10-14 19:56:21 +0200 (Tue, 14 Oct 2008) | 2 lines
fix minstagib out of ammo
r4754 | div0 | 2008-10-14 20:45:40 +0200 (Tue, 14 Oct 2008) | 2 lines
fix antilag 2
r4755 | div0 | 2008-10-14 21:01:04 +0200 (Tue, 14 Oct 2008) | 2 lines
record more antilag frames
r4756 | div0 | 2008-10-14 21:22:00 +0200 (Tue, 14 Oct 2008) | 2 lines
antilag: add mode 3 (old 1) and 1 (current 1 without relying on prydon cursor)
r4757 | div0 | 2008-10-14 21:27:40 +0200 (Tue, 14 Oct 2008) | 2 lines
more bot colors
r4758 | div0 | 2008-10-14 21:29:02 +0200 (Tue, 14 Oct 2008) | 2 lines
menu should set antilag 2 too
r4759 | div0 | 2008-10-14 21:44:46 +0200 (Tue, 14 Oct 2008) | 2 lines
random does not ceil. Fixed.
r4760 | div0 | 2008-10-15 07:54:29 +0200 (Wed, 15 Oct 2008) | 2 lines
MirceaKitsune's color icons, and code to put them in front of the player name
r4761 | div0 | 2008-10-15 07:59:53 +0200 (Wed, 15 Oct 2008) | 2 lines
add the width of a space between icons and text of the same column
r4762 | div0 | 2008-10-15 08:07:01 +0200 (Wed, 15 Oct 2008) | 2 lines
fix this code :)
r4763 | div0 | 2008-10-16 11:56:34 +0200 (Thu, 16 Oct 2008) | 4 lines
more sounds by tenshihan: male/impressive, male/airshot, male/headshot, misc/typehit
airshot still unused (maybe replace electrobitch, or yoda?)
r4764 | div0 | 2008-10-16 12:44:32 +0200 (Thu, 16 Oct 2008) | 2 lines
allow target_spawn to edit entities too
r4765 | div0 | 2008-10-16 13:51:57 +0200 (Thu, 16 Oct 2008) | 2 lines
bugfix target_spawn, and change docs to match it
r4766 | div0 | 2008-10-16 15:19:12 +0200 (Thu, 16 Oct 2008) | 2 lines
move antilag recording to the known working place again... SV_PlayerPhysics contains the wrong time
r4767 | div0 | 2008-10-16 15:22:11 +0200 (Thu, 16 Oct 2008) | 2 lines
add the sounds to the compat pack
r4768 | div0 | 2008-10-16 15:23:09 +0200 (Thu, 16 Oct 2008) | 2 lines
no change, but some helper macros fro death types
r4769 | div0 | 2008-10-16 15:48:07 +0200 (Thu, 16 Oct 2008) | 2 lines
fix bug that allowed ALL votes...
r4770 | div0 | 2008-10-16 15:51:55 +0200 (Thu, 16 Oct 2008) | 2 lines
undo the last change, instead make argv force a tempstring to be returned to fix this once and for all
r4771 | div0 | 2008-10-16 17:36:56 +0200 (Thu, 16 Oct 2008) | 2 lines
use "airshot" for in-air mortar hit
r4772 | div0 | 2008-10-16 17:52:35 +0200 (Thu, 16 Oct 2008) | 2 lines
delay teamkill sound
r4773 | div0 | 2008-10-16 17:59:53 +0200 (Thu, 16 Oct 2008) | 2 lines
play complaint a bit earlier
r4774 | div0 | 2008-10-16 18:24:26 +0200 (Thu, 16 Oct 2008) | 2 lines
and 0.1s more again...
r4775 | div0 | 2008-10-17 15:56:24 +0200 (Fri, 17 Oct 2008) | 2 lines
fix max fields check
r4776 | div0 | 2008-10-17 15:57:21 +0200 (Fri, 17 Oct 2008) | 2 lines
fix it again, correctly this time :P
r4777 | div0 | 2008-10-17 16:58:31 +0200 (Fri, 17 Oct 2008) | 2 lines
add a way to hide maps from the menu in mapinfo (campaign should still be able to use them then)
r4778 | div0 | 2008-10-18 19:05:32 +0200 (Sat, 18 Oct 2008) | 5 lines
-sv_vote_simple_majority
+sv_vote_simple_majority_factor
Allows to win a vote by either 2/3 majority of the voters, OR 1/2 majority of the players.
r4779 | div0 | 2008-10-18 19:08:08 +0200 (Sat, 18 Oct 2008) | 2 lines
new simple majority method
r4780 | div0 | 2008-10-18 19:09:18 +0200 (Sat, 18 Oct 2008) | 2 lines
majority explained
r4781 | div0 | 2008-10-18 19:10:35 +0200 (Sat, 18 Oct 2008) | 2 lines
more stuff :P
r4782 | div0 | 2008-10-18 19:14:35 +0200 (Sat, 18 Oct 2008) | 2 lines
fix comment :P
r4783 | div0 | 2008-10-18 23:37:22 +0200 (Sat, 18 Oct 2008) | 2 lines
add cl_zoomsensitivity to the menu
r4784 | div0 | 2008-10-18 23:54:14 +0200 (Sat, 18 Oct 2008) | 2 lines
add reverse ctf
r4785 | div0 | 2008-10-18 23:56:01 +0200 (Sat, 18 Oct 2008) | 2 lines
forgot these two files
r4786 | div0 | 2008-10-19 00:00:50 +0200 (Sun, 19 Oct 2008) | 2 lines
switch icons in reverse ctf ;)
r4787 | div0 | 2008-10-19 21:08:32 +0200 (Sun, 19 Oct 2008) | 2 lines
hook code cleanup. Should simplify a later change to an onhand hook.
r4788 | div0 | 2008-10-19 21:10:11 +0200 (Sun, 19 Oct 2008) | 2 lines
oops, remove debug code :P


Modified: branches/nexuiz-2.0/.patchsets
===================================================================
--- branches/nexuiz-2.0/.patchsets	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/.patchsets	2008-10-20 13:27:34 UTC (rev 4789)
@@ -1,2 +1,2 @@
 master = svn://svn.icculus.org/nexuiz/trunk
-revisions_applied = 1-4750
+revisions_applied = 1-4788

Modified: branches/nexuiz-2.0/Docs/server/server.cfg
===================================================================
--- branches/nexuiz-2.0/Docs/server/server.cfg	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/Docs/server/server.cfg	2008-10-20 13:27:34 UTC (rev 4789)
@@ -88,8 +88,9 @@
 //sv_vote_call 1 // 0 will disable the normal voting
 //sv_vote_master 1 // 0 will disable voting to become masters
 //sv_vote_master_password "" // when set, vdo login master will allow you to run votable commands directly using vdo
-//sv_vote_simple_majority 0 // 1 will make votes succeed if there are more yes than no votes.  with 0 (default), more than half of the players have to say yes
 //sv_vote_majority_factor 0.5 // 0.666 will require a 2/3 majority instead of a regular 1/2 one
+//sv_vote_simple_majority_factor 0 // 0.666 will win votes by a 2/3 majority of the VOTERS (not the players!)
+//note: to JUST support simple majorities, set these two factors equal
 
 /////////////////////////////////////////////////////////////////////
 // Some more advanced settings.  You probably are not interested in changing them at all.

Modified: branches/nexuiz-2.0/data/build-compat-pack.sh
===================================================================
--- branches/nexuiz-2.0/data/build-compat-pack.sh	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/build-compat-pack.sh	2008-10-20 13:27:34 UTC (rev 4789)
@@ -22,6 +22,9 @@
 	gfx/runningman_mini.tga
 	gfx/sb_kh_full.tga
 	gfx/sb_kh_outline.tga
+	gfx/sb_playercolor_base.tga
+	gfx/sb_playercolor_shirt.tga
+	gfx/sb_playercolor_pants.tga
 	gfx/silvercity_mini.tga
 	gfx/stormkeep_mini.tga
 	gfx/strength_mini.tga
@@ -70,6 +73,10 @@
 	models/weapons/w_minstanex.zym
 	models/weapons/w_porto.zym
 	particles/particlefont.tga
+	sound/announcer/male/impressive.ogg
+	sound/announcer/male/airshot.ogg
+	sound/announcer/male/headshot.ogg
+	sound/misc/typehit.wav
 	sound/player/default.sounds
 	sound/player/torus/attack.ogg
 	sound/player/torus/coverme.ogg

Modified: branches/nexuiz-2.0/data/defaultNexuiz.cfg
===================================================================
--- branches/nexuiz-2.0/data/defaultNexuiz.cfg	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/defaultNexuiz.cfg	2008-10-20 13:27:34 UTC (rev 4789)
@@ -268,7 +268,7 @@
 
 locs_enable 0
 pausable 0
-set g_antilag 1
+set g_antilag 2 // 1: re-aim to enemy that was aimed at in the past, 2: shoot completely in the past, 3: client-side hitscan
 set g_shootfromeye 0
 set g_shootfromcenter 0
 set g_weapon_stay 0
@@ -392,6 +392,7 @@
 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_ctf_reverse 0 // when 1, bases/flags are switched :P you have to capture your OWN flag by bringing it to the ENEMY's
 set g_balance_ctf_delay_collect 1.0
 set g_balance_ctf_damageforcescale 1
                                                
@@ -732,10 +733,11 @@
 set sv_vote_timeout 60
 // a player can not call a vote again for this many seconds
 set sv_vote_wait 120
-// a simple majority suffices to accept a vote (meaning: YES votes > NO votes, otherwise: YES votes > half of the players)
-set sv_vote_simple_majority 0
-// which quotient of the players constitute a majority? (try: 0.667, 0.75 when using the above)
+// which quotient of the PLAYERS constitute a majority? (try: 0.667, 0.75 when using the above)
 set sv_vote_majority_factor 0.5
+// which quotient of the VOTERS constitute a majority too? (0 = off, otherwise it must be higher than or equal to sv_vote_majority_factor)
+set sv_vote_simple_majority_factor 0
+// note: set these two equal to JUST support simple majorities
 // when disabled, don't allow game type changes
 set sv_vote_override_mostrecent 0
 alias vhelp "cmd vote help"
@@ -1158,3 +1160,5 @@
 seta cl_teamradar_position "0 0" // 1 1 would be lower right corner, 0.5 0.5 the center (ARGH) :P
 seta cl_teamradar_zoommode 0 // zoom mode: 0 = zoomed by default, 1 = zoomed when +zoom, 2 = always zoomed, 3 = always zoomed out
 alias cl_teamradar_rotate "toggle cl_teamradar_rotation 0 1 2 3 4"
+
+set g_maplist_allow_hidden 1 // allow hidden maps to be, e.g., voted for and in the maplist

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

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

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

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0000.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0001.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0002.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0003.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0004.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0005.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0006.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0007.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0008.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0009.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0010.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0011.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0012.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0013.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0014.tga
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0015.tga
===================================================================
(Binary files differ)

Deleted: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0016.tga
===================================================================
(Binary files differ)

Deleted: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0017.tga
===================================================================
(Binary files differ)

Deleted: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0018.tga
===================================================================
(Binary files differ)

Deleted: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0019.tga
===================================================================
(Binary files differ)

Deleted: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0020.tga
===================================================================
(Binary files differ)

Deleted: branches/nexuiz-2.0/data/maps/bloodprisonctf/lm_0021.tga
===================================================================
(Binary files differ)

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

Modified: branches/nexuiz-2.0/data/maps/dismal.mapinfo
===================================================================
--- branches/nexuiz-2.0/data/maps/dismal.mapinfo	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/maps/dismal.mapinfo	2008-10-20 13:27:34 UTC (rev 4789)
@@ -11,3 +11,4 @@
 type rune 200 20
 type lms 9 20
 cdtrack 7
+hidden

Copied: branches/nexuiz-2.0/data/models/turrets/aabody_gloss.tga (from rev 4762, trunk/data/models/turrets/aabody_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/aabody_norm.tga (from rev 4762, trunk/data/models/turrets/aabody_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/aagun_gloss.tga (from rev 4762, trunk/data/models/turrets/aagun_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/aagun_norm.tga (from rev 4762, trunk/data/models/turrets/aagun_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/base_gloss.tga (from rev 4762, trunk/data/models/turrets/base_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/base_norm.tga (from rev 4762, trunk/data/models/turrets/base_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/basedestroyed_norm.tga (from rev 4762, trunk/data/models/turrets/basedestroyed_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/mgbody_gloss.tga (from rev 4762, trunk/data/models/turrets/mgbody_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/mgbody_norm.tga (from rev 4762, trunk/data/models/turrets/mgbody_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/mggun_gloss.tga (from rev 4762, trunk/data/models/turrets/mggun_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/mggun_norm.tga (from rev 4762, trunk/data/models/turrets/mggun_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/mlrs_gloss.tga (from rev 4762, trunk/data/models/turrets/mlrs_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/mlrs_norm.tga (from rev 4762, trunk/data/models/turrets/mlrs_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/phaserbody_gloss.tga (from rev 4762, trunk/data/models/turrets/phaserbody_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/phaserbody_norm.tga (from rev 4762, trunk/data/models/turrets/phaserbody_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/phasermag_gloss.tga (from rev 4762, trunk/data/models/turrets/phasermag_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/phasermag_norm.tga (from rev 4762, trunk/data/models/turrets/phasermag_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/plasmabody_gloss.tga (from rev 4762, trunk/data/models/turrets/plasmabody_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/plasmabody_norm.tga (from rev 4762, trunk/data/models/turrets/plasmabody_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/plasmagun_gloss.tga (from rev 4762, trunk/data/models/turrets/plasmagun_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/plasmagun_norm.tga (from rev 4762, trunk/data/models/turrets/plasmagun_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/reactor_gloss.tga (from rev 4762, trunk/data/models/turrets/reactor_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/reactor_norm.tga (from rev 4762, trunk/data/models/turrets/reactor_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/rlbody_gloss.tga (from rev 4762, trunk/data/models/turrets/rlbody_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/rlbody_norm.tga (from rev 4762, trunk/data/models/turrets/rlbody_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/rldouble_gloss.tga (from rev 4762, trunk/data/models/turrets/rldouble_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/rldouble_norm.tga (from rev 4762, trunk/data/models/turrets/rldouble_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/rlgun_gloss.tga (from rev 4762, trunk/data/models/turrets/rlgun_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/rlgun_norm.tga (from rev 4762, trunk/data/models/turrets/rlgun_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/rocket_gloss.tga (from rev 4762, trunk/data/models/turrets/rocket_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/rocket_norm.tga (from rev 4762, trunk/data/models/turrets/rocket_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/tesla_gloss.tga (from rev 4762, trunk/data/models/turrets/tesla_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/models/turrets/tesla_norm.tga (from rev 4762, trunk/data/models/turrets/tesla_norm.tga)
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/nexuiz-credits.txt
===================================================================
--- branches/nexuiz-2.0/data/nexuiz-credits.txt	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/nexuiz-credits.txt	2008-10-20 13:27:34 UTC (rev 4789)
@@ -131,3 +131,4 @@
 Christian Ice
 FruitieX
 Edward "Ed" Holness
+MirceaKitsune

Modified: branches/nexuiz-2.0/data/qcsrc/client/main.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/main.qh	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/client/main.qh	2008-10-20 13:27:34 UTC (rev 4789)
@@ -74,8 +74,7 @@
 #define SP_KDRATIO -4
 #define SP_CLRATIO -5
 #define SP_PL -6
-#define SP_COLOR -7
-#define SP_FRAGS -8
+#define SP_FRAGS -7
 
 #define SP_SEPARATOR -100
 

Modified: branches/nexuiz-2.0/data/qcsrc/client/sbar.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/sbar.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/client/sbar.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -400,7 +400,6 @@
 	}
 		
 	
-	argc = min(MAX_SBAR_FIELDS, argc);
 	sbar_num_fields = 0;
 
 	drawfont = sbar_font;
@@ -412,8 +411,7 @@
 	else
 		subpattern2 = ",noteams,";
 
-	argc = min(argc-1, MAX_SBAR_FIELDS-1);
-	for(i = 0; i < argc; ++i)
+	for(i = 0; i < argc - 1; ++i)
 	{
 		str = argv(i+1);
 
@@ -452,11 +450,6 @@
 			sbar_field[sbar_num_fields] = SP_PL;
 		} else if(str == "kd" || str == "kdr" || str == "kdratio" || str == "k/d") {
 			sbar_field[sbar_num_fields] = SP_KDRATIO;
-		} else if(str == "color") {
-			if(!teamplay)
-				sbar_field[sbar_num_fields] = SP_COLOR;
-			else
-				continue; // can't put this column in teamplay, it is redundant and stupid
 		} else if(str == "name" || str == "nick") {
 			sbar_field[sbar_num_fields] = SP_NAME;
 			sbar_size[sbar_num_fields] = MIN_NAMELEN; // minimum size? any use?
@@ -486,6 +479,8 @@
 				have_secondary = 1;
 		}
 		++sbar_num_fields;
+		if(sbar_num_fields >= MAX_SBAR_FIELDS)
+			break;
 	}
 
 	if(scores_flags[ps_primary] & SFL_ALLOW_HIDE)
@@ -611,6 +606,15 @@
 			return str;
 		
 		case SP_NAME:
+			if(!teamplay)
+			{
+				f = stof(getplayerkey(pl.sv_entnum, "colors"));
+				sbar_field_icon0 = "gfx/sb_playercolor_base";
+				sbar_field_icon1 = "gfx/sb_playercolor_shirt";
+				sbar_field_icon1_rgb = colormapPaletteColor(floor(f / 16), 0);
+				sbar_field_icon2 = "gfx/sb_playercolor_pants";
+				sbar_field_icon2_rgb = colormapPaletteColor(mod(f, 16), 1);
+			}
 			return getplayerkey(pl.sv_entnum, "name");
 
 		case SP_FRAGS:
@@ -618,15 +622,6 @@
 			f -= pl.(scores[SP_SUICIDES]);
 			return ftos(f);
 
-		case SP_COLOR:
-			f = stof(getplayerkey(pl.sv_entnum, "colors"));
-			sbar_field_icon0 = "gfx/sb_playercolor_base";
-			sbar_field_icon1 = "gfx/sb_playercolor_shirt";
-			sbar_field_icon1_rgb = colormapPaletteColor(floor(f / 16), 0);
-			sbar_field_icon2 = "gfx/sb_playercolor_pants";
-			sbar_field_icon2_rgb = colormapPaletteColor(mod(f, 16), 1);
-			return "";
-
 		case SP_KDRATIO:
 			num = pl.(scores[SP_KILLS]);
 			denom = pl.(scores[SP_DEATHS]);
@@ -703,10 +698,11 @@
 float xmin, xmax, ymin, ymax, sbwidth;
 float sbar_fixscoreboardcolumnwidth_len;
 float sbar_fixscoreboardcolumnwidth_iconlen;
+float sbar_fixscoreboardcolumnwidth_marginlen;
 
 string Sbar_FixScoreboardColumnWidth(float i, string str)
 {
-	float field, maxsize, j;
+	float field, maxsize, j, f;
 	vector sz;
 	field = sbar_field[i];
 
@@ -727,33 +723,38 @@
 	if(sbar_field_icon0 != "")
 	{
 		sz = drawgetimagesize(sbar_field_icon0);
-		if(sbar_fixscoreboardcolumnwidth_iconlen < sz_x / sz_y)
-			sbar_fixscoreboardcolumnwidth_iconlen = sz_x / sz_y;
+		f = sz_x / sz_y;
+		if(sbar_fixscoreboardcolumnwidth_iconlen < f)
+			sbar_fixscoreboardcolumnwidth_iconlen = f;
 	}
 
 	if(sbar_field_icon1 != "")
 	{
 		sz = drawgetimagesize(sbar_field_icon1);
-		if(sbar_fixscoreboardcolumnwidth_iconlen < sz_x / sz_y)
-			sbar_fixscoreboardcolumnwidth_iconlen = sz_x / sz_y;
+		f = sz_x / sz_y;
+		if(sbar_fixscoreboardcolumnwidth_iconlen < f)
+			sbar_fixscoreboardcolumnwidth_iconlen = f;
 	}
 
 	if(sbar_field_icon2 != "")
 	{
 		sz = drawgetimagesize(sbar_field_icon2);
-		if(sbar_fixscoreboardcolumnwidth_iconlen < sz_x / sz_y)
-			sbar_fixscoreboardcolumnwidth_iconlen = sz_x / sz_y;
+		f = sz_x / sz_y;
+		if(sbar_fixscoreboardcolumnwidth_iconlen < f)
+			sbar_fixscoreboardcolumnwidth_iconlen = f;
 	}
 
 	sbar_fixscoreboardcolumnwidth_iconlen *= sbar_fontsize_y / sbar_fontsize_x; // fix icon aspect
 
-	if(sbar_size[i] < sbar_fixscoreboardcolumnwidth_len + sbar_fixscoreboardcolumnwidth_iconlen)
-	{
-		print("size: extended from ", ftos(sbar_size[i]), " to ");
-		sbar_size[i] = sbar_fixscoreboardcolumnwidth_len + sbar_fixscoreboardcolumnwidth_iconlen;
-		print(ftos(sbar_size[i]), "\n");
-	}
+	if(sbar_fixscoreboardcolumnwidth_iconlen != 0 && sbar_fixscoreboardcolumnwidth_len != 0)
+		sbar_fixscoreboardcolumnwidth_marginlen = stringwidth(" ", FALSE);
+	else
+		sbar_fixscoreboardcolumnwidth_marginlen = 0;
 
+	f = sbar_fixscoreboardcolumnwidth_len + sbar_fixscoreboardcolumnwidth_marginlen + sbar_fixscoreboardcolumnwidth_iconlen;
+	if(sbar_size[i] < f)
+		sbar_size[i] = f;
+
 	return str;
 }
 
@@ -791,7 +792,7 @@
 		pos_x += sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
 
 		if(field == SP_NAME) {
-			tmp_x = sbar_fontsize_x*(sbar_size[i] - sbar_fixscoreboardcolumnwidth_iconlen) + sbar_fontsize_x;
+			tmp_x = sbar_fontsize_x*(sbar_size[i] - sbar_fixscoreboardcolumnwidth_iconlen - sbar_fixscoreboardcolumnwidth_marginlen) + sbar_fontsize_x;
 			drawcolorcodedstring(pos - tmp, str, sbar_fontsize, 1, DRAWFLAG_NORMAL);
 		} else {
 			tmp_x = sbar_fixscoreboardcolumnwidth_len*sbar_fontsize_x + sbar_fontsize_x;

Modified: branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/common/gamecommand.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -127,7 +127,7 @@
 				//     to be on place n+1, their chance will be 1/(n+1)
 				//     1/n * n/(n+1) = 1/(n+1)
 				//     q.e.d.
-				f = ceil(random() * (i + 1)) - 1; // 0 to i
+				f = floor(random() * (i + 1)); // 0 to i
 				if(f == i)
 					continue; // no change
 
@@ -511,7 +511,7 @@
 					for(i = 0; i < f - 1; ++i) {
 						// move a random item from i..f-1 to position i
 						s = "";
-						f2 = ceil(random() * (f - i) + i) - 1;
+						f2 = floor(random() * (f - i) + i);
 						for(j = 0; j < i; ++j)
 							s = strcat(s, " ", argv(j));
 						s = strcat(s, " ", argv(f2));

Modified: branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -110,6 +110,7 @@
 	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, MapInfo_Map_author);
 	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, ftos(MapInfo_Map_supportedGametypes));
 	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, ftos(MapInfo_Map_supportedFeatures));
+	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, ftos(MapInfo_Map_flags));
 }
 
 float MapInfo_Cache_Retrieve(string map)
@@ -131,6 +132,7 @@
 	MapInfo_Map_author = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i);
 	MapInfo_Map_supportedGametypes = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i));
 	MapInfo_Map_supportedFeatures = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i));
+	MapInfo_Map_flags = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i));
 	return 1;
 }
 
@@ -164,7 +166,7 @@
 	return MapInfo_FilterList_Lookup(i);
 }
 
-string MapInfo_FilterGametype_Recursive(float pGametype, float pFeatures, float pBegin, float pEnd, float pAbortOnGenerate)
+string MapInfo_FilterGametype_Recursive(float pGametype, float pFeatures, float pFlagsRequired, float pFlagsForbidden, float pBegin, float pEnd, float pAbortOnGenerate)
 {
 	float m, valid;
 	string l, r;
@@ -183,8 +185,11 @@
 			MapInfo_progress = m / _MapInfo_globcount;
 			return string_null; // BAIL OUT
 		}
-	valid = (((MapInfo_Map_supportedGametypes & pGametype) != 0) && ((MapInfo_Map_supportedFeatures & pFeatures) == pFeatures));
-	r = MapInfo_FilterGametype_Recursive(pGametype, pFeatures, m + 1, pEnd, pAbortOnGenerate);
+	valid = (((MapInfo_Map_supportedGametypes & pGametype) != 0);
+	valid = valid && ((MapInfo_Map_supportedFeatures & pFeatures) == pFeatures));
+	valid = valid && (MapInfo_Map_flags & pFlagsForbidden == 0);
+	valid = valid && (MapInfo_Map_flags & pFlagsRequired == pFlagsRequired);
+	r = MapInfo_FilterGametype_Recursive(pGametype, pFeatures, pFlagsRequired, pFlagsForbidden, m + 1, pEnd, pAbortOnGenerate);
 	if not(r)
 		return string_null; // BAIL OUT
 
@@ -194,11 +199,11 @@
 		return HugeSetOfIntegers_concat(l, r);
 }
 
-float MapInfo_FilterGametype(float pGametype, float pFeatures, float pAbortOnGenerate)
+float MapInfo_FilterGametype(float pGametype, float pFeatures, pFlagsRequired, pFlagsForbidden, float pAbortOnGenerate)
 {
 	if(_MapInfo_filtered)
 		strunzone(_MapInfo_filtered);
-	_MapInfo_filtered = MapInfo_FilterGametype_Recursive(pGametype, pFeatures, 0, _MapInfo_globcount, pAbortOnGenerate);
+	_MapInfo_filtered = MapInfo_FilterGametype_Recursive(pGametype, pFeatures, pFlagsRequired, pFlagsForbidden, 0, _MapInfo_globcount, pAbortOnGenerate);
 	if not(_MapInfo_filtered)
 	{
 		dprint("Autogenerated a .mapinfo, doing the rest later.\n");
@@ -226,7 +231,7 @@
 	return stof(bufstr_get(_MapInfo_filtered, i));
 }
 
-float MapInfo_FilterGametype(float pGametype, float pFeatures, float pAbortOnGenerate)
+float MapInfo_FilterGametype(float pGametype, float pFeatures, float pFlagsRequired, float pFlagsForbidden, float pAbortOnGenerate)
 {
 	float i, j;
 	if not(_MapInfo_filtered_allocated)
@@ -244,7 +249,10 @@
 				MapInfo_progress = i / _MapInfo_globcount;
 				return 0;
 			}
-		if(((MapInfo_Map_supportedGametypes & pGametype) != 0) && ((MapInfo_Map_supportedFeatures & pFeatures) == pFeatures))
+		if((MapInfo_Map_supportedGametypes & pGametype) != 0)
+		if((MapInfo_Map_supportedFeatures & pFeatures) == pFeatures)
+		if((MapInfo_Map_flags & pFlagsForbidden) == 0)
+		if((MapInfo_Map_flags & pFlagsRequired) == pFlagsRequired)
 			bufstr_set(_MapInfo_filtered, ++j, ftos(i));
 	}
 	MapInfo_count = j + 1;
@@ -445,6 +453,7 @@
 	MapInfo_Map_author = "<AUTHOR>";
 	MapInfo_Map_supportedGametypes = 0;
 	MapInfo_Map_supportedFeatures = 0;
+	MapInfo_Map_flags = 0;
 	MapInfo_Map_clientstuff = "";
 	MapInfo_Map_fog = "";
 	MapInfo_Map_mins = '0 0 0';
@@ -543,7 +552,7 @@
 		fputs(fh, strcat("title ", MapInfo_Map_title, "\n"));
 		fputs(fh, strcat("description ", MapInfo_Map_description, "\n"));
 		fputs(fh, strcat("author ", MapInfo_Map_author, "\n"));
-		fputs(fh, strcat("cdtrack ", ftos(ceil(random() * 9 + 1)), "\n")); // track from 2 to 10
+		fputs(fh, strcat("cdtrack ", ftos(floor(random() * 9 + 2)), "\n")); // track from 2 to 10
 		if(MapInfo_Map_supportedFeatures & MAPINFO_FEATURE_WEAPONS)       fputs(fh, "has weapons\n");
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH)      fputs(fh, "type dm 30 20\n");
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_TEAM_DEATHMATCH) fputs(fh, "type tdm 50 20 2\n");
@@ -568,6 +577,7 @@
 		fputs(fh, "// optional: settemp_for_type (all|gametypename) cvarname value\n");
 		fputs(fh, "// optional: clientsettemp_for_type (all|gametypename) cvarname value\n");
 		fputs(fh, "// optional: size mins_x mins_y mins_z maxs_x maxs_y maxs_z\n");
+		fputs(fh, "// optional: hidden\n");
 
 		fclose(fh);
 		r = 2;
@@ -607,6 +617,10 @@
 			else
 				dprint("Map ", pFilename, " supports unknown feature ", t, ", ignored\n");
 		}
+		else if(t == "hidden")
+		{
+			MapInfo_Map_flags |= MAPINFO_FLAG_HIDDEN;
+		}
 		else if(t == "type")
 		{
 			t = car(s); s = cdr(s);
@@ -865,14 +879,14 @@
 	localcmd(strcat("\nsettemp_restore\nchangelevel ", s, "\n"));
 }
 
-string MapInfo_ListAllowedMaps()
+string MapInfo_ListAllowedMaps(float pRequiredFlags, float pForbiddenFlags)
 {
 	string out;
 	float i;
 
 	// to make absolutely sure:
 	MapInfo_Enumerate();
-	MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0);
+	MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), pRequiredFlags, pForbiddenFlags, 0);
 
 	out = "";
 	for(i = 0; i < MapInfo_count; ++i)

Modified: branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qh	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qh	2008-10-20 13:27:34 UTC (rev 4789)
@@ -13,6 +13,8 @@
 
 float MAPINFO_FEATURE_WEAPONS       = 1; // not defined for minstagib-only maps
 
+float MAPINFO_FLAG_HIDDEN           = 1; // not in lsmaps/menu/vcall/etc., can just be changed to manually
+
 float MapInfo_count;
 
 // info about a map that MapInfo loads
@@ -20,10 +22,11 @@
 string MapInfo_Map_title;
 string MapInfo_Map_description;
 string MapInfo_Map_author;
-string MapInfo_Map_clientstuff;
-string MapInfo_Map_fog;
+string MapInfo_Map_clientstuff; // not in cache, only for map load
+string MapInfo_Map_fog; // not in cache, only for map load
 float MapInfo_Map_supportedGametypes;
 float MapInfo_Map_supportedFeatures;
+float MapInfo_Map_flags;
 vector MapInfo_Map_mins; // these are '0 0 0' if not supported!
 vector MapInfo_Map_maxs; // these are '0 0 0' if not specified!
 
@@ -33,7 +36,7 @@
 
 // filter the info by game type mask (updates MapInfo_count)
 float MapInfo_progress;
-float MapInfo_FilterGametype(float gametype, float features, float pAbortOnGenerate); // 1 on success, 0 on temporary failure (call it again next frame then; use MapInfo_progress as progress indicator)
+float MapInfo_FilterGametype(float gametype, float features, float pFlagsRequired, float pFlagsForbidden, float pAbortOnGenerate); // 1 on success, 0 on temporary failure (call it again next frame then; use MapInfo_progress as progress indicator)
 float MapInfo_CurrentFeatures(); // retrieves currently required features from cvars
 float MapInfo_CurrentGametype(); // retrieves current gametype from cvars
 
@@ -55,7 +58,7 @@
 void MapInfo_LoadMap(string s);
 
 // list all maps for the current game type
-string MapInfo_ListAllowedMaps();
+string MapInfo_ListAllowedMaps(float pFlagsRequired, float pFlagsForbidden);
 
 // gets a gametype from a string
 float MapInfo_Type_FromString(string t);

Modified: branches/nexuiz-2.0/data/qcsrc/common/util.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/util.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/common/util.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -921,7 +921,7 @@
 	// Perl-ish -1 for the last argument
 	if(i < 0)
 		i = _argc_sane + i;
-	return _argv_sane_buffer[i];
+	return strcat("", _argv_sane_buffer[i]); // force tempstring
 }
 
 float _argv_start_index_sane(float i)

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_create.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_create.c	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_create.c	2008-10-20 13:27:34 UTC (rev 4789)
@@ -100,7 +100,7 @@
 		me.TD(me, 1, 2.8, e = makeNexuizSliderCheckBox(-1, 0, me.sliderFraglimit, "Use map specified default"));
 	me.TR(me);
 	me.TR(me);
-		me.TD(me, 1, 3, e = makeNexuizCheckBox(0, "g_antilag", "AntiLag"));
+		me.TD(me, 1, 3, e = makeNexuizCheckBoxEx(2, 0, "g_antilag", "AntiLag"));
 	me.TR(me);
 	me.TR(me);
 		me.TD(me, 1, 1, e = makeNexuizTextLabel(0, "Map voting:"));

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup.c	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup.c	2008-10-20 13:27:34 UTC (rev 4789)
@@ -68,10 +68,12 @@
 		me.TD(me, 1, 1, e = makeNexuizTextLabel(0, "Field of View:"));
 		me.TD(me, 1, 2, e = makeNexuizSlider(60, 130, 1, "fov"));
 	me.TR(me);
-
 		me.TD(me, 1, 1, e = makeNexuizTextLabel(0, "Zoom Factor:"));
 		me.TD(me, 1, 2, e = makeNexuizSlider(2, 16, 0.5, "cl_zoomfactor"));
 	me.TR(me);
+		me.TD(me, 1, 1, e = makeNexuizTextLabel(0, "Zoom Sensitivity:"));
+		me.TD(me, 1, 2, e = makeNexuizSlider(0, 1, 0.01, "cl_zoomsensitivity"));
+	me.TR(me);
 		sl = makeNexuizSlider(1, 8, 0.5, "cl_zoomspeed");
 		me.TD(me, 1, 1, e = makeNexuizSliderCheckBox(-1, 1, sl, "Zoom speed:"));
 		me.TD(me, 1, 2, sl);
@@ -118,7 +120,6 @@
 		me.TD(me, 1, 2.8, e = makeNexuizCheckBox(0, "sbar_hudselector", "Use alternate HUD layout"));
 			setDependent(e, "viewsize", 0, 110);
 	me.TR(me);
-	me.TR(me);
 		me.TDempty(me, 0.5);
 		me.TD(me, 1, 2, e = makeNexuizButton("Radar & Waypoints...", '0 0 0'));
 			e.onClick = DialogOpenButton_Click;

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c	2008-10-20 13:27:34 UTC (rev 4789)
@@ -203,7 +203,7 @@
 	float gt, f;
 	gt = MapInfo_CurrentGametype();
 	f = MapInfo_CurrentFeatures();
-	MapInfo_FilterGametype(gt, f, 0);
+	MapInfo_FilterGametype(gt, f, 0, MAPINFO_FLAG_HIDDEN, 0);
 	me.nItems = MapInfo_count;
 	for(i = 0; i < MapInfo_count; ++i)
 		draw_PreloadPicture(strcat("/maps/", MapInfo_BSPName_ByID(i)));
@@ -236,7 +236,7 @@
 {
 	float i;
 	string s;
-	MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 0); // all
+	MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 0, MAPINFO_FLAG_HIDDEN, 0); // all
 	s = "";
 	for(i = 0; i < MapInfo_count; ++i)
 		s = strcat(s, " ", MapInfo_BSPName_ByID(i));

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/util.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -207,7 +207,7 @@
 
 	MapInfo_Cache_Create();
 	MapInfo_Enumerate();
-	if(!MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 1))
+	if(!MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 0, 0, 1))
 	{
 		draw_reset();
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/antilag.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/antilag.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/antilag.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -1,4 +1,4 @@
-#define ANTILAG_MAX_ORIGINS 32
+#define ANTILAG_MAX_ORIGINS 64
 .vector antilag_origins[ANTILAG_MAX_ORIGINS];
 .float antilag_times[ANTILAG_MAX_ORIGINS];
 .float antilag_index;

Modified: branches/nexuiz-2.0/data/qcsrc/server/antilag.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/antilag.qh	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/antilag.qh	2008-10-20 13:27:34 UTC (rev 4789)
@@ -3,3 +3,6 @@
 vector antilag_takebackorigin(entity e, float t);
 void antilag_takeback(entity e, float t);
 void antilag_restore(entity e);
+
+#define ANTILAG_LATENCY(e) min(0.4, e.ping * 0.001)
+// add one ticrate?

Modified: branches/nexuiz-2.0/data/qcsrc/server/bots.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/bots.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/bots.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -1442,9 +1442,9 @@
 	suffix = cvar_string("bot_suffix");
 
 	// this is really only a default, JoinBestTeam is called later
-	pants = bound(0, floor(random() * 13), 13);
-	//shirt = bound(0, floor(random() * 16), 15);
-	shirt = pants;
+	pants = floor(random() * 15);
+	shirt = floor(random() * 15);
+	//shirt = pants;
 	setcolor(self, shirt * 16 + pants);
 	self.bot_preferredcolors = self.clientcolors;
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -2055,9 +2055,8 @@
 
 	if(frametime)
 	{
+		SendFog();
 		antilag_record(self);
-
-		SendFog();
 	}
 
 	if(self.classname == "player") {
@@ -2238,6 +2237,22 @@
 		if(g_race)
 			race_InitSpectator();
 	}
+
+	if(self.teamkill_soundtime)
+	if(time > self.teamkill_soundtime)
+	{
+		self.teamkill_soundtime = 0;
+
+		entity oldpusher, oldself;
+
+		oldself = self; self = self.teamkill_soundsource;
+		oldpusher = self.pusher; self.pusher = oldself;
+
+		VoiceMessage("teamshoot_auto");
+
+		self.pusher = oldpusher;
+		self = oldself;
+	}
 }
 
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -413,7 +413,7 @@
 					else
 						player_setanim(self.anim_pain2, FALSE, TRUE, TRUE);
 
-					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)
+					if(!DEATH_ISWEAPON(deathtype, 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?
@@ -751,6 +751,8 @@
 		return 0;
 	if(type == "teamshoot")
 		return 2;
+	if(type == "teamshoot_auto")
+		return 3;
 	return 1;
 }
 
@@ -763,17 +765,18 @@
 	GetPlayerSoundSampleField_fixed = 0;
 	switch(type)
 	{
-		case "attack":       return playersound_attack;
-		case "attackinfive": return playersound_attackinfive;
-		case "coverme":      return playersound_coverme;
-		case "defend":       return playersound_defend;
-		case "freelance":    return playersound_freelance;
-		case "incoming":     return playersound_incoming;
-		case "meet":         return playersound_meet;
-		case "needhelp":     return playersound_needhelp;
-		case "seenflag":     return playersound_seenflag;
-		case "taunt":        return playersound_taunt;
-		case "teamshoot":    return playersound_teamshoot;
+		case "attack":            return playersound_attack;
+		case "attackinfive":      return playersound_attackinfive;
+		case "coverme":           return playersound_coverme;
+		case "defend":            return playersound_defend;
+		case "freelance":         return playersound_freelance;
+		case "incoming":          return playersound_incoming;
+		case "meet":              return playersound_meet;
+		case "needhelp":          return playersound_needhelp;
+		case "seenflag":          return playersound_seenflag;
+		case "taunt":             return playersound_taunt;
+		case "teamshoot":         return playersound_teamshoot;
+		case "teamshoot_auto":    return playersound_teamshoot;
 	}
 	GetPlayerSoundSampleField_notFound = 1;
 	return playersound_taunt;
@@ -906,21 +909,32 @@
 	tokenize_sane(sample);
 	n = stof(argv(1));
 	if(n > 0)
-		sample = strcat(argv(0), ftos(ceil(random() * n)), ".wav"); // randomization
+		sample = strcat(argv(0), ftos(floor(random() * n + 1)), ".wav"); // randomization
 	else
 		sample = strcat(argv(0), ".wav"); // randomization
 
-	if(teamsay == 2) // only to last attacker
+	if(teamsay == 3) // only to last attacker
 	{
-		if(teams_matter)
-			if(self.pusher)
-				if(self.pusher.team == self.team)
-				{
-					msg_entity = self.pusher;
+		if(self.pusher)
+			if(self.pusher.team == self.team)
+			{
+				msg_entity = self.pusher;
+				if(clienttype(msg_entity) == CLIENTTYPE_REAL)
 					soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE);
-					msg_entity = self;
+			}
+	}
+	else if(teamsay == 2) // only to last attacker and self
+	{
+		if(self.pusher)
+			if(self.pusher.team == self.team)
+			{
+				msg_entity = self.pusher;
+				if(clienttype(msg_entity) == CLIENTTYPE_REAL)
 					soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE);
-				}
+				msg_entity = self;
+				if(clienttype(msg_entity) == CLIENTTYPE_REAL)
+					soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTN_NONE);
+			}
 	}
 	else if(teamsay == 0) // to everyone
 	{

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -346,7 +346,7 @@
 	numberof = WEP_LAST - WEP_FIRST; // all but the current one
 	if(g_nixnex_with_laser)
 		numberof = numberof - 1;
-	id = WEP_FIRST + ceil(random() * numberof) - 1;
+	id = WEP_FIRST + floor(random() * numberof);
 
 	if(g_nixnex_with_laser) // skip the laser if needed
 		id = id + 1;

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -50,6 +50,7 @@
 	// calculate the shotdir from the chosen shotorg
 	w_shotdir = normalize(trueaimpoint - w_shotorg);
 
+#if 0
 	// explanation of g_antilag:
 	// if client reports it was aiming at a player, and the serverside trace
 	// says it would miss, change the aim point to the player's new origin,
@@ -79,7 +80,7 @@
 				if(self.antilag_debug)
 					antilag_takeback(self.cursor_trace_ent, time - self.antilag_debug);
 				else
-					antilag_takeback(self.cursor_trace_ent, time - self.ping * 0.001);
+					antilag_takeback(self.cursor_trace_ent, time - ANTILAG_LATENCY(self));
 
 				traceline(self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, self);
 				antilag_restore(self.cursor_trace_ent);
@@ -100,8 +101,8 @@
 				{
 					vector v, vplus, vel;
 					float X;
-					v     = antilag_takebackorigin(self.cursor_trace_ent, time - (self.ping * 0.001       ));
-					vplus = antilag_takebackorigin(self.cursor_trace_ent, time - (self.ping * 0.001 + 0.01));
+					v     = antilag_takebackorigin(self.cursor_trace_ent, time - (ANTILAG_LATENCY(self)       ));
+					vplus = antilag_takebackorigin(self.cursor_trace_ent, time - (ANTILAG_LATENCY(self) + 0.01));
 					vel = (vplus - v) * (1 / 0.01);
 					// solve: v + X * vel = closest to self.origin + self.view_ofs, v_forward axis
 					v     -= (self.origin + self.view_ofs);
@@ -113,11 +114,53 @@
 					// (v + X * vel)^2 closest to 0
 					// v^2 + 2 * X * (v * vel) + X^2 * vel^2 closest to 0
 					X = -(v * vel) / (vel * vel);
-					dprint("dead center needs adjustment of ", ftos(X * 1000), " (that is, ", ftos(self.ping + X * 1000), " instead of ", ftos(self.ping), "\n");
+					dprint("dead center needs adjustment of ", ftos(X), " (that is, ", ftos(ANTILAG_LATENCY(self) + X), " instead of ", ftos(ANTILAG_LATENCY(self)), "\n");
 				}
 			}
 		}
 	}
+#else
+	if (antilag)
+	{
+		if (cvar("g_antilag") == 1) // switch to "ghost" if not hitting original
+		{
+			traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, self);
+			if (!trace_ent.takedamage)
+			{
+				traceline_antilag_force (self, w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, self, ANTILAG_LATENCY(self));
+				if (trace_ent.takedamage && trace_ent.classname == "player")
+				{
+					entity e;
+					e = trace_ent;
+					traceline(w_shotorg, e.origin, MOVE_NORMAL, self);
+					if(trace_ent == e)
+						w_shotdir = normalize(trace_ent.origin - w_shotorg);
+				}
+			}
+		}
+		else if(cvar("g_antilag") == 3) // client side hitscan
+		{
+			if (self.cursor_trace_ent)                 // client was aiming at someone
+			if (self.cursor_trace_ent != self)         // just to make sure
+			if (self.cursor_trace_ent.takedamage)      // and that person is killable
+			if (self.cursor_trace_ent.classname == "player") // and actually a player
+			{
+				// verify that the shot would miss without antilag
+				// (avoids an issue where guns would always shoot at their origin)
+				traceline(w_shotorg, w_shotorg + w_shotdir * MAX_SHOT_DISTANCE, MOVE_NORMAL, self);
+				if (!trace_ent.takedamage)
+				{
+					// verify that the shot would hit if altered
+					traceline(w_shotorg, self.cursor_trace_ent.origin, MOVE_NORMAL, self);
+					if (trace_ent == self.cursor_trace_ent)
+						w_shotdir = normalize(self.cursor_trace_ent.origin - w_shotorg);
+					else
+						print("antilag fail\n");
+				}
+			}
+		}
+	}
+#endif
 
 	self.solid = oldsolid; // restore solid type (generally SOLID_SLIDEBOX)
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -223,7 +223,7 @@
 //float ctf_clientcommand();
 void SV_ParseClientCommand(string s) {
 	local string cmd;
-	local float i, tokens;
+	local float i, j, tokens;
 
 	tokens = tokenize_sane(s);
 
@@ -340,7 +340,7 @@
 			}
 		}
 	} else if(argv(0) == "maplist") {
-		local float n, j;
+		local float n;
 		local string col;
 		n = tokenize_sane(cvar_string("g_maplist"));
 		sprint(self, "^7Maps in list: ");
@@ -359,13 +359,18 @@
 		sprint(self, "\n");
 	} else if(argv(0) == "lsmaps") {
 		sprint(self, "^7Maps available: ");
-		for(i = 0; i < MapInfo_count; ++i)
+		for(i = 0, j = 0; i < MapInfo_count; ++i)
 		{
-			if(mod(i, 2))
-				col = "^2";
-			else
-				col = "^3";
-			sprint(self, strcat(col, MapInfo_BSPName_ByID(i), " "));
+			if(MapInfo_Get_ByID(i))
+			if not(MapInfo_Map_flags & MAPINFO_FLAG_HIDDEN)
+			{
+				if(mod(i, 2))
+					col = "^2";
+				else
+					col = "^3";
+				++j;
+				sprint(self, strcat(col, MapInfo_Map_bspname, " "));
+			}
 		}
 		sprint(self, "\n");
 	} else if(argv(0) == "voice") {

Modified: branches/nexuiz-2.0/data/qcsrc/server/constants.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/constants.qh	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/constants.qh	2008-10-20 13:27:34 UTC (rev 4789)
@@ -187,6 +187,13 @@
 float	HITTYPE_SPLASH = 0x200;
 float	HITTYPE_BOUNCE = 0x400;
 
+// macros to access these
+#define DEATH_ISSPECIAL(t)            ((t) >= DEATH_SPECIAL_START)
+#define DEATH_WEAPONOFWEAPONDEATH(t)  ((t) & DEATH_WEAPONMASK)
+#define DEATH_ISWEAPON(t,w)           (!DEATH_ISSPECIAL(t) && DEATH_WEAPONOFWEAPONDEATH(t) == (w))
+#define DEATH_WEAPONOF(t)             (DEATH_ISSPECIAL(t) ? 0 : DEATH_WEAPONOFWEAPONDEATH(t))
+#define WEP_VALID(w)                  ((w) >= WEP_FIRST && (w) <= WEP_LAST)
+
 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-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -534,8 +534,16 @@
 	ctf_worldflaglist = self;
 
 	self.classname = "item_flag_team";
-	self.team = COLOR_TEAM1; // color 4 team (red)
-	self.items = IT_KEY2; // gold key (redish enough)
+	if(g_ctf_reverse)
+	{
+		self.team = COLOR_TEAM2; // color 13 team (blue)
+		self.items = IT_KEY1; // silver key (bluish enough)
+	}
+	else
+	{
+		self.team = COLOR_TEAM1; // color 4 team (red)
+		self.items = IT_KEY2; // gold key (redish enough)
+	}
 	self.netname = "^1RED^7 flag";
 	self.target = "###item###";
 	self.skin = 0;
@@ -618,8 +626,16 @@
 	ctf_worldflaglist = self;
 
 	self.classname = "item_flag_team";
-	self.team = COLOR_TEAM2; // color 13 team (blue)
-	self.items = IT_KEY1; // silver key (bluish enough)
+	if(g_ctf_reverse)
+	{
+		self.team = COLOR_TEAM1; // color 4 team (red)
+		self.items = IT_KEY2; // gold key (redish enough)
+	}
+	else
+	{
+		self.team = COLOR_TEAM2; // color 13 team (blue)
+		self.items = IT_KEY1; // silver key (bluish enough)
+	}
 	self.netname = "^4BLUE^7 flag";
 	self.target = "###item###";
 	self.skin = 0;
@@ -761,9 +777,9 @@
 
 		for (flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext) if(flag.cnt != FLAG_BASE)
 		{
-			if(flag.team == COLOR_TEAM1)
+			if(flag.items & IT_KEY2) // blue
 				++redflags;
-			else if(flag.team == COLOR_TEAM2)
+			else if(flag.items & IT_KEY1) // red
 				++blueflags;
 		}
 
@@ -775,12 +791,12 @@
 
 		for (flag = ctf_worldflaglist; flag; flag = flag.ctf_worldflagnext) if(flag.cnt != FLAG_BASE)
 		{
-			if(flag.team == COLOR_TEAM1)
+			if(flag.items & IT_KEY2) // blue
 			{
 				if(--redflags == -1) // happens exactly once (redflags is in 0..count-1, and will --'ed count times)
 					ctf_setstatus2(flag, IT_RED_FLAG_TAKEN);
 			}
-			else if(flag.team == COLOR_TEAM2)
+			else if(flag.items & IT_KEY1) // red
 			{
 				if(--blueflags == -1) // happens exactly once
 					ctf_setstatus2(flag, IT_BLUE_FLAG_TAKEN);

Modified: branches/nexuiz-2.0/data/qcsrc/server/defs.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2008-10-20 13:27:34 UTC (rev 4789)
@@ -25,12 +25,14 @@
 float g_warmup_allow_timeout;
 float g_ctf_win_mode;
 float g_ctf_ignore_frags;
+float g_ctf_reverse;
 float g_race_qualifying;
 float inWarmupStage;
 float g_pickup_respawntime_short;
 float g_pickup_respawntime_medium;
 float g_pickup_respawntime_long;
 float g_pickup_respawntime_powerup;
+float g_maplist_allow_hidden;
 
 float sv_cheats;
 float sv_gentle;
@@ -168,7 +170,7 @@
 .float		dmgtime;
 
 .float		killcount;
-.float hitsound;
+.float hitsound, typehitsound;
 
 .float watersound_finished;
 .float iscreature;
@@ -253,17 +255,6 @@
 void VoteStop(entity stopper);
 void VoteCount();
 
-// Wazat's grappling hook
-.entity		hook;
-void GrapplingHookFrame();
-void RemoveGrapplingHook(entity pl);
-void SetGrappleHookBindings();
-// hook impulses
-float GRAPHOOK_FIRE		= 20;
-float GRAPHOOK_RELEASE		= 21;
-// (note: you can change the hook impulse #'s to whatever you please)
-.float hook_time;
-
 // Laser target for laser-guided weapons
 .entity lasertarget;
 .float laser_on;

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -5,7 +5,12 @@
 float damage_gooddamage;
 float headshot;
 
+.float teamkill_complain;
+.float teamkill_soundtime;
+.entity teamkill_soundsource;
+.entity pusher;
 
+
 float IsDifferentTeam(entity a, entity b)
 {
 	if(teams_matter)
@@ -152,7 +157,7 @@
 void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
 {
 	string	s, a;
-	float p;
+	float p, w;
 
 	if (targ.classname == "player" || targ.classname == "corpse")
 	{
@@ -212,11 +217,12 @@
 				if (targ.killcount > 2)
 					bprint ("^1",s,"^1 ended it all with a ",ftos(targ.killcount)," scoring spree\n");
 			} else {
-				if(deathtype < DEATH_SPECIAL_START && deathtype & DEATH_WEAPONMASK >= WEP_FIRST && deathtype & DEATH_WEAPONMASK <= WEP_LAST)
+				w = DEATH_WEAPONOF(deathtype);
+				if(WEP_VALID(w))
 				{
 					w_deathtypestring = "couldn't resist the urge to self-destruct";
 					w_deathtype = deathtype;
-					weapon_action(deathtype & DEATH_WEAPONMASK, WR_SUICIDEMESSAGE);
+					weapon_action(w, WR_SUICIDEMESSAGE);
 					bprint("^1", s, "^1 ", w_deathtypestring, "\n");
 				}
 				else if (deathtype == DEATH_KILL)
@@ -293,11 +299,12 @@
 				if(sv_gentle) {
 					bprint ("^1",s, "^1 needs a restart thanks to ", a, "\n");
 				} else {
-					if(deathtype < DEATH_SPECIAL_START && deathtype & DEATH_WEAPONMASK >= WEP_FIRST && deathtype & DEATH_WEAPONMASK <= WEP_LAST)
+					w = DEATH_WEAPONOF(deathtype);
+					if(WEP_VALID(w))
 					{
 						w_deathtypestring = "was blasted by";
 						w_deathtype = deathtype;
-						weapon_action(deathtype & DEATH_WEAPONMASK, WR_KILLMESSAGE);
+						weapon_action(w, WR_KILLMESSAGE);
 						p = strstrofs(w_deathtypestring, "#", 0);
 						if(p < 0)
 							bprint("^1", s, "^1 ", w_deathtypestring, " ", a, "\n");
@@ -513,7 +520,7 @@
 		targ.flags -= targ.flags & FL_GODMODE;
 		damage = 100000;
 	}
-	else if(deathtype == DEATH_MIRRORDAMAGE)
+	else if(deathtype == DEATH_MIRRORDAMAGE || deathtype == DEATH_NOAMMO)
 	{
 		// no processing
 	}
@@ -589,7 +596,7 @@
 				damage = 0;
 				targ.hitsound += 1;
 			}
-			if (deathtype == WEP_LASER)
+			if (DEATH_ISWEAPON(deathtype, WEP_LASER))
 			{
 				damage = 0;
 				if (targ != attacker)
@@ -606,7 +613,7 @@
 		}
 
 		// apply strength multiplier
-		if (attacker.items & IT_STRENGTH && !g_minstagib)
+		if ((attacker.items & IT_STRENGTH) && !g_minstagib)
 		{
 			if(targ == attacker)
 			{
@@ -672,33 +679,52 @@
 
 		// count the damage
 		if(attacker)
-		if(targ.classname == "player")
-		if(IsDifferentTeam(targ, attacker))
 		if(!targ.deadflag)
 		if(targ.takedamage == DAMAGE_AIM)
-		if(damage > 0)
+		if(targ != attacker)
+		if(targ.classname == "player")
 		{
-			attacker.hitsound += 1;
+			if(IsDifferentTeam(targ, attacker))
+			{
+				if(damage > 0)
+				{
+					if(targ.BUTTON_CHAT)
+						attacker.typehitsound += 1;
+					else
+						attacker.hitsound += 1;
 
-			damage_goodhits += 1;
-			damage_gooddamage += damage;
+					damage_goodhits += 1;
+					damage_gooddamage += damage;
 
-			if(!g_minstagib)
-			if(IsFlying(targ))
-				yoda = 1;
+					if(!g_minstagib)
+					if(IsFlying(targ))
+						yoda = 1;
 
-			if(g_minstagib)
-			if(targ.items & IT_STRENGTH)
-				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;
+					// 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, org;
+					org = antilag_takebackorigin(targ, time - ANTILAG_LATENCY(attacker));
+					headmins = org + '0.5 0 0' * targ.mins_x + '0 0.5 0' * targ.mins_y + '0 0 1' * targ.view_ofs_z;
+					headmaxs = org + '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;
+				}
+			}
+			else
+			{
+				attacker.typehitsound += 1; // TODO possibly trigger teamkill complain sound!
+				if(time > attacker.teamkill_complain)
+				{
+					attacker.teamkill_complain = time + 5;
+					attacker.teamkill_soundtime = time + 0.4;
+					attacker.teamkill_soundsource = targ;
+				}
+			}
 		}
 	}
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -83,8 +83,7 @@
 	return 0;
 }
 
-.float rope_length;
-.float button6_pressed_before;
+.float hook_length;
 
 void RemoveGrapplingHook(entity pl)
 {
@@ -95,8 +94,6 @@
 	if(pl.movetype == MOVETYPE_FLY)
 		pl.movetype = MOVETYPE_WALK;
 
-	pl.hook_time = time + 0.0;
-
 	//pl.disableclientprediction = FALSE;
 }
 
@@ -112,7 +109,7 @@
 	self.touch = SUB_Null;
 	self.velocity = '0 0 0';
 	self.movetype = MOVETYPE_NONE;
-	self.rope_length = -1;
+	self.hook_length = -1;
 }
 
 void GrapplingHookThink()
@@ -160,8 +157,8 @@
 	}
 #endif
 
-	if(self.rope_length < 0)
-		self.rope_length = vlen(org - self.origin);
+	if(self.hook_length < 0)
+		self.hook_length = vlen(org - self.origin);
 
 	if(self.state == 1)
 	{
@@ -192,38 +189,50 @@
 
 		if(cvar("g_grappling_hook_tarzan"))
 		{
-			newlength = self.rope_length;
 			v0 = self.owner.velocity;
 
 			// first pull the rope...
-			newlength = max(newlength - pullspeed * frametime, minlength);
-
-			if(newlength < dist - ropestretch) // overstretched?
+			if(self.owner.hook_state & HOOK_PULLING)
 			{
-				newlength = dist - ropestretch;
-				if(self.owner.velocity * dir < 0) // only if not already moving in hook direction
-					self.owner.velocity = self.owner.velocity + frametime * dir * rubberforce_overstretch;
-			}
+				newlength = self.hook_length;
+				newlength = max(newlength - pullspeed * frametime, minlength);
 
-			if(!self.owner.BUTTON_CROUCH) // crouch key = don't pull
-				self.rope_length = newlength;
+				if(newlength < dist - ropestretch) // overstretched?
+				{
+					newlength = dist - ropestretch;
+					if(self.owner.velocity * dir < 0) // only if not already moving in hook direction
+						self.owner.velocity = self.owner.velocity + frametime * dir * rubberforce_overstretch;
+				}
 
-			// then pull the player
-			spd = bound(0, (dist - self.rope_length) / ropestretch, 1);
-			self.owner.velocity = self.owner.velocity * (1 - frametime * ropeairfriction);
-			self.owner.velocity = self.owner.velocity + frametime * dir * spd * rubberforce;
+				self.hook_length = newlength;
+			}
 
-			dv = ((self.owner.velocity - v0) * dir) * dir;
-			if(cvar("g_grappling_hook_tarzan") >= 2)
+			if(self.owner.hook_state & HOOK_RELEASING)
 			{
-				if(self.aiment.movetype == MOVETYPE_WALK || self.aiment.movetype == MOVETYPE_TOSS)
+				newlength = dist;
+				self.hook_length = newlength;
+			}
+			else
+			{
+				// then pull the player
+				spd = bound(0, (dist - self.hook_length) / ropestretch, 1);
+				self.owner.velocity = self.owner.velocity * (1 - frametime * ropeairfriction);
+				self.owner.velocity = self.owner.velocity + frametime * dir * spd * rubberforce;
+
+				dv = ((self.owner.velocity - v0) * dir) * dir;
+				if(cvar("g_grappling_hook_tarzan") >= 2)
 				{
-					self.owner.velocity = self.owner.velocity - dv * 0.5;
-					self.aiment.velocity = self.aiment.velocity - dv * 0.5;
-					self.aiment.flags = self.aiment.flags - (self.aiment.flags & FL_ONGROUND);
-					self.aiment.pusher = self.owner;
-					self.aiment.pushltime = time + cvar("g_maxpushtime");
+					if(self.aiment.movetype == MOVETYPE_WALK || self.aiment.movetype == MOVETYPE_TOSS)
+					{
+						self.owner.velocity = self.owner.velocity - dv * 0.5;
+						self.aiment.velocity = self.aiment.velocity - dv * 0.5;
+						self.aiment.flags = self.aiment.flags - (self.aiment.flags & FL_ONGROUND);
+						self.aiment.pusher = self.owner;
+						self.aiment.pushltime = time + cvar("g_maxpushtime");
+					}
 				}
+
+				self.owner.flags (-) FL_ONGROUND;
 			}
 		}
 		else
@@ -238,10 +247,10 @@
 				spd = 0;
 			self.owner.velocity = dir*spd;
 			self.owner.movetype = MOVETYPE_FLY;
+
+			self.owner.flags (-) FL_ONGROUND;
 		}
 
-		self.owner.flags = self.owner.flags - (self.owner.flags & FL_ONGROUND);
-
 		org = org + dir*50; // get the beam out of the player's eyes
 	}
 
@@ -352,21 +361,73 @@
 	missile.damageforcescale = 0;
 }
 
+//  void GrapplingHookFrame()
+//  {
+//         // this function has been modified for Nexuiz
+// -       if (self.BUTTON_HOOK && g_grappling_hook)
+//         {
+// -               if (!self.hook && self.hook_time <= time && !self.button6_pressed_before)
+// -                       if (timeoutStatus != 2) //only allow the player to fire the grappling hook if the game is not paused (timeout)
+// -                               FireGrapplingHook();
+//         }
+// -       else
+//         {
+//                 if (self.hook)
+//                         RemoveGrapplingHook(self);
+//         }
+// -       self.button6_pressed_before = self.BUTTON_HOOK;
+//         /*
+//         // if I have no hook or it's not pulling yet, make sure I'm not flying!
+//         if((self.hook == world || !self.hook.state) && self.movetype == MOVETYPE_FLY)
+
 void GrapplingHookFrame()
 {
-	// this function has been modified for Nexuiz
-	if (self.BUTTON_HOOK && g_grappling_hook)
+	if(g_grappling_hook && timeoutStatus != 2)
 	{
-		if (!self.hook && self.hook_time <= time && !self.button6_pressed_before)
-			if (timeoutStatus != 2) //only allow the player to fire the grappling hook if the game is not paused (timeout)
-				FireGrapplingHook();
+		// offhand hook controls
+		if(self.BUTTON_HOOK)
+		{
+			if not(self.hook || (self.hook_state & HOOK_WAITING_FOR_REFIRE))
+			{
+				self.hook_state |= HOOK_FIRING;
+				self.hook_state |= HOOK_WAITING_FOR_REFIRE;
+			}
+		}
+		else
+		{
+			if(self.hook)
+			{
+				self.hook_state |= HOOK_REMOVING;
+				self.hook_state (-) HOOK_WAITING_FOR_REFIRE;
+			}
+		}
+
+		self.hook_state (-) HOOK_RELEASING;
+		if(self.BUTTON_CROUCH)
+		{
+			self.hook_state (-) HOOK_PULLING;
+			//self.hook_state |= HOOK_RELEASING;
+		}
+		else
+		{
+			self.hook_state |= HOOK_PULLING;
+			//self.hook_state (-) HOOK_RELEASING;
+		}
 	}
-	else
+
+	if (self.hook_state & HOOK_FIRING)
 	{
 		if (self.hook)
 			RemoveGrapplingHook(self);
+		FireGrapplingHook();
+		self.hook_state (-) HOOK_FIRING;
 	}
-	self.button6_pressed_before = self.BUTTON_HOOK;
+	else if(self.hook_state & HOOK_REMOVING)
+	{
+		if (self.hook)
+			RemoveGrapplingHook(self);
+		self.hook_state (-) HOOK_REMOVING;
+	}
 	/*
 	// if I have no hook or it's not pulling yet, make sure I'm not flying!
 	if((self.hook == world || !self.hook.state) && self.movetype == MOVETYPE_FLY)

Copied: branches/nexuiz-2.0/data/qcsrc/server/g_hook.qh (from rev 4788, trunk/data/qcsrc/server/g_hook.qh)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_hook.qh	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_hook.qh	2008-10-20 13:27:34 UTC (rev 4789)
@@ -0,0 +1,14 @@
+// Wazat's grappling hook
+.entity		hook;
+void GrapplingHookFrame();
+void RemoveGrapplingHook(entity pl);
+void SetGrappleHookBindings();
+// (note: you can change the hook impulse #'s to whatever you please)
+.float hook_time;
+
+float HOOK_FIRING = 1;
+float HOOK_REMOVING = 2;
+float HOOK_PULLING = 4;
+float HOOK_RELEASING = 8;
+float HOOK_WAITING_FOR_REFIRE = 16;
+.float hook_state;

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_subs.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_subs.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_subs.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -215,7 +215,7 @@
 Additionally it moves players back into the past before the trace and restores them afterward.
 ==================
 */
-void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
+void traceline_antilag_force (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
 {
 	local entity player;
 	local float oldsolid;
@@ -225,9 +225,6 @@
 		lag = 0;
 	if (clienttype(forent) != CLIENTTYPE_REAL)
 		lag = 0; // only antilag for clients
-	if (lag)
-	if (cvar("g_antilag") != 2)
-		lag = 0;
 
 	// change shooter to SOLID_BBOX so the shot can hit corpses
 	oldsolid = source.solid;
@@ -261,6 +258,12 @@
 	// restore shooter solid type
 	source.solid = oldsolid;
 }
+void traceline_antilag (entity source, vector v1, vector v2, float nomonst, entity forent, float lag)
+{
+	if (cvar("g_antilag") != 2)
+		lag = 0;
+	traceline_antilag_force(source, v1, v2, nomonst, forent, lag);
+}
 
 /*
 ==================

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -143,7 +143,7 @@
 			cvar_set("nextmap", argv(0));
 
 			MapInfo_Enumerate();
-			MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0);
+			MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0, (g_maplist_allow_hidden ? MAPINFO_FLAG_HIDDEN : 0), 0);
 
 			if(!DoNextMapOverride())
 				GotoNextMap();
@@ -356,7 +356,7 @@
 	orig_slowmo = cvar("slowmo");
 
 	MapInfo_Enumerate();
-	MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 1);
+	MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0, (g_maplist_allow_hidden ? MAPINFO_FLAG_HIDDEN : 0), 1);
 
 	if(whichpack(strcat("maps/", mapname, ".cfg")) != "")
 	{
@@ -629,7 +629,7 @@
 	for(i = 0; i <= imax; ++i)
 	{
 		float mapindex;
-		mapindex = mod(Map_Current + ceil(random() * (Map_Count - 1)), Map_Count); // any OTHER map
+		mapindex = mod(Map_Current + floor(random() * (Map_Count - 1) + 1), Map_Count); // any OTHER map
 		if(Map_Check(mapindex, 1))
 			return mapindex;
 	}
@@ -681,7 +681,7 @@
 	if(Map_Count == 0)
 	{
 		bprint( "Maplist is empty!  Resetting it to default map list.\n" );
-		cvar_set("g_maplist", temp = MapInfo_ListAllowedMaps());
+		cvar_set("g_maplist", temp = MapInfo_ListAllowedMaps(0, MAPINFO_FLAG_HIDDEN));
 		localcmd("\nmenu_cmd sync\n");
 		Map_Count = tokenizebyseparator(temp, " ");
 	}
@@ -799,7 +799,7 @@
 			if(allowReset)
 			{
 				bprint( "Maplist contains no single playable map!  Resetting it to default map list.\n" );
-				cvar_set("g_maplist", MapInfo_ListAllowedMaps());
+				cvar_set("g_maplist", MapInfo_ListAllowedMaps(0, MAPINFO_FLAG_HIDDEN));
 				localcmd("\nmenu_cmd sync\n");
 			}
 			else
@@ -1399,7 +1399,7 @@
 		result = "";
 
 		// select a random item
-		selected = ceil(random() * (litems - start) + start) - 1;
+		selected = floor(random() * (litems - start) + start);
 
 		// shift this item to the place start
 		for(i = 0; i < start; ++i)
@@ -1747,7 +1747,7 @@
 			return "This map was already suggested.";
 	if(mapvote_suggestion_ptr >= MAPVOTE_COUNT)
 	{
-		i = ceil(random() * mapvote_suggestion_ptr) - 1;
+		i = floor(random() * mapvote_suggestion_ptr);
 	}
 	else
 	{
@@ -1797,7 +1797,7 @@
 
 	if(mapvote_suggestion_ptr)
 		for(i = 0; i < 100 && mapvote_count < smax; ++i)
-			MapVote_AddVotable(mapvote_suggestions[ceil(random() * mapvote_suggestion_ptr) - 1], TRUE);
+			MapVote_AddVotable(mapvote_suggestions[floor(random() * mapvote_suggestion_ptr)], TRUE);
 
 	for(i = 0; i < 100 && mapvote_count < nmax; ++i)
 		MapVote_AddVotable(GetNextMap(), FALSE);
@@ -1805,7 +1805,7 @@
 	if(mapvote_count == 0)
 	{
 		bprint( "Maplist contains no single playable map!  Resetting it to default map list.\n" );
-		cvar_set("g_maplist", MapInfo_ListAllowedMaps());
+		cvar_set("g_maplist", MapInfo_ListAllowedMaps(0, MAPINFO_FLAG_HIDDEN));
 		localcmd("\nmenu_cmd sync\n");
 		for(i = 0; i < 100 && mapvote_count < nmax; ++i)
 			MapVote_AddVotable(GetNextMap(), FALSE);
@@ -2180,7 +2180,7 @@
 		return;
 
 	MapInfo_Enumerate();
-	if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 1))
+	if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0, (g_maplist_allow_hidden ? MAPINFO_FLAG_HIDDEN : 0), 1))
 		mapvote_run = TRUE;
 }
 void MapVote_Think()
@@ -2237,17 +2237,24 @@
 	{
 		if(self.classname == "spectator")
 		{
-			if(self.enemy.hitsound)
+			if(self.enemy.typehitsound)
+				play2(self, "misc/typehit.wav");
+			else if(self.enemy.hitsound)
 				play2(self, "misc/hit.wav");
 		}
 		else
 		{
-			if(self.hitsound)
+			if(self.typehitsound)
+				play2(self, "misc/typehit.wav");
+			else if(self.hitsound)
 				play2(self, "misc/hit.wav");
 		}
 	}
 	FOR_EACH_CLIENT(self)
+	{
 		self.hitsound = FALSE;
+		self.typehitsound = FALSE;
+	}
 }
 
 
@@ -2312,7 +2319,7 @@
 	// Mapinfo
 	MapInfo_Shutdown();
 	MapInfo_Enumerate();
-	MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 1);
+	MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0, (g_maplist_allow_hidden ? MAPINFO_FLAG_HIDDEN : 0), 1);
 }
 
 void SV_Shutdown()

Modified: branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/gamecommand.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -438,10 +438,10 @@
 
 void make_mapinfo_Think()
 {
-	if(MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 1))
+	if(MapInfo_FilterGametype(MAPINFO_TYPE_ALL, 0, 0, 0, 1))
 	{
 		print("Done rebuiling mapinfos.\n");
-		MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0);
+		MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0, (g_maplist_allow_hidden ? MAPINFO_FLAG_HIDDEN : 0), 0);
 		remove(self);
 	}
 	else
@@ -527,16 +527,17 @@
 		if(t)
 		{
 			MapInfo_SwitchGameType(t);
-			MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0);
+			MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0, MAPINFO_FLAG_HIDDEN, 0);
 			if(MapInfo_count > 0)
 			{
 				bprint("Game type successfully switched to ", s, "\n");
+				MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0, (g_maplist_allow_hidden ? MAPINFO_FLAG_HIDDEN : 0), 0);
 			}
 			else
 			{
 				bprint("Cannot use this game type: no map for it found\n");
 				MapInfo_SwitchGameType(tsave);
-				MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0);
+				MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), 0, (g_maplist_allow_hidden ? MAPINFO_FLAG_HIDDEN : 0), 0);
 			}
 		}
 		else

Modified: branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -863,6 +863,8 @@
 	sv_maxidle_spectatorsareidle = cvar("sv_maxidle_spectatorsareidle");
 	sv_pogostick = cvar("sv_pogostick");
 	sv_doublejump = cvar("sv_doublejump");
+	g_maplist_allow_hidden = cvar("g_maplist_allow_hidden");
+	g_ctf_reverse = cvar("g_ctf_reverse");
 
 	inWarmupStage = cvar("g_warmup");
 	g_warmup_limit = cvar("g_warmup_limit");
@@ -1093,7 +1095,8 @@
 	precache_sound ("player/slime.wav");
 
 	// announcer sounds - male
-	//precache_sound ("announcer/male/electrobitch.wav");
+	precache_sound ("announcer/male/electrobitch.wav");
+	precache_sound ("announcer/male/airshot.wav");
 	precache_sound ("announcer/male/03kills.wav");
 	precache_sound ("announcer/male/05kills.wav");
 	precache_sound ("announcer/male/10kills.wav");

Modified: branches/nexuiz-2.0/data/qcsrc/server/progs.src
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/progs.src	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/progs.src	2008-10-20 13:27:34 UTC (rev 4789)
@@ -19,6 +19,8 @@
 
 portals.qh
 
+g_hook.qh
+
 scores.qh
 
 ipban.qh

Modified: branches/nexuiz-2.0/data/qcsrc/server/runematch.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/runematch.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/runematch.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -228,7 +228,7 @@
 	float num, r;
 	entity spot;
 	num = count_rune_spawnpoints();
-	r = ceil(random()*num);
+	r = floor(random()*num) + 1;
 
 	if(self.owner.classname == "runematch_spawn_point")
 	{
@@ -380,7 +380,7 @@
 		{
 			// avoid pairing runes and curses that match each other
 			do{
-				rand = ceil(random()*ccount);
+				rand = floor(random()*ccount) + 1;
 				curse = FindRune(pl, "curse", rand);
 				tries = tries - 1;
 			}while(RuneMatchesCurse(rune.runes, curse.runes) && tries > 0);
@@ -391,7 +391,7 @@
 		}
 		else
 		{
-				rand = ceil(random()*ccount);
+				rand = floor(random()*ccount) + 1;
 				curse = FindRune(pl, "curse", rand);
 		}
 
@@ -476,7 +476,7 @@
 
 	while(numrunes > 0)
 	{
-		r = ceil(random()*numrunes);
+		r = floor(random()*numrunes) + 1;
 		if(r == 1)
 			rn = RUNE_STRENGTH;
 		else if(r == 2)
@@ -493,7 +493,7 @@
 			tries = 15;
 			// avoid pairing runes and curses that match each other
 			do{
-				r = ceil(random()*numrunes);
+				r = floor(random()*numrunes) + 1;
 				if(r == 1)
 					cs = CURSE_WEAK;
 				else if(r == 2)
@@ -513,7 +513,7 @@
 		}
 		else
 		{
-			r = ceil(random()*numrunes);
+			r = floor(random()*numrunes) + 1;
 			if(r == 1)
 				cs = CURSE_WEAK;
 			else if(r == 2)
@@ -531,7 +531,7 @@
 		if(num <= 1)
 			r = 1;
 		else
-			r = ceil(random()*num*1.25);
+			r = floor(random()*num*1.25) + 1;
 
 		spot = rune_find_spawnpoint(num, r);
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/t_items.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_items.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_items.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -898,7 +898,7 @@
 			self.colormap = 0x00;
 	}
 	else
-		self.colormap = ceil(random() * 256) - 1;
+		self.colormap = floor(random() * 256);
 	self.colormap |= 1024; // RENDER_COLORMAPPED
 }
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -507,6 +507,8 @@
 		return;
 	if (other.classname != "player")
 		return;
+	if(other.velocity * self.movedir < 0)
+		return;
 	self.enemy = other;
 	if (other.owner)
 		self.enemy = other.owner;

Modified: branches/nexuiz-2.0/data/qcsrc/server/target_spawn.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/target_spawn.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/target_spawn.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -10,31 +10,35 @@
 float target_spawn_spawnfunc_field;
 .entity target_spawn_activator;
 
-void target_spawn_use()
+void target_spawn_useon(entity e)
 {
-	float i, n, valuefieldpos, sPWNed;
-	entity e;
+	float i, n, valuefieldpos;
 	string key, value, valuefield, valueoffset, valueoffsetrandom;
 	entity valueent;
 	vector data, data2;
 	entity oldself;
 	entity oldactivator;
 
-	e = spawn();
 	n = tokenize_sane(self.message);
 
-	sPWNed = FALSE;
-
 	for(i = 0; i < n-1; i += 2)
 	{
 		key = argv(i);
 		value = argv(i+1);
-		data = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", key)));
-		if(data_y == 0) // undefined field, i.e., invalid type
+		if(key == "$")
 		{
-			print("target_spawn: invalid/unknown entity key ", key, " specified, ignored!\n");
-			continue;
+			data_x = -1;
+			data_y = FIELD_STRING;
 		}
+		else
+		{
+			data = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", key)));
+			if(data_y == 0) // undefined field, i.e., invalid type
+			{
+				print("target_spawn: invalid/unknown entity key ", key, " specified, ignored!\n");
+				continue;
+			}
+		}
 		if(substring(value, 0, 1) == "$")
 		{
 			value = substring(value, 1, strlen(value) - 1);
@@ -47,20 +51,12 @@
 			else
 			{
 				// replace me!
-				valuefieldpos = strstrofs(value, ".", 0);
-				valuefield = "";
-				if(valuefieldpos != -1)
-				{
-					valuefield = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
-					value = substring(value, 0, valuefieldpos);
-				}
-
 				valuefieldpos = strstrofs(value, "+", 0);
 				valueoffset = "";
 				if(valuefieldpos != -1)
 				{
-					valueoffset = substring(valuefield, valuefieldpos + 1, strlen(valueoffset) - valuefieldpos - 1);
-					valuefield = substring(valuefield, 0, valuefieldpos);
+					valueoffset = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
+					value = substring(value, 0, valuefieldpos);
 				}
 
 				valuefieldpos = strstrofs(valueoffset, "+", 0);
@@ -71,6 +67,14 @@
 					valueoffset = substring(valueoffset, 0, valuefieldpos);
 				}
 
+				valuefieldpos = strstrofs(value, ".", 0);
+				valuefield = "";
+				if(valuefieldpos != -1)
+				{
+					valuefield = substring(value, valuefieldpos + 1, strlen(value) - valuefieldpos - 1);
+					value = substring(value, 0, valuefieldpos);
+				}
+
 				if(value == "self")
 				{
 					valueent = self;
@@ -115,7 +119,7 @@
 					data2 = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", valuefield)));
 					if(data2_y == 0) // undefined field, i.e., invalid type
 					{
-						print("target_spawn: invalid/unknown entity key replacement ", value, " specified, ignored!\n");
+						print("target_spawn: invalid/unknown entity key replacement ", valuefield, " specified, ignored!\n");
 						continue;
 					}
 					value = getentityfieldstring(data2_x, valueent);
@@ -158,35 +162,53 @@
 				}
 			}
 		}
-		putentityfieldstring(data_x, e, value);
-
-		if(key == "classname" && !sPWNed)
+		if(key == "$")
 		{
-			if(self.spawnflags & 1)
-			{
-				if(!e.target_spawn_spawnfunc)
-					putentityfieldstring(target_spawn_spawnfunc_field, e, strcat("spawnfunc_", value));
+			putentityfieldstring(target_spawn_spawnfunc_field, e, value);
 
-				oldself = self;
-				oldactivator = activator;
+			oldself = self;
+			oldactivator = activator;
 
-				self = e;
-				activator = self.target_spawn_activator;
+			self = e;
+			activator = self.target_spawn_activator;
 
-				self.target_spawn_spawnfunc();
+			self.target_spawn_spawnfunc();
 
-				self = oldself;
-				activator = oldactivator;
-			}
-			sPWNed = TRUE;
+			self = oldself;
+			activator = oldactivator;
 		}
+		else
+		{
+			if(data_y == FIELD_VECTOR)
+				value = strreplace("'", "", value); // why?!?
+			putentityfieldstring(data_x, e, value);
+		}
 	}
 }
 
+void target_spawn_use()
+{
+	entity e;
+
+	if(self.target == "")
+	{
+		// spawn new entity
+		e = spawn();
+		target_spawn_useon(e);
+	}
+	else
+	{
+		// edit entity
+		for(e = world; (e = find(e, targetname, self.target)); )
+			target_spawn_useon(e);
+	}
+}
+
 void target_spawn_spawnfirst()
 {
 	activator = self.target_spawn_activator;
-	target_spawn_use();
+	if(self.spawnflags & 2)
+		target_spawn_use();
 }
 
 void spawnfunc_target_spawn()
@@ -195,6 +217,7 @@
 	{
 		float n, i;
 		string fn;
+		vector prev, new;
 		float ft;
 
 		n = numentityfields();
@@ -202,13 +225,19 @@
 		{
 			fn = entityfieldname(i);
 			ft = entityfieldtype(i);
-			db_put(TemporaryDB, strcat("/target_spawn/field/", fn), vtos(i * '1 0 0' + ft * '0 1 0' + '0 0 1'));
-			if(fn == "target_spawn_spawnfunc")
-				target_spawn_spawnfunc_field = i;
+			new = i * '1 0 0' + ft * '0 1 0' + '0 0 1';
+			prev = stov(db_get(TemporaryDB, strcat("/target_spawn/field/", fn)));
+			if(prev_y == 0)
+			{
+				db_put(TemporaryDB, strcat("/target_spawn/field/", fn), vtos(new));
+				if(fn == "target_spawn_spawnfunc")
+					target_spawn_spawnfunc_field = i;
+			}
 		}
 
 		target_spawn_initialized = 1;
 	}
 	self.use = target_spawn_use;
+	self.message = strzone(strreplace("'", "\"", self.message));
 	InitializeEntity(self, target_spawn_spawnfirst, INITPRIO_LAST);
 }

Modified: branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -172,12 +172,13 @@
 	ReadGameCvars();
 	WriteGameCvars();
 
+	// find out good world mins/maxs bounds, either the static bounds found by looking for solid, or the mapinfo specified bounds
+	get_mi_min_max(1);
+	world.mins = mi_min;
+	world.maxs = mi_max;
+
 	MapInfo_LoadMapSettings(mapname);
-	if(MapInfo_Map_mins_x < MapInfo_Map_maxs_x)
-	{
-		world.mins = MapInfo_Map_mins;
-		world.maxs = MapInfo_Map_maxs;
-	}
+	
 	if not(cvar_value_issafe(world.fog))
 	{
 		print("The current map contains a potentially harmful fog setting, ignored\n");

Modified: branches/nexuiz-2.0/data/qcsrc/server/vote.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/vote.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/vote.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -66,8 +66,6 @@
 	entity victim;
 	vote_argc = tokenize_sane(vote);
 
-	print(">>", vote, "<<\n");
-
 	if(!VoteAllowed(argv(0)))
 	{
 		return FALSE;
@@ -553,8 +551,9 @@
 		}
 		VoteReset();
 	} else {
-		float votefactor;
+		float votefactor, simplevotefactor;
 		votefactor = bound(0.5, cvar("sv_vote_majority_factor"), 0.999);
+		simplevotefactor = cvar("sv_vote_simple_majority_factor");
 		if(yescount > (playercount - abstaincount) * votefactor)
 		{
 			VoteSpam(yescount, nocount, abstaincount, playercount - yescount - nocount - abstaincount, -1, "yes");
@@ -567,10 +566,11 @@
 		}
 		else if(time > votefinished)
 		{
-			if(cvar("sv_vote_simple_majority"))
+			if(simplevotefactor)
 			{
 				string result;
-				if(yescount > (yescount + nocount) * votefactor)
+				simplevotefactor = bound(votefactor, simplevotefactor, 0.999);
+				if(yescount > (yescount + nocount) * simplevotefactor)
 					result = "yes";
 				else if(yescount + nocount > 0)
 					result = "no";

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_common.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_common.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_common.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -46,7 +46,7 @@
 		if(self.antilag_debug)
 			traceline_antilag (self, start, end, FALSE, self, self.antilag_debug);
 		else
-			traceline_antilag (self, start, end, FALSE, self, self.ping * 0.001);
+			traceline_antilag (self, start, end, FALSE, self, ANTILAG_LATENCY(self));
 
 		// if it is world we can't hurt it so stop now
 		if (trace_ent == world || trace_fraction == 1)
@@ -121,7 +121,7 @@
 	if(self.antilag_debug)
 		traceline_antilag (self, start, end, FALSE, self, self.antilag_debug);
 	else
-		traceline_antilag (self, start, end, FALSE, self, self.ping * 0.001);
+		traceline_antilag (self, start, end, FALSE, self, ANTILAG_LATENCY(self));
 
 	if (tracer)
 	{
@@ -144,7 +144,7 @@
 	{
 		if (trace_ent.solid == SOLID_BSP && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
 		{
-			if (dtype < DEATH_SPECIAL_START && (dtype & DEATH_WEAPONMASK) == WEP_SHOTGUN)
+			if (DEATH_ISWEAPON(dtype, 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_electro.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_electro.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_electro.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -15,6 +15,13 @@
 		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"), self.projectiledeathtype, other);
 	}
+
+	if(other.takedamage == DAMAGE_AIM)
+		if(other.classname == "player")
+			if(IsDifferentTeam(self.owner, other))
+				if(IsFlying(other))
+					announce(self.owner, "announcer/male/electrobitch.ogg");
+
 	sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
 
 	remove (self);
@@ -35,7 +42,6 @@
 
 void W_Plasma_Touch (void)
 {
-	entity o;
 	if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
 	{
 		sound (self, CHAN_PROJECTILE, "misc/null.wav", VOL_BASE, ATTN_NORM);
@@ -43,12 +49,7 @@
 		return;
 	}
 	if (other.takedamage == DAMAGE_AIM) {
-		o = self.owner;
 		W_Plasma_Explode ();
-		if(other.classname == "player")
-			if(IsDifferentTeam(o, other))
-				if(IsFlying(other))
-					announce(o, "announcer/male/electrobitch.ogg");
 	} else {
 		sound (self, CHAN_PROJECTILE, "weapons/electro_bounce.wav", VOL_BASE, ATTN_NORM);
 		self.projectiledeathtype |= HITTYPE_BOUNCE;
@@ -66,11 +67,6 @@
 	}
 	o = self.owner;
 	W_Plasma_Explode ();
-	if(other.takedamage == DAMAGE_AIM)
-		if(other.classname == "player")
-			if(IsDifferentTeam(o, other))
-				if(IsFlying(other))
-					announce(o, "announcer/male/electrobitch.ogg");
 }
 
 void W_Plasma_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_grenadelauncher.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_grenadelauncher.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_grenadelauncher.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -8,6 +8,12 @@
 	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"), self.projectiledeathtype, other);
 
+	if(other.takedamage == DAMAGE_AIM)
+		if(other.classname == "player")
+			if(IsDifferentTeam(self.owner, other))
+				if(IsFlying(other))
+					announce(self.owner, "announcer/male/airshot.ogg");
+
 	remove (self);
 }
 
@@ -21,6 +27,12 @@
 	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"), self.projectiledeathtype, other);
 
+	if(other.takedamage == DAMAGE_AIM)
+		if(other.classname == "player")
+			if(IsDifferentTeam(self.owner, other))
+				if(IsFlying(other))
+					announce(self.owner, "announcer/male/airshot.ogg");
+
 	remove (self);
 }
 
@@ -42,7 +54,9 @@
 		return;
 	}
 	if (other.takedamage == DAMAGE_AIM)
+	{
 		self.use ();
+	}
 	else
 	{
 		float r;

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_minstanex.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_minstanex.qc	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_minstanex.qc	2008-10-20 13:27:34 UTC (rev 4789)
@@ -22,7 +22,10 @@
 		if(yoda && flying)
 			announce(self, "announcer/male/yoda.ogg");
 		if(headshot)
+		{
 			announce(self, "announcer/male/headshot.ogg");
+			print("h\n");
+		}
 		if(damage_goodhits && self.minstanex_lasthit)
 		{
 			if(announce(self, "announcer/male/impressive.ogg"))

Modified: branches/nexuiz-2.0/data/scripts/entities.def
===================================================================
--- branches/nexuiz-2.0/data/scripts/entities.def	2008-10-19 19:10:11 UTC (rev 4788)
+++ branches/nexuiz-2.0/data/scripts/entities.def	2008-10-20 13:27:34 UTC (rev 4789)
@@ -1081,10 +1081,11 @@
 ANDNOT: the items listed will get removed from the player
 */
 
-/*QUAKED target_spawn (1 0 1) (-8 -8 -8) (8 8 8) SPAWNFUNC ONLOAD
+/*QUAKED target_spawn (1 0 1) (-8 -8 -8) (8 8 8) - ONLOAD
 Spawns an entity when triggered.
 The entity field list is a single string of the form:
-"field" "value" "field" "value" ... "classname" "item_bullets" ... "field" "value"
+'field' 'value' 'field' 'value' ... 'classname' 'item_bullets' ... 'field' 'value'
+The special "field" name $ calls a void(void) function, for example a spawn function.
 Field values can use various variable replacements:
 $E
 $E.field
@@ -1093,14 +1094,24 @@
 where "E" can be self, activator and pusher.
 Example is a Mario-style question mark block which could throw a new weapon_nex when activated like this:
 {
+"classname" "func_button"
+"angle" "-1"
+"wait" "5"
+"target" "makenex"
+"speed" "1000"
+"lip" "64"
+...
+}
+{
 "classname" "target_spawn"
-"message" "origin \"$self.origin+0 0 128\" velocity \"$activator.velocity+0 0 200\" owner $activator flags 65536 colormap $activator.colormap target_spawn_spawnfunc weapon_nex classname droppedweapon think thrown_wep_think nextthink $time+0.5"
-"spawnflags" "1"
+"origin" "0 0 448"
+"targetname" "makenex"
+"message" "origin $self.origin owner $activator flags 65536 colormap $activator.colormap classname droppedweapon $ spawnfunc_weapon_nex think thrown_wep_think nextthink $time+0.5 velocity $activator.velocity velocity_z 512 movetype 3"
 }
 -------- KEYS --------
 targetname: used to trigger this
 message: entity field list
+target: when set, target_spawn edits entities, instead of creating new ones
 -------- SPAWNFLAGS --------
-SPAWNFUNC: call the spawn function when the "classname" key is mentioned in the fields list
 ONLOAD: create a first entity on map load
 */

Copied: branches/nexuiz-2.0/data/sound/announcer/male/airshot.ogg (from rev 4788, trunk/data/sound/announcer/male/airshot.ogg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/sound/announcer/male/headshot.ogg (from rev 4788, trunk/data/sound/announcer/male/headshot.ogg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/sound/announcer/male/impressive.ogg (from rev 4788, trunk/data/sound/announcer/male/impressive.ogg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/sound/misc/typehit.wav (from rev 4788, trunk/data/sound/misc/typehit.wav)
===================================================================
(Binary files differ)




More information about the nexuiz-commits mailing list