r3038 - in branches/nexuiz-2.0/data: . maps models models/player particles qcsrc/client qcsrc/server scripts sound/cdtracks sound/weapons textures

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Thu Dec 20 06:07:32 EST 2007


Author: div0
Date: 2007-12-20 06:07:30 -0500 (Thu, 20 Dec 2007)
New Revision: 3038

Added:
   branches/nexuiz-2.0/data/models/player/template.md3.animinfo
   branches/nexuiz-2.0/data/scripts/default_project.proj
   branches/nexuiz-2.0/data/textures/muzzle1.tga
   branches/nexuiz-2.0/data/textures/muzzle2.tga
Modified:
   branches/nexuiz-2.0/data/default.cfg
   branches/nexuiz-2.0/data/effectinfo.txt
   branches/nexuiz-2.0/data/maps/silvercity.ent
   branches/nexuiz-2.0/data/maps/silvercity.map
   branches/nexuiz-2.0/data/models/uziflash.md3
   branches/nexuiz-2.0/data/particles/nexbeam.tga
   branches/nexuiz-2.0/data/particles/particlefont.tga
   branches/nexuiz-2.0/data/physicsQ3.cfg
   branches/nexuiz-2.0/data/qcsrc/client/csqc_builtins.h
   branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.h
   branches/nexuiz-2.0/data/qcsrc/server/arena.qc
   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_physics.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc
   branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
   branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
   branches/nexuiz-2.0/data/qcsrc/server/defs.qh
   branches/nexuiz-2.0/data/qcsrc/server/domination.qc
   branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
   branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc
   branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
   branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc
   branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc
   branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh
   branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
   branches/nexuiz-2.0/data/qcsrc/server/runematch.qc
   branches/nexuiz-2.0/data/qcsrc/server/t_jumppads.qc
   branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_shotgun.qc
   branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc
   branches/nexuiz-2.0/data/sound/cdtracks/thunder.ogg
   branches/nexuiz-2.0/data/sound/cdtracks/track001.ogg
   branches/nexuiz-2.0/data/sound/cdtracks/track002.ogg
   branches/nexuiz-2.0/data/sound/cdtracks/track003.ogg
   branches/nexuiz-2.0/data/sound/cdtracks/track004.ogg
   branches/nexuiz-2.0/data/sound/cdtracks/track005.ogg
   branches/nexuiz-2.0/data/sound/cdtracks/track006.ogg
   branches/nexuiz-2.0/data/sound/cdtracks/track007.ogg
   branches/nexuiz-2.0/data/sound/cdtracks/track008.ogg
   branches/nexuiz-2.0/data/sound/cdtracks/track009.ogg
   branches/nexuiz-2.0/data/sound/weapons/uzi_fire.ogg
   branches/nexuiz-2.0/data/weapons.cfg
Log:
- g_player_brightness cvar (still needs engine support)
- leileilol's effect updates
- sv_maxspeed 320 matches Q3
- ZeroRadiant project
- cd tracks now with replaygain
- silvercity fog
- animinfo (with example), tag_weapon support
- electro and crylink now fire a bit faster
- less cvar queries in game, mapinfo system as option
- better reset_map function
- jumppad.noise support
- ctf flag noalign support


Modified: branches/nexuiz-2.0/data/default.cfg
===================================================================
--- branches/nexuiz-2.0/data/default.cfg	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/default.cfg	2007-12-20 11:07:30 UTC (rev 3038)
@@ -236,6 +236,7 @@
 
 set g_cloaked 0
 set g_player_alpha 1
+set g_player_brightness 0 // set to 2 for brighter players
 seta g_balance_cloaked_alpha 0.25
 
 set welcome_message_time		8

Modified: branches/nexuiz-2.0/data/effectinfo.txt
===================================================================
--- branches/nexuiz-2.0/data/effectinfo.txt	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/effectinfo.txt	2007-12-20 11:07:30 UTC (rev 3038)
@@ -75,6 +75,19 @@
 liquidfriction 6
 //originjitter 32 32 32
 velocityjitter 256 256 256
+effect TE_KNIGHTSPIKE
+count 14
+type smoke
+tex 48 55
+color 0x800000 0xFF8020
+size 12 12
+alpha 0 256 100
+originjitter 1 1 1
+airfriction 5
+liquidfriction 16
+velocityjitter 23 23 183
+scalemultiplier 1
+gravity -0.04
 
 // machinegun bullet impact
 // bullet impact decal
@@ -90,38 +103,96 @@
 //lightcolor 1 1 1
 // dust/smoke drifting away from the impact
 effect TE_SPIKE
-count 8
+count 5
 type smoke
-tex 0 8
+tex 48 55
 color 0x101010 0x101010
-size 3 3
-sizeincrease 3
-alpha 255 255 256
-originjitter 0 0 0
-velocityjitter 8 8 8
+size 7 7
+alpha 0 256 100
+originjitter 1 1 1
+airfriction 5
+liquidfriction 16
+velocityjitter 183 183 183
+scalemultiplier 1
+gravity -0.04
 // dust/smoke staying at the impact
 effect TE_SPIKE
-count 1
+count 5
 type smoke
-tex 0 8
+tex 48 55
 color 0x505050 0x505050
-size 4 4
-sizeincrease 4
-alpha 255 255 128
-originjitter 0 0 0
-velocityjitter 0 0 0
+size 7 7
+alpha 0 256 100
+originjitter 1 1 1
+airfriction 3
+liquidfriction 16
+velocityjitter 85 85 85
+scalemultiplier 1
+gravity -0.04
+
 // bouncing sparks
 effect TE_SPIKE
-count 20
+count 12
+tex 40 40
 type spark
 color 0x8f4333 0xfff31b
 size 0.4 0.4
-alpha 0 256 256
-gravity 1
+alpha 0 256 7256
+gravity 0.6
 bounce 1.5
+airfriction 3
 velocityoffset 0 0 80
-velocityjitter 64 64 64
+velocityjitter 124 124 124
 
+/*
+effect TE_SPIKE
+count 3
+type spark
+tex 40 40
+color 0xFDFFD9 0xFDFFD9
+size 2 2
+alpha 511 512 644
+//gravity 1
+gravity 0
+airfriction 16
+bounce 1
+
+velocityoffset 0 0 45
+originjitter 1 1 1
+velocityjitter 777 777 777
+velocitymultiplier 65
+*/
+
+effect TE_SPIKE
+count 2
+type spark
+tex 40 40
+color 0xFDFFD9 0xFDFFD9
+size 6 4
+alpha 444 512 866
+gravity 1
+bounce 1
+airfriction 2
+velocityoffset 0 0 15
+originjitter 1 1 1
+velocityjitter 153 153 153
+velocitymultiplier 65
+
+effect TE_SPIKE
+count 14
+type spark
+tex 40 40
+color 0xFDFFD9 0xFDFFD9
+size 4 4
+alpha 444 512 866
+gravity 1
+bounce 1
+velocityoffset 0 0 15
+airfriction 5
+originjitter 1 1 1
+velocityjitter 888 888 888
+
+
 // electro combo explosion
 // decal
 effect TE_SPIKEQUAD
@@ -155,6 +226,19 @@
 liquidfriction 16
 //velocityoffset 0 0 120
 velocityjitter 512 512 512
+effect TE_SPIKEQUAD
+count 32
+type spark
+tex 41 41
+color 0xFDFFD9 0xFDFFD9
+size 16 16
+alpha 444 512 866
+gravity 1
+bounce 1
+velocityoffset 0 0 15
+airfriction 9
+originjitter 1 1 1
+velocityjitter 1333 1333 1333
 /*
 // inner cloud of smoke
 effect TE_SPIKEQUAD
@@ -275,11 +359,12 @@
 type smoke
 tex 0 8
 color 0x101010 0x101010
-size 3 3
-sizeincrease 3
+size 4 4
+sizeincrease 10
 alpha 128 128 64
 originjitter 0 0 0
-velocityjitter 8 8 8
+airfriction 8
+velocityjitter 30 30 30
 // dust/smoke staying at the impact
 effect TE_GUNSHOT
 count 1
@@ -303,6 +388,21 @@
 velocityoffset 0 0 80
 velocityjitter 64 64 64
 
+effect TE_GUNSHOT
+count 6
+type spark
+tex 40 40
+color 0xFDFFD9 0xFDFFD9
+size 3 2
+alpha 444 512 866
+gravity 1
+bounce 1
+velocityoffset 0 0 5
+airfriction 5
+originjitter 1 1 1
+velocityjitter 500 500 500
+
+
 /*
 // quake effect
 // decal
@@ -714,19 +814,36 @@
 type beam
 tex 60 60
 color 0xFFFFFF 0xFFFFFF
+size 6 6
+alpha 128 128 192
+
+// The RING smoke
+// experimental
+effect TE_TEI_G3
+trailspacing 12
+color 0x0B3E4F 0x0B3E4F
 size 4 4
-alpha 128 128 256
+tex 32 32
+alpha 0 256 100
+airfriction 5
+//liquidfriction -4
+sizeincrease 12
+//velocityjitter 4 4
+type static
+
+// The drifting smoke to accompany it
 // experimental
 effect TE_TEI_G3
-trailspacing 2
+trailspacing 8
+color 0x0B3E4F 0x0B3E4F
+size 4 4
+tex 48 55
+alpha 0 256 100
+airfriction 5
+//liquidfriction -4
+sizeincrease 16
+//velocityjitter 125 125 125
 type static
-color 0x202020 0x404040
-size 1 1
-alpha 256 256 512
-airfriction -4
-//liquidfriction -4
-velocityjitter 8 8 8
-type smoke
 /*
 // experimental
 effect TE_TEI_G3
@@ -994,6 +1111,21 @@
 lightcolor 1.5 3 6
 velocitymultiplier -0.1
 
+effect TR_NEXUIZ_PLASMA
+trailspacing 6
+count 3
+type spark
+tex 41 41
+color 0xFDFFD9 0xFDFFD9
+size 2 2
+alpha 444 512 1866
+gravity 1
+bounce 1
+velocityoffset 0 0 15
+airfriction 12
+originjitter 1 1 1
+velocityjitter 200 200
+
 // quake effect
 effect EF_FLAME
 count 300

Modified: branches/nexuiz-2.0/data/maps/silvercity.ent
===================================================================
--- branches/nexuiz-2.0/data/maps/silvercity.ent	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/maps/silvercity.ent	2007-12-20 11:07:30 UTC (rev 3038)
@@ -2,6 +2,7 @@
 "classname" "worldspawn"
 "message" "Silver City"
 "gridsize" "1024 1024 1024"
+"fog" "0.035 0.3 0.3 0.3 0 4000"
 }
 {
 "classname" "info_player_deathmatch"

Modified: branches/nexuiz-2.0/data/maps/silvercity.map
===================================================================
--- branches/nexuiz-2.0/data/maps/silvercity.map	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/maps/silvercity.map	2007-12-20 11:07:30 UTC (rev 3038)
@@ -4,6 +4,7 @@
 "classname" "worldspawn"
 "gridsize" "1024 1024 1024"
 "message" "SilverCity"
+"fog" "0.035 0.3 0.3 0.3 0 4000"
 // brush 0
 {
 ( -2176 -2120 2336 ) ( -2176 -2120 -392 ) ( -2176 2120 -392 ) sav-graysky1/sav-graysky2_skybox 0 0 0 0.5 0.5 0 0 0

Added: branches/nexuiz-2.0/data/models/player/template.md3.animinfo
===================================================================
--- branches/nexuiz-2.0/data/models/player/template.md3.animinfo	                        (rev 0)
+++ branches/nexuiz-2.0/data/models/player/template.md3.animinfo	2007-12-20 11:07:30 UTC (rev 3038)
@@ -0,0 +1,21 @@
+  0 40 20 // die1         : die
+ 40 40 20 // die2         : die differently
+ 80  6 20 // draw         : raise weapon
+ 86  6 20 // duck         : crouch quickly
+ 92 12 20 // duckwalk     : crouch walking
+104 10 20 // duckjump     : jump from crouching position, stays on last frame until you land
+114 20 20 // duckidle     : crouched
+134 30 20 // idle         : standing
+164 10 20 // jump         : jump, stays on last frame until you land
+174 10 20 // pain1        : flinch from pain
+184 10 20 // pain2        : flinch differently
+194  6 20 // shoot        : 300ms shooting anim, may be played faster/slower by code, used for all weapons
+200  1 20 // taunt        : not used
+201 10 20 // run          : run forward
+211 10 20 // runbackwards : run backwards
+221 10 20 // strafeleft   : fast shuffling to the left
+231 10 20 // straferight  : fast shuffling to the right
+241 10 20 // forwardright : running forward and right
+251 10 20 // forwardleft  : running forward and left
+261 10 20 // backright    : running backward and right
+271 10 20 // backleft     : running backward and left
\ No newline at end of file

Modified: branches/nexuiz-2.0/data/models/uziflash.md3
===================================================================
(Binary files differ)

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

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

Modified: branches/nexuiz-2.0/data/physicsQ3.cfg
===================================================================
--- branches/nexuiz-2.0/data/physicsQ3.cfg	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/physicsQ3.cfg	2007-12-20 11:07:30 UTC (rev 3038)
@@ -1,5 +1,5 @@
 // these values match Quake3
-sv_maxspeed 400
+sv_maxspeed 320
 sv_maxairspeed $sv_maxspeed
 sv_accelerate 10
 sv_airaccelerate 1

Modified: branches/nexuiz-2.0/data/qcsrc/client/csqc_builtins.h
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/csqc_builtins.h	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/client/csqc_builtins.h	2007-12-20 11:07:30 UTC (rev 3038)
@@ -1,4 +1,5 @@
 void (vector ang)							makevectors = #1;
+void(entity e, vector o) setorigin	= #2;
 void (entity e, string m)						setmodel = #3;
 
 void ()									break = #6;

Modified: branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.h
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.h	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.h	2007-12-20 11:07:30 UTC (rev 3038)
@@ -73,6 +73,7 @@
 const float EF_NOSHADOW		= 4096;
 const float EF_RED		= 128;
 const float EF_STARDUST		= 2048;
+const float EF_SELECTABLE 	= 16384;
 
 const float PFL_ONGROUND	= 1;
 const float PFL_CROUCH		= 2;

Modified: branches/nexuiz-2.0/data/qcsrc/server/arena.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/arena.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/arena.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -15,21 +15,72 @@
 void(entity e) DropFlag;
 void(entity e) ReturnFlag;
 void(entity e) removedecor;
+void dom_controlpoint_setup();
 
 void reset_map()
 {
+	if(g_arena)
 	if(cvar("g_arena_warmup"))
 		warmup = time + cvar("g_arena_warmup");
 	
+	lms_lowest_lives = 999;
+	lms_next_place = player_count;
+
 	self = nextent(world);
 	while(self)
 	{
-		if(self.classname == "droppedweapon"		// cleanup
+		if(self.flags & FL_CLIENT)				// reset all players
+		{
+			if(time < restart_countdown)
+			{
+				self.frags = (g_lms)?LMS_NewPlayerLives():0;
+				self.deaths = 0;
+				self.killcount = 0;
+				self.classname = "player";
+				PutClientInServer();
+			}
+			else if(g_arena)
+			{
+				if(self.spawned)
+					PutClientInServer();
+				else
+					PutObserverInServer();
+			}
+		}
+		else if(self.classname == STR_ITEM_KH_KEY)
+		{
+			kh_Key_AssignTo(self, world);
+			//if(self.owner)
+			//	kh_Key_DropAll(self.owner, TRUE);
+			kh_Key_Remove(self);
+		}
+		else if(self.classname == "droppedweapon"		// cleanup
 				|| self.classname == "gib"
 				|| self.classname == "body")
 		{
 			remove(self);
 		}
+		else if(self.items & (IT_KEY1 | IT_KEY2))
+		{
+			DropFlag(self);
+			ReturnFlag(self);
+		}
+		else if(self.classname == "rune")
+		{
+			if(self.owner)
+			if(self.owner.classname != "runematch_spawn_point")
+				DropAllRunes(self.owner);
+			rune_respawn();
+		}
+		else if(self.classname == "sprite_waypoint")
+		{
+			if(self.health | g_keyhunt)
+				WaypointSprite_Kill(self);
+		}
+		else if(self.classname == "dom_controlpoint")
+		{
+			dom_controlpoint_setup();
+		}
 		else if(self.flags & FL_ITEM)			// reset items
 		{
 			self.model = self.mdl;
@@ -48,17 +99,13 @@
 		{
 			removedecor(self);
 		}
-		else if(self.flags & FL_CLIENT)			// reset all players
-		{
-			if(self.spawned)
-				PutClientInServer();
-			else
-				PutObserverInServer();
-		}
-		
 		self = nextent(self);
 	}
 
+	if(g_keyhunt)
+		kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_round")+RESTART_COUNTDOWN, "", kh_StartRound);
+
+	if(g_arena)
 	if(champion)
 		UpdateFrags(champion, +1);
 }
@@ -117,7 +164,7 @@
 	float f;
 	string msg;
 
-	if(!arena_roundbased)
+	if(!g_arena || !arena_roundbased || (time < restart_countdown))
 		return;
 
 	f = rint(warmup - time);

Modified: branches/nexuiz-2.0/data/qcsrc/server/bots.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/bots.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/bots.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -1783,7 +1783,7 @@
 	//self.bot_painintensity = self.bot_painintensity + self.bot_oldhealth - self.health;
 	//self.bot_painintensity = bound(0, self.bot_painintensity, 100);
 
-	if(cvar("g_campaign") && !campaign_bots_may_start)
+	if(time < restart_countdown || ((cvar("g_campaign") && !campaign_bots_may_start)))
 	{
 		self.nextthink = time + 0.5;
 		return;

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -193,6 +193,9 @@
 	else if(cvar("sv_servermodelsonly"))
 	{
 		if(substring(plyermodel,strlen(plyermodel)-4,4) != ".zym")
+		if(substring(plyermodel,strlen(plyermodel)-4,4) != ".dpm")
+		if(substring(plyermodel,strlen(plyermodel)-4,4) != ".md3")
+		if(substring(plyermodel,strlen(plyermodel)-4,4) != ".psk")
 			return FallbackPlayerModel;
 		if(!fexists(plyermodel))
 			return FallbackPlayerModel;
@@ -248,7 +251,8 @@
 #ifdef ALLOW_VARIABLE_LOD
 	string s;
 
-	s = strcat(substring(modelname, 0, strlen(modelname) - 4), "_1.zym");
+	// FIXME: this only supports 3-letter extensions
+	s = strcat(substring(modelname, 0, strlen(modelname) - 4), "_1", substring(modelname, 0, strlen(modelname) - 4));
 	if(fexists(s))
 	{
 		precache_model(s);
@@ -258,7 +262,7 @@
 	else
 		self.modelindex_lod1 = -1;
 
-	s = strcat(substring(modelname, 0, strlen(modelname) - 4), "_2.zym");
+	s = strcat(substring(modelname, 0, strlen(modelname) - 4), "_2", substring(modelname, 0, strlen(modelname) - 4));
 	if(fexists(s))
 	{
 		precache_model(s);
@@ -281,6 +285,7 @@
 	precache_model(modelname);
 	setmodel(e, modelname); // players have high precision
 #endif
+	player_setupanimsformodel();
 }
 
 /*
@@ -332,9 +337,7 @@
 	self.pauseregen_finished = 0;
 	self.damageforcescale = 0;
 	self.death_time = 0;
-	self.dead_time = 0;
 	self.dead_frame = 0;
-	self.die_frame = 0;
 	self.deaths = 0;
 	self.alpha = 0;
 	self.scale = 0;
@@ -451,9 +454,7 @@
 		self.pauseregen_finished = time + cvar("g_balance_pause_health_regen_spawn");
 		self.damageforcescale = 2;
 		self.death_time = 0;
-		self.dead_time = 0;
 		self.dead_frame = 0;
-		self.die_frame = 0;
 		self.alpha = 0;
 		self.scale = 0;
 		self.fade_time = 0;
@@ -547,6 +548,7 @@
 
 		CL_SpawnWeaponentity();
 		self.alpha = default_player_alpha;
+		self.colormod = '1 1 1' * cvar("g_player_brightness");
 		self.exteriorweaponentity.alpha = default_weapon_alpha;
 
 		self.lms_nextcheck = time + cvar("g_lms_campcheck_interval")*2;
@@ -672,7 +674,7 @@
 
 	bot_clientconnect();
 
-	//if(cvar("g_domination"))
+	//if(g_domination)
 	//	dom_player_join_team(self);
 
 	//JoinBestTeam(self, FALSE);
@@ -702,7 +704,7 @@
 	bprint ("^4",self.netname);
 	bprint ("^4 connected");
 
-	if(cvar("g_domination") || g_ctf)
+	if(g_domination || g_ctf)
 	{
 		bprint(" and joined the ");
 		bprint(ColoredTeamName(self.team));
@@ -755,16 +757,9 @@
 
 	if(g_lms)
 	{
-		self.frags = cvar("fraglimit");
-		// no fraglimit was set, so player gets 999 lives
-		if(self.frags < 1)
-			self.frags = 999;
-
 		self.frags = LMS_NewPlayerLives();
 		if(!self.frags)
-		{
 			self.frags = -666;
-		}
 	}
 	else if(g_arena)
 	{
@@ -1357,8 +1352,7 @@
 			dist_z = 0;
 			self.lms_traveled_distance += fabs(vlen(dist));
 
-			if(cvar("g_campaign"))
-			if(!campaign_bots_may_start)
+			if((cvar("g_campaign") && !campaign_bots_may_start) || (time < restart_countdown))
 			{
 				self.lms_nextcheck = time + cvar("g_lms_campcheck_interval")*2;
 				self.lms_traveled_distance = 0;
@@ -1386,6 +1380,7 @@
 				self.crouch = TRUE;
 				self.view_ofs = PL_CROUCH_VIEW_OFS;
 				setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX);
+				player_setanim(self.anim_duck, FALSE, TRUE, TRUE);
 			}
 		}
 		else
@@ -1586,16 +1581,37 @@
 		UpdateChatBubble();
 		UpdateTeamBubble();
 		if (self.impulse)
-			ImpulseCommands ();
+			ImpulseCommands();
 		if (intermission_running)
 			return;		// intermission or finale
 
 		//PrintWelcomeMessage(self);
 		//if (TetrisPostFrame()) return;
+	
+		// restart countdown
+		if(time < restart_countdown)
+		{
+			string s;
+			float sec;
+
+			sec = ceil(restart_countdown-time);
+			s = strcat(NEWLINES, "^1Game starts in ", ftos(sec), " seconds");
+			centerprint(self, s);
+			self.movetype = MOVETYPE_NONE;		
+			self.velocity = '0 0 0';
+			self.avelocity = '0 0 0';
+			self.movement = '0 0 0';
+		}
+		else if(self.movetype == MOVETYPE_NONE)
+		{
+			self.movetype = MOVETYPE_WALK;
+			centerprint(self, "\n");
+		}
 	} else if (self.classname == "observer") {
 		//do nothing
 	} else if (self.classname == "spectator") {
 		//do nothing
 	}
+
 	Arena_Warmup();
 }

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -49,7 +49,7 @@
 	if (!(self.flags & FL_JUMPRELEASED))
 		return;
 
-	if(cvar("g_runematch"))
+	if(g_runematch)
 	{
 		if(self.runes & RUNE_SPEED)
 		{
@@ -74,6 +74,11 @@
 
 	self.flags = self.flags - FL_ONGROUND;
 	self.flags = self.flags - FL_JUMPRELEASED;
+
+	if (self.crouch)
+		player_setanim(self.anim_duckjump, FALSE, TRUE, TRUE);
+	else
+		player_setanim(self.anim_jump, FALSE, TRUE, TRUE);
 }
 
 void() CheckWaterJump =
@@ -157,7 +162,7 @@
 
 	maxspd_mod = 1;
 
-	if(cvar("g_runematch"))
+	if(g_runematch)
 	{
 		if(self.runes & RUNE_SPEED)
 		{

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -1,7 +1,3 @@
-$frame die1 die2 draw duck duckwalk duckjump duckidle idle
-$frame jump pain1 pain2 shoot taunt run runbackwards
-$frame strafeleft straferight dead1 dead2 forwardright
-$frame forwardleft backright backleft
 
 // changes by LordHavoc on 03/29/04 and 03/30/04 at Vermeulen's request
 // merged player_run and player_stand to player_anim
@@ -32,7 +28,16 @@
 	self.damageforcescale = oldself.damageforcescale;
 	self.effects = oldself.effects;
 	self.event_damage = oldself.event_damage;
+	self.animstate_startframe = oldself.animstate_startframe;
+	self.animstate_numframes = oldself.animstate_numframes;
+	self.animstate_framerate = oldself.animstate_framerate;
+	self.animstate_starttime = oldself.animstate_starttime;
+	self.animstate_endtime = oldself.animstate_endtime;
+	self.animstate_override = oldself.animstate_override;
+	self.animstate_looping = oldself.animstate_looping;
 	self.frame = oldself.frame;
+	self.dead_frame = oldself.dead_frame;
+	self.pain_finished = oldself.pain_finished;
 	self.health = oldself.health;
 	self.armorvalue = oldself.armorvalue;
 	self.armortype = oldself.armortype;
@@ -58,11 +63,137 @@
 	self = oldself;
 }
 
+float animparseerror;
+vector(float animfile) animparseline =
+{
+	local string line;
+	local float c;
+	local vector anim;
+	if (animfile < 0)
+		return '0 1 2';
+	line = fgets(animfile);
+	c = tokenize(line);
+	if (c != 3)
+	{
+		animparseerror = TRUE;
+		return '0 1 2';
+	}
+	anim_x = stof(argv(0));
+	anim_y = stof(argv(1));
+	anim_z = stof(argv(2));
+	// don't allow completely bogus values
+	if (anim_x < 0 || anim_y < 1 || anim_z < 0.001)
+		anim = '0 1 2';
+	return anim;
+};
+
+void() player_setupanimsformodel =
+{
+	local string animfilename;
+	local float animfile;
+	// defaults for legacy .zym models without animinfo files
+	self.anim_die1 = '0 1 0.5'; // 2 seconds
+	self.anim_die2 = '1 1 0.5'; // 2 seconds
+	self.anim_draw = '2 1 3'; // TODO: analyze models and set framerate
+	self.anim_duck = '3 1 100'; // this anim seems bogus in most models, so make it play VERY briefly!
+	self.anim_duckwalk = '4 1 1';
+	self.anim_duckjump = '5 1 100'; // zym anims keep playing until changed, so this only has to start the anim, landing will end it
+	self.anim_duckidle = '6 1 1';
+	self.anim_idle = '7 1 1';
+	self.anim_jump = '8 1 100'; // zym anims keep playing until changed, so this only has to start the anim, landing will end it
+	self.anim_pain1 = '9 1 2'; // 0.5 seconds
+	self.anim_pain2 = '10 1 2'; // 0.5 seconds
+	self.anim_shoot = '11 1 5'; // TODO: analyze models and set framerate
+	self.anim_taunt = '12 1 1'; // FIXME?  there is no code using this anim
+	self.anim_run = '13 1 1';
+	self.anim_runbackwards = '14 1 1';
+	self.anim_strafeleft = '15 1 1';
+	self.anim_straferight = '16 1 1';
+	self.anim_dead1 = '17 1 1';
+	self.anim_dead2 = '18 1 1';
+	self.anim_forwardright = '19 1 1';
+	self.anim_forwardleft = '20 1 1';
+	self.anim_backright = '21 1 1';
+	self.anim_backleft  = '22 1 1';
+	animparseerror = FALSE;
+	animfilename = strcat(self.model, ".animinfo");
+	animfile = fopen(animfilename, FILE_READ);
+	if (animfile >= 0)
+	{
+		self.anim_die1         = animparseline(animfile);
+		self.anim_die2         = animparseline(animfile);
+		self.anim_draw         = animparseline(animfile);
+		self.anim_duck         = animparseline(animfile);
+		self.anim_duckwalk     = animparseline(animfile);
+		self.anim_duckjump     = animparseline(animfile);
+		self.anim_duckidle     = animparseline(animfile);
+		self.anim_idle         = animparseline(animfile);
+		self.anim_jump         = animparseline(animfile);
+		self.anim_pain1        = animparseline(animfile);
+		self.anim_pain2        = animparseline(animfile);
+		self.anim_shoot        = animparseline(animfile);
+		self.anim_taunt        = animparseline(animfile);
+		self.anim_run          = animparseline(animfile);
+		self.anim_runbackwards = animparseline(animfile);
+		self.anim_strafeleft   = animparseline(animfile);
+		self.anim_straferight  = animparseline(animfile);
+		self.anim_forwardright = animparseline(animfile);
+		self.anim_forwardleft  = animparseline(animfile);
+		self.anim_backright    = animparseline(animfile);
+		self.anim_backleft     = animparseline(animfile);
+		fclose(animfile);
+
+		// derived anims
+		self.anim_dead1 = '0 1 1' + '1 0 0' * (self.anim_die1_x + self.anim_die1_y - 1);
+		self.anim_dead2 = '0 1 1' + '1 0 0' * (self.anim_die2_x + self.anim_die2_y - 1);
+
+		if (animparseerror)
+			print("Parse error in ", animfilename, ", some player animations are broken\n");
+	}
+	else
+		dprint("File ", animfilename, " not found, assuming legacy .zym model animation timings\n");
+	// reset animstate now
+	player_setanim(self.anim_idle, TRUE, FALSE, TRUE);
+};
+
+void(vector anim, float looping, float override, float restart) player_setanim =
+{
+	if (!restart)
+	if (anim_x == self.animstate_startframe)
+	if (anim_y == self.animstate_numframes)
+	if (anim_z == self.animstate_framerate)
+		return;
+	self.animstate_startframe = anim_x;
+	self.animstate_numframes = anim_y;
+	self.animstate_framerate = anim_z;
+	self.animstate_starttime = time;
+	self.animstate_endtime = time + self.animstate_numframes / self.animstate_framerate;
+	self.animstate_looping = looping;
+	self.animstate_override = override;
+	self.frame = self.animstate_startframe;
+};
+
+void() player_updateframe =
+{
+	if (time >= self.animstate_endtime)
+	{
+		if (self.animstate_looping)
+		{
+			self.animstate_starttime = self.animstate_endtime;
+			self.animstate_endtime = self.animstate_endtime + self.animstate_numframes / self.animstate_framerate;
+		}
+		self.animstate_override = FALSE;
+	}
+	self.frame = self.animstate_startframe + bound(0, (time - self.animstate_starttime) * self.animstate_framerate, self.animstate_numframes - 1);
+};
+
 void player_anim (void)
 {
+	player_updateframe();
+
 	if (self.deadflag != DEAD_NO)
 	{
-		if (time > self.dead_time)
+		if (time > self.animstate_endtime)
 		{
 			if (self.maxs_z > 5)
 			{
@@ -71,54 +202,49 @@
 			}
 			self.frame = self.dead_frame;
 		}
-		else
-			self.frame = self.die_frame;
 		return;
 	}
 
-
-	if (self.crouch)
+	if (!self.animstate_override)
 	{
-		if (self.movement_x * self.movement_x + self.movement_y * self.movement_y > 20)
-			self.frame = $duckwalk;
+		if (!(self.flags & FL_ONGROUND))
+		{
+			if (self.crouch)
+				player_setanim(self.anim_duckjump, FALSE, TRUE, FALSE);
+			else
+				player_setanim(self.anim_jump, FALSE, TRUE, FALSE);
+		}
+		else if (self.crouch)
+		{
+			if (self.movement_x * self.movement_x + self.movement_y * self.movement_y > 20)
+				player_setanim(self.anim_duckwalk, TRUE, FALSE, FALSE);
+			else
+				player_setanim(self.anim_duckidle, TRUE, FALSE, FALSE);
+		}
+		else if ((self.movement_x * self.movement_x + self.movement_y * self.movement_y) > 20)
+		{
+			if (self.movement_x > 0 && self.movement_y == 0)
+				player_setanim(self.anim_run, TRUE, FALSE, FALSE);
+			else if (self.movement_x < 0 && self.movement_y == 0)
+				player_setanim(self.anim_runbackwards, TRUE, FALSE, FALSE);
+			else if (self.movement_x == 0 && self.movement_y > 0)
+				player_setanim(self.anim_straferight, TRUE, FALSE, FALSE);
+			else if (self.movement_x == 0 && self.movement_y < 0)
+				player_setanim(self.anim_strafeleft, TRUE, FALSE, FALSE);
+			else if (self.movement_x > 0 && self.movement_y > 0)
+				player_setanim(self.anim_forwardright, TRUE, FALSE, FALSE);
+			else if (self.movement_x > 0 && self.movement_y < 0)
+				player_setanim(self.anim_forwardleft, TRUE, FALSE, FALSE);
+			else if (self.movement_x < 0 && self.movement_y > 0)
+				player_setanim(self.anim_backright, TRUE, FALSE, FALSE);
+			else if (self.movement_x < 0 && self.movement_y < 0)
+				player_setanim(self.anim_backleft, TRUE, FALSE, FALSE);
+			else
+				player_setanim(self.anim_run, TRUE, FALSE, FALSE);
+		}
 		else
-			self.frame = $duckidle;
+			player_setanim(self.anim_idle, TRUE, FALSE, FALSE);
 	}
-	else if ((self.movement_x * self.movement_x + self.movement_y * self.movement_y) > 20)
-	{
-		if (self.movement_x > 0 && self.movement_y == 0)
-			self.frame = $run;
-		else if (self.movement_x < 0 && self.movement_y == 0)
-			self.frame = $runbackwards;
-		else if (self.movement_x == 0 && self.movement_y > 0)
-			self.frame = $straferight;
-		else if (self.movement_x == 0 && self.movement_y < 0)
-			self.frame = $strafeleft;
-		else if (self.movement_x > 0 && self.movement_y > 0)
-			self.frame = $forwardright;
-		else if (self.movement_x > 0 && self.movement_y < 0)
-			self.frame = $forwardleft;
-		else if (self.movement_x < 0 && self.movement_y > 0)
-			self.frame = $backright;
-		else if (self.movement_x < 0 && self.movement_y < 0)
-			self.frame = $backleft;
-		else
-			self.frame = $run;
-	}
-	else if (self.pain_finished > time)
-		self.frame = self.pain_frame;
-	else if (ATTACK_FINISHED(self) > time)
-		self.frame = $shoot;
-	else
-		self.frame = $idle;
-
-	if (!(self.flags & FL_ONGROUND))
-	{
-		if (self.crouch)
-			self.frame = $duckidle;		// if player is crouching while in air, show crouch frame
-		else
-			self.frame = $jump;
-	}
 }
 //End change by Supajoe on 11:44 PM EST 11/16/03 (Subject: Player animations)
 
@@ -173,7 +299,6 @@
 		// don't use any animations as a gib
 		self.frame = 0;
 		self.dead_frame = 0;
-		self.die_frame = 0;
 		// view just above the floor
 		self.view_ofs = '0 0 4';
 
@@ -224,9 +349,9 @@
 	if (self.pain_finished < time)		//Don't switch pain sequences like crazy
 	{
 		if (random() > 0.5)
-			self.pain_frame = $pain1;
+			player_setanim(self.anim_pain1, FALSE, TRUE, TRUE);
 		else
-			self.pain_frame = $pain2;
+			player_setanim(self.anim_pain2, FALSE, TRUE, TRUE);
 		self.pain_finished = time + 0.5;	//Supajoe
 
 		// throw off bot aim temporarily
@@ -360,20 +485,16 @@
 			self.respawn_countdown = 10; // first number to count down from is 10
 		else
 			self.respawn_countdown = -1; // do not count down
-		// when to switch to the dead_frame
-		self.dead_time = time + 2;
 		if (random() < 0.5)
 		{
-			self.die_frame = $die1;
-			self.dead_frame = $dead1;
+			player_setanim(self.anim_die1, FALSE, TRUE, TRUE);
+			self.dead_frame = self.anim_dead1_x;
 		}
 		else
 		{
-			self.die_frame = $die2;
-			self.dead_frame = $dead2;
+			player_setanim(self.anim_die2, FALSE, TRUE, TRUE);
+			self.dead_frame = self.anim_dead2_x;
 		}
-		// start the animation
-		player_anim();
 		// set damage function to corpse damage
 		self.event_damage = PlayerCorpseDamage;
 		// call the corpse damage function just in case it wants to gib

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_weapons.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -210,8 +210,7 @@
 // Bringed back weapon frame
 void() W_WeaponFrame =
 {
-	if(arena_roundbased)
-	if(time < warmup)
+	if((arena_roundbased && time < warmup) || (time < restart_countdown))
 		return;
 
 	if (!self.weaponentity || self.health < 1)
@@ -231,6 +230,7 @@
 	{
 		if (self.weaponentity.state == WS_CLEAR)
 		{
+			player_setanim(self.anim_draw, FALSE, TRUE, TRUE);
 			self.weaponentity.state = WS_RAISE;
 			weapon_action(self.switchweapon, WR_SETUP);
 			// VorteX: add player model weapon select frame here

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_weaponsystem.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -197,6 +197,7 @@
 
 void() CL_ExteriorWeaponentity_Think =
 {
+	float tag_found;
 	self.nextthink = time;
 	if (self.owner.exteriorweaponentity != self)
 	{
@@ -217,7 +218,15 @@
 			setmodel(self, strcat("models/weapons/v_", self.owner.weaponname, ".md3")); // precision set below
 		else
 			self.model = "";
-		setattachment(self, self.owner, "bip01 r hand");
+
+		if((tag_found = gettagindex(self.owner, "tag_weapon")))
+		{
+			self.tag_index = tag_found;
+			self.tag_entity = self.owner;
+		}
+		else
+			setattachment(self, self.owner, "bip01 r hand");
+
 		// if that didn't find a tag, hide the exterior weapon model
 		if (!self.tag_index)
 			self.model = "";
@@ -392,7 +401,7 @@
 		backtrace("Tried to override initial weapon think function - should this really happen?");
 	}
 
-	if(cvar("g_runematch"))
+	if(g_runematch)
 	{
 		if(self.runes & RUNE_SPEED)
 		{
@@ -410,6 +419,15 @@
 	// VorteX: haste can be added here
 	self.weapon_nextthink = max(time, self.weapon_nextthink_lastframe + t);
 	self.weapon_think = func;
+
+	if (fr == WFRAME_FIRE1 || fr == WFRAME_FIRE2)
+	if (t)
+	{
+		local vector anim;
+		anim = self.anim_shoot;
+		anim_z = anim_y / t;
+		player_setanim(anim, FALSE, TRUE, TRUE);
+	}
 };
 
 void(float spd, vector org) weapon_boblayer1 =

Modified: branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -427,9 +427,14 @@
 	} else if(argv(0) == "ready") {
 		if(cvar("sv_ready_restart"))
 		{
-			self.ready = TRUE;
-			bprint(self.netname, "^2 is ready\n");
-			ReadyCount();
+			if(!restart_countdown)
+			{
+				self.ready = TRUE;
+				bprint(self.netname, "^2 is ready\n");
+				ReadyCount();
+			} else {
+				sprint(self, "^1game has already been restarted\n");
+			}
 		}
 	} else if(argv(0) == "maplist") {
 		local float i, n;
@@ -691,6 +696,7 @@
 	} // else still running
 }
 
+float timelimit_orig;
 
 void ReadyCount()
 {
@@ -704,9 +710,26 @@
 			r += 1;
 	}
 
-	if(p && r == p)
+	if(!p || r < p)
+		return;
+
+	bprint("^1Server is restarting...\n");
+	
+	// no arena, assault & onslaught support yet...
+	if(g_arena | g_assault | g_onslaught | gameover | intermission_running)
+		localcmd("restart\n");
+
+	restart_countdown = time + RESTART_COUNTDOWN;
+	if(0<cvar("timelimit"))
 	{
-		bprint("^1Server is restarting...\n");
-		localcmd("restart\n");
+		// remember original timelimit on first restart
+		if(!timelimit_orig)
+			timelimit_orig = cvar("timelimit");
+		cvar_set("timelimit", ftos(timelimit_orig + ceil(restart_countdown)/60));
 	}
+
+	reset_map();
+	
+	if(cvar("sv_eventlog"))
+		GameLogEcho(":restart", FALSE);
 }

Modified: branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -24,7 +24,7 @@
 	self.mdl = self.model;
 	self.flags = FL_ITEM;
 	self.solid = SOLID_TRIGGER;
-	self.movetype = MOVETYPE_TOSS;
+	self.movetype = MOVETYPE_NONE;
 	self.velocity = '0 0 0';
 	self.origin_z = self.origin_z + 6;
 	self.think = FlagThink;
@@ -34,11 +34,15 @@
 	self.mangle = self.angles;
 	self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
 	//self.effects = self.effects | EF_DIMLIGHT;
-	if (!droptofloor())
+	if(!self.noalign)
 	{
-		dprint("Flag fell out of level at ", vtos(self.origin), "\n");
-		remove(self);
-		return;
+		self.movetype = MOVETYPE_TOSS;
+		if (!droptofloor())
+		{
+			dprint("Flag fell out of level at ", vtos(self.origin), "\n");
+			remove(self);
+			return;
+		}
 	}
 	self.oldorigin = self.origin;
 };
@@ -58,7 +62,9 @@
 void(entity e) RegenFlag =
 {
 	setattachment(e, world, "");
-	e.movetype = MOVETYPE_TOSS;
+	e.movetype = MOVETYPE_NONE;
+	if(!self.noalign)
+		e.movetype = MOVETYPE_TOSS;
 	e.solid = SOLID_TRIGGER;
 	// TODO: play a sound here
 	setorigin(e, e.oldorigin);
@@ -406,6 +412,8 @@
 	self.netname = "^1RED^7 flag";
 	self.target = "###item###";
 	self.skin = 0;
+	if(self.spawnflags & 1)
+		self.noalign = 1;
 	if (!self.model)
 		self.model = "models/ctf/flag_red.md3";
 	if (!self.noise)
@@ -433,7 +441,8 @@
 	//	self.glow_size = 50;
 
 	self.effects = self.effects | EF_FULLBRIGHT | EF_LOWPRECISION;
-	droptofloor();
+	if(!self.noalign)
+		droptofloor();
 
 	WaypointSprite_SpawnFixed("redbase", self.origin + '0 0 37');
 };
@@ -462,6 +471,8 @@
 	self.netname = "^4BLUE^7 flag";
 	self.target = "###item###";
 	self.skin = 0;
+	if(self.spawnflags & 1)
+		self.noalign = 1;
 	if (!self.model)
 		self.model = "models/ctf/flag_blue.md3";
 	if (!self.noise)
@@ -489,7 +500,8 @@
 	//	self.glow_size = 50;
 
 	self.effects = self.effects | EF_FULLBRIGHT | EF_LOWPRECISION;
-	droptofloor();
+	if(!self.noalign)
+		droptofloor();
 
 	WaypointSprite_SpawnFixed("bluebase", self.origin + '0 0 37');
 };

Modified: branches/nexuiz-2.0/data/qcsrc/server/defs.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2007-12-20 11:07:30 UTC (rev 3038)
@@ -1,6 +1,6 @@
 // Globals
 
-float g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught, g_assault, g_arena, g_lms;
+float g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught, g_assault, g_arena, g_lms, g_runematch;
 float g_cloaked, g_footsteps, g_grappling_hook, g_instagib, g_laserguided_missile, g_midair, g_minstagib, g_nixnex, g_nixnex_with_laser, g_norecoil, g_rocketarena, g_vampire;
 
 float sv_cheats;
@@ -68,12 +68,51 @@
 
 .float play_time;
 .float death_time;
-.float dead_time;
 .float dead_frame;
-.float die_frame;
 .float fade_time;
 .float fade_rate;
 
+// player animation state
+.float animstate_startframe;
+.float animstate_numframes;
+.float animstate_framerate;
+.float animstate_starttime;
+.float animstate_endtime;
+.float animstate_override;
+.float animstate_looping;
+
+// player animation data for this model
+// each vector is as follows:
+// _x = startframe
+// _y = numframes
+// _z = framerate
+.vector anim_die1; // player dies
+.vector anim_die2; // player dies differently
+.vector anim_draw; // player pulls out a weapon
+.vector anim_duck; // player crouches (from idle to duckidle)
+.vector anim_duckwalk; // player walking while crouching
+.vector anim_duckjump; // player jumping from a crouch
+.vector anim_duckidle; // player idling while crouching
+.vector anim_idle; // player standing
+.vector anim_jump; // player jump
+.vector anim_pain1; // player flinches from pain
+.vector anim_pain2; // player flinches from pain, differently
+.vector anim_shoot; // player shoots
+.vector anim_taunt; // player taunts others (FIXME: no code references this)
+.vector anim_run; // player running forward
+.vector anim_runbackwards; // player running backward
+.vector anim_strafeleft; // player shuffling left quickly
+.vector anim_straferight; // player shuffling right quickly
+.vector anim_dead1; // player dead (must be identical to last frame of die1)
+.vector anim_dead2; // player dead (must be identical to last frame of die2)
+.vector anim_forwardright; // player running forward and right
+.vector anim_forwardleft; // player running forward and left
+.vector anim_backright; // player running backward and right
+.vector anim_backleft; // player running back and left
+
+void() player_setupanimsformodel;
+void(vector anim, float looping, float override, float restart) player_setanim;
+
 .string mdl;
 
 .string playermodel;
@@ -231,6 +270,8 @@
 .float nextstep;
 
 .float ready;
+#define RESTART_COUNTDOWN 10
+float restart_countdown;
 
 .float winning;
 .float deaths;

Modified: branches/nexuiz-2.0/data/qcsrc/server/domination.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/domination.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/domination.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -99,21 +99,9 @@
 
 	// give points
 
-	if (gameover)	// game has ended, don't keep giving points
+	if (gameover || self.delay > time || time < restart_countdown)	// game has ended, don't keep giving points
 		return;
 
-	if(self.delay > time)
-		return;
-
-/*
-	if(self.state == 1)
-	{
-		self.state = 0;
-		dompoint_captured();
-		return;
-	}
-*/
-
 	waittime = cvar("g_domination_point_rate");
 	if(!waittime)
 		waittime = self.wait;
@@ -480,7 +468,7 @@
 */
 void() dom_controlpoint =
 {
-	if(!cvar("g_domination"))
+	if(!g_domination)
 	{
 		remove(self);
 		return;

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -15,13 +15,13 @@
 		if(cvar("g_arena_roundbased"))
 			return;
 
-	if(cvar("g_domination"))
+	if(g_domination)
 	{
 		if(cvar("g_domination_disable_frags"))
 			if(f > 0)
 				return;
 	}
-	else if(cvar("g_runematch"))
+	else if(g_runematch)
 	{
 		if(f > 0)
 			f = RunematchHandleFrags(attacker, targ, f);
@@ -450,7 +450,7 @@
 			damage = damage * cvar("g_balance_powerup_invincible_takedamage");
 
 
-		if(cvar("g_runematch"))
+		if(g_runematch)
 		{
 			// apply strength rune
 			if (attacker.runes & RUNE_STRENGTH)
@@ -503,7 +503,7 @@
 		{
 			attacker.health += damage;
 		}
-		if(cvar("g_runematch"))
+		if(g_runematch)
 		{
 			if (attacker.runes & RUNE_VAMPIRE)
 			{

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_hook.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -201,8 +201,7 @@
 	local entity missile;
 	local vector org;
 
-	if(arena_roundbased)
-	if(time < warmup)
+	if((arena_roundbased && time < warmup) || (time < restart_countdown))
 		return;
 
 	makevectors(self.v_angle);

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -84,16 +84,12 @@
 float world_already_spawned;
 void worldspawn (void)
 {
-	float globhandle, i, n;
-
 	dprint_load(); // load dprint status from cvar
 
 	if(world_already_spawned)
 		error("world already spawned - you may have EXACTLY ONE worldspawn!");
 	world_already_spawned = TRUE;
 
-	sv_cheats = cvar("sv_cheats");
-
 	/*
 	TODO sound pack system
 	// initialize sound pack system
@@ -103,145 +99,6 @@
 	soundpack = strzone(soundpack);
 	*/
 
-	// gamemode related things
-	precache_model ("models/misc/chatbubble.spr");
-	precache_model ("models/misc/teambubble.spr");
-	if (cvar("g_runematch"))
-	{
-		precache_model ("models/runematch/curse.mdl");
-		precache_model ("models/runematch/rune.mdl");
-	}
-
-	// Precache all player models if desired
-	if (cvar("sv_precacheplayermodels"))
-	{
-		globhandle = search_begin("models/player/*.zym", TRUE, FALSE);
-		n = search_getsize(globhandle);
-		for(i = 0; i < n; ++i)
-		{
-			//print(search_getfilename(globhandle, i), "\n");
-			precache_model(search_getfilename(globhandle, i));
-		}
-		search_end(globhandle);
-		//precache_model("models/player/carni.zym");
-		//precache_model("models/player/crash.zym");
-		//precache_model("models/player/grunt.zym");
-		//precache_model("models/player/headhunter.zym");
-		//precache_model("models/player/insurrectionist.zym");
-		//precache_model("models/player/jeandarc.zym");
-		//precache_model("models/player/lurk.zym");
-		//precache_model("models/player/lycanthrope.zym");
-		//precache_model("models/player/marine.zym");
-		//precache_model("models/player/nexus.zym");
-		//precache_model("models/player/pyria.zym");
-		//precache_model("models/player/shock.zym");
-		//precache_model("models/player/skadi.zym");
-		//precache_model("models/player/specop.zym");
-		//precache_model("models/player/visitant.zym");
-	}
-
-	if (cvar("g_footsteps"))
-	{
-		precache_sound ("misc/footstep01.wav");
-		precache_sound ("misc/footstep02.wav");
-		precache_sound ("misc/footstep03.wav");
-		precache_sound ("misc/footstep04.wav");
-		precache_sound ("misc/footstep05.wav");
-		precache_sound ("misc/footstep06.wav");
-	}
-
-	// gore and miscellaneous sounds
-	//precache_sound ("misc/h2ohit.wav");
-	precache_model ("models/gibs/bloodyskull.md3");
-	precache_model ("models/gibs/chunk.mdl");
-	precache_model ("models/gibs/eye.md3");
-	precache_model ("models/gibs/gib1.md3");
-	precache_model ("models/gibs/gib1.mdl");
-	precache_model ("models/gibs/gib2.mdl");
-	precache_model ("models/gibs/gib3.mdl");
-	precache_model ("models/gibs/gib5.md3");
-	precache_model ("models/hook.md3");
-	precache_sound ("misc/armorimpact.wav");
-	precache_sound ("misc/bodyimpact1.wav");
-	precache_sound ("misc/bodyimpact2.wav");
-	precache_sound ("misc/gib.wav");
-	precache_sound ("misc/gib_splat01.wav");
-	precache_sound ("misc/gib_splat02.wav");
-	precache_sound ("misc/gib_splat03.wav");
-	precache_sound ("misc/gib_splat04.wav");
-	precache_sound ("misc/hit.wav");
-	precache_sound ("misc/hitground1.wav");
-	precache_sound ("misc/hitground2.wav");
-	precache_sound ("misc/hitground3.wav");
-	precache_sound ("misc/hitground4.wav");
-	precache_sound ("misc/null.wav");
-	precache_sound ("misc/spawn.wav");
-	precache_sound ("misc/talk.wav");
-	precache_sound ("misc/teleport.wav");
-	precache_sound ("player/lava.wav");
-	precache_sound ("player/slime.wav");
-
-	// announcer sounds - male
-	//precache_sound ("announcer/male/electrobitch.wav");
-	precache_sound ("announcer/male/03kills.wav");
-	precache_sound ("announcer/male/05kills.wav");
-	precache_sound ("announcer/male/10kills.wav");
-	precache_sound ("announcer/male/15kills.wav");
-	precache_sound ("announcer/male/20kills.wav");
-	precache_sound ("announcer/male/25kills.wav");
-	precache_sound ("announcer/male/30kills.wav");
-	precache_sound ("announcer/male/botlike.wav");
-	precache_sound ("announcer/male/yoda.wav");
-
-	// announcer sounds - robotic
-	precache_sound ("announcer/robotic/1fragleft.wav");
-	precache_sound ("announcer/robotic/1minuteremains.wav");
-	precache_sound ("announcer/robotic/2fragsleft.wav");
-	precache_sound ("announcer/robotic/3fragsleft.wav");
-	if (cvar("g_minstagib"))
-	{
-		precache_sound ("announcer/robotic/lastsecond.wav");
-		precache_sound ("announcer/robotic/narrowly.wav");
-		precache_sound ("announcer/robotic/1.wav");
-		precache_sound ("announcer/robotic/2.wav");
-		precache_sound ("announcer/robotic/3.wav");
-		precache_sound ("announcer/robotic/4.wav");
-		precache_sound ("announcer/robotic/5.wav");
-		precache_sound ("announcer/robotic/6.wav");
-		precache_sound ("announcer/robotic/7.wav");
-		precache_sound ("announcer/robotic/8.wav");
-		precache_sound ("announcer/robotic/9.wav");
-		precache_sound ("announcer/robotic/10.wav");
-	}
-
-	// common weapon precaches
-	precache_sound ("weapons/weapon_switch.wav");
-	precache_sound ("weapons/weaponpickup.wav");
-	if (cvar("g_grappling_hook"))
-	{
-		precache_sound ("weapons/hook_fire.wav"); // hook
-		precache_sound ("weapons/hook_impact.wav"); // hook
-	}
-
-	if (cvar("sv_precacheweapons") || cvar("g_nixnex"))
-	{
-		//precache weapon models/sounds
-		local float wep;
-		wep = WEP_FIRST;
-		while (wep <= WEP_LAST)
-		{
-			weapon_action(wep, WR_PRECACHE);
-			wep = wep + 1;
-		}
-	}
-
-	// plays music for the level if there is any
-	if (self.noise)
-	{
-		precache_sound (self.noise);
-		ambientsound ('0 0 0', self.noise, 1.00, ATTN_NONE);
-	}
-
 	// 0 normal
 	lightstyle(0, "m");
 
@@ -298,10 +155,12 @@
 		CampaignPreInit();
 
 	InitGameplayMode();
+	readlevelcvars();
+	precache();
 
 	WaypointSprite_Init();
 
-	//if (cvar("g_domination"))
+	//if (g_domination)
 	//	dom_init();
 
 	local entity head;
@@ -361,8 +220,6 @@
 
 	fteqcc_testbugs();
 
-	readlevelcvars();
-
 	Ban_LoadBans();
 
 #ifdef MAPINFO
@@ -1419,7 +1276,7 @@
 	else
 		ClearWinners();
 
-	if (!cvar("g_runematch"))
+	if (!g_runematch)
 		if (checkrules_leaderfrags != checkrules_oldleaderfrags)
 		{
 			if (checkrules_leaderfrags == fraglimit - 1)
@@ -1462,7 +1319,7 @@
 			AddWinners(team, COLOR_TEAM4);
 	}
 
-	if(!cvar("g_runematch") && !cvar("g_domination"))
+	if(!g_runematch && !g_domination)
 		if(tdm_max_score != tdm_old_score)
 		{
 			if(tdm_max_score == fraglimit - 1)
@@ -1739,7 +1596,7 @@
 	{
 		if(teams_matter)
 		{
-			if(g_tdm || cvar("g_runematch") || g_ctf || cvar("g_domination") || g_keyhunt)
+			if(g_tdm || g_runematch || g_ctf || g_domination || g_keyhunt)
 				status = WinningCondition_MaxTeamSum(fraglimit);
 			//else if()
 			//	status = WinningCondition_MaxTeamMax(fraglimit);

Modified: branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/havocbot_roles.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -711,7 +711,7 @@
 	self.bot_strategytime = -1;
 	if (g_ctf)
 		havocbot_chooserole_ctf();
-	else if (cvar("g_domination"))
+	else if (g_domination)
 		havocbot_chooserole_dom();
 	else if (g_keyhunt)
 		havocbot_chooserole_kh();

Modified: branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -1,4 +1,3 @@
-string STR_ITEM_KH_KEY = "item_kh_key";
 #define FOR_EACH_KH_KEY(v) for(v = world; (v = find(v, classname, STR_ITEM_KH_KEY)); )
 
 // #define KH_PLAYER_USE_ATTACHMENT
@@ -22,8 +21,6 @@
 vector KH_KEY_MAX = '10 10 3';
 float KH_KEY_BRIGHTNESS = 2;
 
-typedef void(void) kh_Think_t;
-var kh_Think_t kh_Controller_Thinkfunc;
 string kh_Controller_Waitmsg;
 
 float kh_Team_ByID(float t)

Modified: branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh	2007-12-20 11:07:30 UTC (rev 3038)
@@ -24,3 +24,9 @@
 void kh_setstatus();
 float kh_HandleFrags(entity attacker, entity targ, float f);
 float kh_Key_AllOwnedByWhichTeam();
+
+#define STR_ITEM_KH_KEY "item_kh_key"
+typedef void(void) kh_Think_t;
+var kh_Think_t kh_Controller_Thinkfunc;
+void kh_Controller_SetThink(float t, string msg, kh_Think_t func)
+void kh_Key_Remove(entity key)

Modified: branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -687,6 +687,7 @@
 
 void readlevelcvars(void)
 {
+	sv_cheats = cvar("sv_cheats");
 	g_cloaked = cvar("g_cloaked");
 	g_footsteps = cvar("g_footsteps");
 	g_grappling_hook = cvar("g_grappling_hook");
@@ -873,3 +874,155 @@
 			play2(head, filename);
 	}
 }
+
+void precache_all_models(string pattern)
+{
+	float globhandle, i, n;
+
+	globhandle = search_begin(pattern, TRUE, FALSE);
+	n = search_getsize(globhandle);
+	for(i = 0; i < n; ++i)
+	{
+		//print(search_getfilename(globhandle, i), "\n");
+		precache_model(search_getfilename(globhandle, i));
+	}
+	search_end(globhandle);
+}
+
+void precache()
+{
+	// gamemode related things
+	precache_model ("models/misc/chatbubble.spr");
+	precache_model ("models/misc/teambubble.spr");
+	if (g_runematch)
+	{
+		precache_model ("models/runematch/curse.mdl");
+		precache_model ("models/runematch/rune.mdl");
+	}
+
+	// Precache all player models if desired
+	if (cvar("sv_precacheplayermodels"))
+	{
+		precache_all_models("models/player/*.zym");
+		precache_all_models("models/player/*.dpm");
+		precache_all_models("models/player/*.md3");
+		precache_all_models("models/player/*.psk");
+		//precache_model("models/player/carni.zym");
+		//precache_model("models/player/crash.zym");
+		//precache_model("models/player/grunt.zym");
+		//precache_model("models/player/headhunter.zym");
+		//precache_model("models/player/insurrectionist.zym");
+		//precache_model("models/player/jeandarc.zym");
+		//precache_model("models/player/lurk.zym");
+		//precache_model("models/player/lycanthrope.zym");
+		//precache_model("models/player/marine.zym");
+		//precache_model("models/player/nexus.zym");
+		//precache_model("models/player/pyria.zym");
+		//precache_model("models/player/shock.zym");
+		//precache_model("models/player/skadi.zym");
+		//precache_model("models/player/specop.zym");
+		//precache_model("models/player/visitant.zym");
+	}
+
+	if (g_footsteps)
+	{
+		precache_sound ("misc/footstep01.wav");
+		precache_sound ("misc/footstep02.wav");
+		precache_sound ("misc/footstep03.wav");
+		precache_sound ("misc/footstep04.wav");
+		precache_sound ("misc/footstep05.wav");
+		precache_sound ("misc/footstep06.wav");
+	}
+
+	// gore and miscellaneous sounds
+	//precache_sound ("misc/h2ohit.wav");
+	precache_model ("models/gibs/bloodyskull.md3");
+	precache_model ("models/gibs/chunk.mdl");
+	precache_model ("models/gibs/eye.md3");
+	precache_model ("models/gibs/gib1.md3");
+	precache_model ("models/gibs/gib1.mdl");
+	precache_model ("models/gibs/gib2.mdl");
+	precache_model ("models/gibs/gib3.mdl");
+	precache_model ("models/gibs/gib5.md3");
+	precache_model ("models/hook.md3");
+	precache_sound ("misc/armorimpact.wav");
+	precache_sound ("misc/bodyimpact1.wav");
+	precache_sound ("misc/bodyimpact2.wav");
+	precache_sound ("misc/gib.wav");
+	precache_sound ("misc/gib_splat01.wav");
+	precache_sound ("misc/gib_splat02.wav");
+	precache_sound ("misc/gib_splat03.wav");
+	precache_sound ("misc/gib_splat04.wav");
+	precache_sound ("misc/hit.wav");
+	precache_sound ("misc/hitground1.wav");
+	precache_sound ("misc/hitground2.wav");
+	precache_sound ("misc/hitground3.wav");
+	precache_sound ("misc/hitground4.wav");
+	precache_sound ("misc/null.wav");
+	precache_sound ("misc/spawn.wav");
+	precache_sound ("misc/talk.wav");
+	precache_sound ("misc/teleport.wav");
+	precache_sound ("player/lava.wav");
+	precache_sound ("player/slime.wav");
+
+	// announcer sounds - male
+	//precache_sound ("announcer/male/electrobitch.wav");
+	precache_sound ("announcer/male/03kills.wav");
+	precache_sound ("announcer/male/05kills.wav");
+	precache_sound ("announcer/male/10kills.wav");
+	precache_sound ("announcer/male/15kills.wav");
+	precache_sound ("announcer/male/20kills.wav");
+	precache_sound ("announcer/male/25kills.wav");
+	precache_sound ("announcer/male/30kills.wav");
+	precache_sound ("announcer/male/botlike.wav");
+	precache_sound ("announcer/male/yoda.wav");
+
+	// announcer sounds - robotic
+	precache_sound ("announcer/robotic/1fragleft.wav");
+	precache_sound ("announcer/robotic/1minuteremains.wav");
+	precache_sound ("announcer/robotic/2fragsleft.wav");
+	precache_sound ("announcer/robotic/3fragsleft.wav");
+	if (g_minstagib)
+	{
+		precache_sound ("announcer/robotic/lastsecond.wav");
+		precache_sound ("announcer/robotic/narrowly.wav");
+		precache_sound ("announcer/robotic/1.wav");
+		precache_sound ("announcer/robotic/2.wav");
+		precache_sound ("announcer/robotic/3.wav");
+		precache_sound ("announcer/robotic/4.wav");
+		precache_sound ("announcer/robotic/5.wav");
+		precache_sound ("announcer/robotic/6.wav");
+		precache_sound ("announcer/robotic/7.wav");
+		precache_sound ("announcer/robotic/8.wav");
+		precache_sound ("announcer/robotic/9.wav");
+		precache_sound ("announcer/robotic/10.wav");
+	}
+
+	// common weapon precaches
+	precache_sound ("weapons/weapon_switch.wav");
+	precache_sound ("weapons/weaponpickup.wav");
+	if (cvar("g_grappling_hook"))
+	{
+		precache_sound ("weapons/hook_fire.wav"); // hook
+		precache_sound ("weapons/hook_impact.wav"); // hook
+	}
+
+	if (cvar("sv_precacheweapons") || g_nixnex)
+	{
+		//precache weapon models/sounds
+		local float wep;
+		wep = WEP_FIRST;
+		while (wep <= WEP_LAST)
+		{
+			weapon_action(wep, WR_PRECACHE);
+			wep = wep + 1;
+		}
+	}
+
+	// plays music for the level if there is any
+	if (self.noise)
+	{
+		precache_sound (self.noise);
+		ambientsound ('0 0 0', self.noise, 1.00, ATTN_NONE);
+	}
+}

Modified: branches/nexuiz-2.0/data/qcsrc/server/runematch.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/runematch.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/runematch.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -33,7 +33,7 @@
 
 void runematch_spawn_point()
 {
-	if(!cvar("g_runematch"))
+	if(!g_runematch)
 	{
 		remove(self);
 		return;
@@ -151,7 +151,7 @@
 	vector ang;
 	entity rune;
 
-	if(self.owner.classname != "player")
+	if(self.owner.classname != "player" || time < restart_countdown)
 	{
 		rune_respawn();
 		return;
@@ -181,7 +181,7 @@
 
 void rune_touch()
 {
-	if(other.classname != "player" || other.health < 2)
+	if(other.classname != "player" || other.health < 1)
 		return;
 	if(self.wait > time)
 		return; // "notouch" time isn't finished
@@ -619,7 +619,7 @@
 
 void runematch_init()
 {
-	if(!cvar("g_runematch"))
+	if(!g_runematch)
 		return;
 
 	entity e;
@@ -636,7 +636,7 @@
 {
 	entity rune;
 
-	if(!cvar("g_runematch") || !cvar("g_runematch_pointamt"))
+	if(!g_runematch || !cvar("g_runematch_pointamt"))
 		return;
 
 	if(gameover)

Modified: branches/nexuiz-2.0/data/qcsrc/server/t_jumppads.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_jumppads.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_jumppads.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -118,20 +118,13 @@
 	if (other.deadflag && other.classname == "player")
 		return;
 
-	if (!self.target)
-	{
-		other.velocity = self.movedir;
-		other.flags = other.flags - (other.flags & FL_ONGROUND);
-		return;
-	}
-
 	if (other.classname == "player")
 	{
 		if(self.pushltime < time)  // prevent "snorring" sound when a player hits the jumppad more than once
 		{
 			// flash when activated
 			te_smallflash(other.origin);
-			sound (other, CHAN_ITEM, "misc/jumppad.wav", 1, ATTN_NORM);
+			sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
 			self.pushltime = time + 0.2;
 		}
 		if(clienttype(other) == CLIENTTYPE_REAL)
@@ -152,7 +145,8 @@
 			other.jumppadcount = TRUE;
 	}
 
-	self.movedir = trigger_push_calculatevelocity(other.origin, self.enemy, self.height);
+	if(self.target)
+		self.movedir = trigger_push_calculatevelocity(other.origin, self.enemy, self.height);
 
 	other.flags = other.flags - (other.flags & FL_ONGROUND);
 	// reset tracking of oldvelocity for impact damage (sudden velocity changes)
@@ -242,8 +236,9 @@
 		self.speed = 1000;
 	self.movedir = self.movedir * self.speed * 10;
 
-	if (self.target)
-		precache_sound ("misc/jumppad.wav");
+	if not(self.noise)
+		self.noise = "misc/jumppad.wav";
+	precache_sound (self.noise);
 
 	// this must be called to spawn the teleport waypoints for bots
 	self.think = trigger_push_findtarget;

Modified: branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -280,38 +280,18 @@
 		fraglimit_override = cvar("fraglimit_override");
 	}*/
 
-	// enforce the server's universal frag/time limits
-	if(!cvar("g_campaign"))
-	{
-		if(fraglimit_override >= 0)
-			cvar_set("fraglimit", ftos(fraglimit_override));
-		if(timelimit_override >= 0)
-			cvar_set("timelimit", ftos(timelimit_override));
-	}
-
-	if (game == GAME_DOMINATION)//cvar("g_domination"))
-		dom_init();
-	else if (game == GAME_CTF)//cvar("g_ctf"))
-		ctf_init();
-	else if (game == GAME_RUNEMATCH)//cvar("g_runematch"))
-		runematch_init();
-	else if (game == GAME_TEAM_DEATHMATCH)//cvar("g_runematch"))
-		tdm_init();
-	else if (game == GAME_KEYHUNT)//cvar("g_keyhunt"))
-		kh_init();
-
 	// those mutators rule each other out
-	if(g_minstagib)
+	if(cvar("g_minstagib"))
 	{
 		cvar_set("g_instagib", "0");
 		cvar_set("g_rocketarena", "0");
 	}
-	if(g_instagib)
+	if(cvar("g_instagib"))
 	{
 		cvar_set("g_minstagib", "0");
 		cvar_set("g_rocketarena", "0");
 	}
-	if(g_rocketarena)
+	if(cvar("g_rocketarena"))
 	{
 		cvar_set("g_instagib", "0");
 		cvar_set("g_minstagib", "0");
@@ -326,10 +306,31 @@
 	g_ctf = cvar("g_ctf");
 	g_lms = cvar("g_lms");
 	g_tdm = cvar("g_tdm");
+	g_runematch = cvar("g_runematch");
 	g_keyhunt = cvar("g_keyhunt");
 	g_onslaught = cvar("g_onslaught");
 	g_assault = cvar("g_assault");
 	g_arena = cvar("g_arena");
+
+	// enforce the server's universal frag/time limits
+	if(!cvar("g_campaign"))
+	{
+		if(fraglimit_override >= 0)
+			cvar_set("fraglimit", ftos(fraglimit_override));
+		if(timelimit_override >= 0)
+			cvar_set("timelimit", ftos(timelimit_override));
+	}
+
+	if (game == GAME_DOMINATION)//cvar("g_domination"))
+		dom_init();
+	else if (game == GAME_CTF)//cvar("g_ctf"))
+		ctf_init();
+	else if (game == GAME_RUNEMATCH)//cvar("g_runematch"))
+		runematch_init();
+	else if (game == GAME_TEAM_DEATHMATCH)//cvar("g_runematch"))
+		tdm_init();
+	else if (game == GAME_KEYHUNT)//cvar("g_keyhunt"))
+		kh_init();
 }
 
 string GetClientVersionMessage(float v) {
@@ -423,6 +424,9 @@
 	if(modifications != "")
 		s = strcat(s, "^8\nactive modifications: ^3", modifications, "^8\n");
 
+	if(time < restart_countdown)
+		s = strcat(s, "\n^1Game starts in ", ftos(ceil(restart_countdown-time)), " seconds^7");
+
 	if((self.classname == "observer" || self.classname == "spectator") && self.version == cvar("gameversion")) {
 		if(!g_arena)
 			s = strcat(s,"^7\n\n\npress jump to play\npress attack to spectate other players\n\n");

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_shotgun.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_shotgun.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_shotgun.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -6,6 +6,7 @@
 	float	d;
 	float	f;
 	float	spread;
+	local entity flash;
 
 	bullets = cvar("g_balance_shotgun_primary_bullets");
 	d = cvar("g_balance_shotgun_primary_damage");
@@ -24,6 +25,22 @@
 	// casing code
 	if (cvar("g_casings") >= 1)
 		SpawnCasing (w_shotorg, ((random () * 50 + 50) * v_right) - ((random () * 25 + 25) * v_forward) - ((random () * 5 - 30) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 1);
+
+	// muzzle flash for 1st person view
+	flash = spawn();
+	setorigin(flash, '53 5 0');
+	setmodel(flash, "models/uziflash.md3"); // precision set below
+	setattachment(flash, self.weaponentity, "bone01");
+	flash.owner = self;
+	flash.viewmodelforclient = self;
+	flash.customizeentityforclient = CL_Weaponentity_CustomizeEntityForClient;
+	flash.scale = 1.2;
+	flash.think = SUB_Remove;
+	flash.nextthink = time + 0.06;
+	flash.angles_z = flash.v_angle_z + random() * 180;
+	flash.alpha = 1;
+	flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
+
 }
 
 void W_Shotgun_Attack2 (void)

Modified: branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/qcsrc/server/w_uzi.qc	2007-12-20 11:07:30 UTC (rev 3038)
@@ -1,3 +1,16 @@
+// leilei's fancy muzzleflash stuff
+void() W_Uzi_Flash_Go;
+void() W_Uzi_Flash_Go {
+	if (self.frame > 10){
+		SUB_Remove();
+		return;
+	}
+	self.frame = self.frame + 2;
+	self.alpha = self.alpha - 0.2;
+	self.think = W_Uzi_Flash_Go;
+	self.nextthink = time + 0.02;
+};
+
 .float uzi_bulletcounter;
 void W_Uzi_Attack (void)
 {
@@ -34,18 +47,23 @@
 	flash.viewmodelforclient = self;
 	flash.customizeentityforclient = CL_Weaponentity_CustomizeEntityForClient;
 	flash.scale = 1.2;
-	SUB_SetFade(flash, time, 0.2);
+	//SUB_SetFade(flash, time + 0.06, 0);
+	flash.think = W_Uzi_Flash_Go;
+	flash.nextthink = time + 0.02;
+	flash.frame = 2;
 
 	// muzzle flash for 3rd person view
 	flash2 = spawn();
 	setorigin(flash2, '43 1 8');
 	setmodel(flash2, "models/uziflash.md3"); // precision set below
 	setattachment(flash2, self.exteriorweaponentity, "");
-	SUB_SetFade(flash2, time, 0.2);
-
+	//SUB_SetFade(flash2, time + 0.06, 0);
+	flash2.think = W_Uzi_Flash_Go;
+	flash2.nextthink = time + 0.02;
+	flash2.frame = 2;
 	// common properties
 	flash.angles_z = flash2.angles_z = flash.v_angle_z + random() * 180;
-	flash.alpha = flash2.alpha = 0.5;
+	flash.alpha = flash2.alpha = 1;
 	flash.effects = flash2.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
 
 	// casing code

Added: branches/nexuiz-2.0/data/scripts/default_project.proj
===================================================================
--- branches/nexuiz-2.0/data/scripts/default_project.proj	                        (rev 0)
+++ branches/nexuiz-2.0/data/scripts/default_project.proj	2007-12-20 11:07:30 UTC (rev 3038)
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<!DOCTYPE project SYSTEM "dtds/project.dtd">
+<!--
+project template
+the $* strings will be expanded following these rules:
+$TEMPLATEapppath: path to the Radiant .. C:\Program Files\Gtkradiant
+$TEMPLATEenginepath: path to the engine .. C:\quake3\ C:\Program Files\Quake III Arena\ /usr/local/games/quake3/
+$TEMPLATEtoolspath: path to the tools directory (enginepath)radiant
+  (NOTE: on win32 tools directory is usually where the editor is .. but it's not true on linux)
+$TEMPLATEuserhomepath: on linux, the directory with write permissions for saving maps etc.
+  on win32, == $TEMPLATEenginepath
+$TEMPLATEbasedir: base game dir
+
+Note : Default project settings are for single player... this can be changed throught the projects select in the File Menu
+
+-->
+<project>
+<key name="version" value="2"/>
+<key name="basepath" value="$TEMPLATEenginepath$TEMPLATEbasedir/"/>
+<key name="rshcmd" value=""/>
+<key name="remotebasepath" value="$TEMPLATEenginepath$TEMPLATEbasedir/"/>
+<key name="entitypath" value="$TEMPLATEtoolspath$TEMPLATEbasedir/scripts/entities.def"/>
+<key name="texturepath" value="$TEMPLATEenginepath$TEMPLATEbasedir/textures/"/>
+<key name="autosave" value="$TEMPLATEuserhomepath$TEMPLATEbasedir/maps/autosave.map"/>
+<key name="mapspath" value="$TEMPLATEuserhomepath$TEMPLATEbasedir/maps/"/>
+
+<key name="bsp_Q3Map2: (single) BSP -meta" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -meta $"/>
+
+<key name="bsp_Q3Map2: (single) -vis" value="! &quot;$TEMPLATEapppathq3map2&quot; # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -vis $" />
+
+<key name="bsp_Q3Map2: (single test) -vis -fast" value="! &quot;$TEMPLATEapppathq3map2&quot; # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -vis -fast $" />
+
+<key name="bsp_Q3Map2: (single test) -light -faster" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -faster $" />
+
+<key name="bsp_Q3Map2: (single test) -light -fast" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -fast $" />
+
+<key name="bsp_Q3Map2: (single) -light -super 2" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -super 2 $" />
+
+<key name="bsp_Q3Map2: (single) -light -fast -super 2" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -fast -super 2 $" />
+
+<key name="bsp_Q3Map2: (single) -light -fast -super 2 -filter" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -fast -super 2 -filter $" />
+
+<key name="bsp_Q3Map2: (single) -light -super 2 -filter -bounce 8" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -super 2 -filter -bounce 8 $" />
+
+<key name="bsp_Q3Map2: (single) -light -super 2 -filter -bounce 1" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -super 2 -filter -bounce 1 $" />
+
+<key name="bsp_Q3Map2: (single) -light -fast -super 2 -filter -bounce 8" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -fast -super 2 -filter -bounce 8 $" />
+
+<key name="bsp_Q3Map2: (test) BSP -meta, -vis, -light -fast -filter" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -meta $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -vis -saveprt $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -fast -filter $" />
+
+<key name="bsp_Q3Map2: (test) BSP -meta, -vis -fast, -light -fast -super 2 -filter" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -meta $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -vis -saveprt -fast $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -fast -super 2 -filter $" />
+
+<key name="bsp_Q3Map2: (final) BSP -meta, -vis, -light -fast -filter -super 2" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -meta $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -vis -saveprt $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -fast -filter -super 2 $" />
+
+<key name="bsp_Q3Map2: (final) BSP -meta, -vis, -light -fast -filter -super 2" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -meta $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -vis -saveprt $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -fast -filter -super 2 $" />
+
+<key name="bsp_Q3Map2: (final) BSP -meta, -vis, -light -fast -filter -super 2 -bounce 8" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -meta $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -vis -saveprt $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -fast -super 2 -filter -bounce 8 $" />
+
+<key name="bsp_Q3Map2: (simulate old style -light -extra) BSP -meta, -vis, -light -super 2" value="! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -meta $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -vis -saveprt $ &amp;&amp; ! &quot;$TEMPLATEapppathq3map2&quot; -v # -game quake3 -fs_basepath &quot;$TEMPLATEenginepath&quot; -light -super 2 $" />
+
+<key name="bsp_AAS: compile AAS" value="! &quot;$TEMPLATEapppathbspc&quot; -optimize -threads 2 -forcesidesvisible -bsp2aas $" />
+</project>

Modified: branches/nexuiz-2.0/data/sound/cdtracks/thunder.ogg
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/sound/cdtracks/track001.ogg
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/sound/cdtracks/track002.ogg
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/sound/cdtracks/track003.ogg
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/sound/cdtracks/track004.ogg
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/sound/cdtracks/track005.ogg
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/sound/cdtracks/track006.ogg
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/sound/cdtracks/track007.ogg
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/sound/cdtracks/track008.ogg
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/sound/cdtracks/track009.ogg
===================================================================
(Binary files differ)

Modified: branches/nexuiz-2.0/data/sound/weapons/uzi_fire.ogg
===================================================================
(Binary files differ)

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


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

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


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

Modified: branches/nexuiz-2.0/data/weapons.cfg
===================================================================
--- branches/nexuiz-2.0/data/weapons.cfg	2007-12-18 20:24:14 UTC (rev 3037)
+++ branches/nexuiz-2.0/data/weapons.cfg	2007-12-20 11:07:30 UTC (rev 3038)
@@ -102,7 +102,7 @@
 set g_balance_electro_primary_speed 2000
 set g_balance_electro_primary_lifetime 30
 set g_balance_electro_primary_refire 0.6
-set g_balance_electro_primary_animtime 0.05
+set g_balance_electro_primary_animtime 0.3
 set g_balance_electro_primary_ammo 2
 set g_balance_electro_secondary_damage 60
 set g_balance_electro_secondary_edgedamage 0
@@ -112,7 +112,7 @@
 set g_balance_electro_secondary_speed_up 200
 set g_balance_electro_secondary_lifetime 5
 set g_balance_electro_secondary_refire 0.3
-set g_balance_electro_secondary_animtime 0.05
+set g_balance_electro_secondary_animtime 0.3
 set g_balance_electro_secondary_ammo 2
 set g_balance_electro_combo_damage 70
 set g_balance_electro_combo_edgedamage 0
@@ -128,7 +128,7 @@
 set g_balance_crylink_primary_shots 4
 set g_balance_crylink_primary_lifetime 30
 set g_balance_crylink_primary_refire 0.25
-set g_balance_crylink_primary_animtime 0.15
+set g_balance_crylink_primary_animtime 0.3
 set g_balance_crylink_primary_ammo 1
 set g_balance_crylink_secondary_damage 20
 set g_balance_crylink_secondary_edgedamage 0
@@ -139,7 +139,7 @@
 set g_balance_crylink_secondary_shots 7
 set g_balance_crylink_secondary_lifetime 30
 set g_balance_crylink_secondary_refire 0.5
-set g_balance_crylink_secondary_animtime 0.15
+set g_balance_crylink_secondary_animtime 0.3
 set g_balance_crylink_secondary_ammo 3
 
 set g_balance_nex_damage 140




More information about the nexuiz-commits mailing list