[nexuiz-commits] r7131 - in trunk/data/qcsrc: client common menu/nexuiz server server/monsters server/pathlib server/tturrets/include server/tturrets/system server/tturrets/units server/vehicles

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Tue Jun 30 10:36:37 EDT 2009


Author: div0
Date: 2009-06-30 10:36:36 -0400 (Tue, 30 Jun 2009)
New Revision: 7131

Modified:
   trunk/data/qcsrc/client/Defs.qc
   trunk/data/qcsrc/client/Main.qc
   trunk/data/qcsrc/client/View.qc
   trunk/data/qcsrc/client/bgmscript.qc
   trunk/data/qcsrc/client/bgmscript.qh
   trunk/data/qcsrc/client/casings.qc
   trunk/data/qcsrc/client/csqc_builtins.qc
   trunk/data/qcsrc/client/csqc_constants.qc
   trunk/data/qcsrc/client/ctf.qc
   trunk/data/qcsrc/client/damage.qc
   trunk/data/qcsrc/client/effects.qc
   trunk/data/qcsrc/client/gibs.qc
   trunk/data/qcsrc/client/hook.qc
   trunk/data/qcsrc/client/interpolate.qc
   trunk/data/qcsrc/client/interpolate.qh
   trunk/data/qcsrc/client/laser.qc
   trunk/data/qcsrc/client/main.qh
   trunk/data/qcsrc/client/mapvoting.qc
   trunk/data/qcsrc/client/movetypes.qc
   trunk/data/qcsrc/client/movetypes.qh
   trunk/data/qcsrc/client/particles.qc
   trunk/data/qcsrc/client/prandom.qc
   trunk/data/qcsrc/client/prandom.qh
   trunk/data/qcsrc/client/pre.qh
   trunk/data/qcsrc/client/projectile.qc
   trunk/data/qcsrc/client/rubble.qc
   trunk/data/qcsrc/client/sortlist.qc
   trunk/data/qcsrc/client/teamplay.qc
   trunk/data/qcsrc/client/teamradar.qc
   trunk/data/qcsrc/client/teamradar.qh
   trunk/data/qcsrc/client/wall.qc
   trunk/data/qcsrc/client/waypointsprites.qc
   trunk/data/qcsrc/client/waypointsprites.qh
   trunk/data/qcsrc/common/items.qc
   trunk/data/qcsrc/common/items.qh
   trunk/data/qcsrc/common/util-pre.qh
   trunk/data/qcsrc/menu/nexuiz/bigbutton.c
   trunk/data/qcsrc/menu/nexuiz/bigcommandbutton.c
   trunk/data/qcsrc/menu/nexuiz/colorpicker.c
   trunk/data/qcsrc/menu/nexuiz/cvarlist.c
   trunk/data/qcsrc/menu/nexuiz/demolist.c
   trunk/data/qcsrc/menu/nexuiz/dialog_multiplayer_create_advanced.c
   trunk/data/qcsrc/menu/nexuiz/dialog_multiplayer_demo.c
   trunk/data/qcsrc/menu/nexuiz/dialog_multiplayer_join_serverinfo.c
   trunk/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup_radar.c
   trunk/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup_weapons.c
   trunk/data/qcsrc/menu/nexuiz/dialog_settings_audio.c
   trunk/data/qcsrc/menu/nexuiz/dialog_settings_misc_cvars.c
   trunk/data/qcsrc/menu/nexuiz/dialog_settings_network.c
   trunk/data/qcsrc/menu/nexuiz/modbutton.c
   trunk/data/qcsrc/menu/nexuiz/playerlist.c
   trunk/data/qcsrc/menu/nexuiz/skinlist.c
   trunk/data/qcsrc/menu/nexuiz/weaponslist.c
   trunk/data/qcsrc/server/bots_scripting.qc
   trunk/data/qcsrc/server/csqceffects.qc
   trunk/data/qcsrc/server/csqcprojectile.qc
   trunk/data/qcsrc/server/csqcprojectile.qh
   trunk/data/qcsrc/server/ent_cs.qc
   trunk/data/qcsrc/server/func_breakable.qc
   trunk/data/qcsrc/server/g_hook.qh
   trunk/data/qcsrc/server/g_models.qc
   trunk/data/qcsrc/server/havocbot_ons.qc
   trunk/data/qcsrc/server/monsters/ai.qc
   trunk/data/qcsrc/server/monsters/defs.qc
   trunk/data/qcsrc/server/monsters/fight.qc
   trunk/data/qcsrc/server/monsters/m_monsters.qc
   trunk/data/qcsrc/server/monsters/mode_management.qc
   trunk/data/qcsrc/server/movelib.qc
   trunk/data/qcsrc/server/nexball.qc
   trunk/data/qcsrc/server/pathlib.qc
   trunk/data/qcsrc/server/pathlib/costs.qc
   trunk/data/qcsrc/server/pathlib/debug.qc
   trunk/data/qcsrc/server/pathlib/expandnode.qc
   trunk/data/qcsrc/server/pathlib/main.qc
   trunk/data/qcsrc/server/pathlib/movenode.qc
   trunk/data/qcsrc/server/pathlib/pathlib.qh
   trunk/data/qcsrc/server/pathlib/utility.qc
   trunk/data/qcsrc/server/portals.qc
   trunk/data/qcsrc/server/portals.qh
   trunk/data/qcsrc/server/post-builtins.qh
   trunk/data/qcsrc/server/pre-builtins.qh
   trunk/data/qcsrc/server/race.qc
   trunk/data/qcsrc/server/race.qh
   trunk/data/qcsrc/server/scores.qc
   trunk/data/qcsrc/server/scores.qh
   trunk/data/qcsrc/server/scores_rules.qc
   trunk/data/qcsrc/server/steerlib.qc
   trunk/data/qcsrc/server/target_spawn.qc
   trunk/data/qcsrc/server/tturrets/include/turrets.qh
   trunk/data/qcsrc/server/tturrets/include/turrets_early.qh
   trunk/data/qcsrc/server/tturrets/system/system_aimprocs.qc
   trunk/data/qcsrc/server/tturrets/system/system_main.qc
   trunk/data/qcsrc/server/tturrets/system/system_misc.qc
   trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc
   trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc
   trunk/data/qcsrc/server/tturrets/units/unit_common.qc
   trunk/data/qcsrc/server/tturrets/units/unit_ewheel.qc
   trunk/data/qcsrc/server/tturrets/units/unit_flac.qc
   trunk/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc
   trunk/data/qcsrc/server/tturrets/units/unit_hellion.qc
   trunk/data/qcsrc/server/tturrets/units/unit_hk.qc
   trunk/data/qcsrc/server/tturrets/units/unit_machinegun.qc
   trunk/data/qcsrc/server/tturrets/units/unit_mlrs.qc
   trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc
   trunk/data/qcsrc/server/tturrets/units/unit_plasma.qc
   trunk/data/qcsrc/server/tturrets/units/unit_targettrigger.qc
   trunk/data/qcsrc/server/tturrets/units/unit_tessla.qc
   trunk/data/qcsrc/server/tturrets/units/unit_walker.qc
   trunk/data/qcsrc/server/vehicles/vehicles.qh
   trunk/data/qcsrc/server/verbstack.qc
   trunk/data/qcsrc/server/vote.qc
   trunk/data/qcsrc/server/vote.qh
   trunk/data/qcsrc/server/w_campingrifle.qc
   trunk/data/qcsrc/server/w_hlac.qc
   trunk/data/qcsrc/server/w_hook.qc
   trunk/data/qcsrc/server/w_minstanex.qc
   trunk/data/qcsrc/server/w_porto.qc
   trunk/data/qcsrc/server/w_seeker.qc
   trunk/data/qcsrc/server/w_tuba.qc
Log:
eol-style only


Modified: trunk/data/qcsrc/client/Defs.qc
===================================================================
--- trunk/data/qcsrc/client/Defs.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/client/Defs.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,235 +1,235 @@
-#pragma flag off fastarrays // make dp behave with new fteqcc versions. remove when dp bug with fteqcc fastarrays is fixed
-
-
-//NOTE: THIS IS AN INTERFACE FILE. DO NOT EDIT.
-//MODIFYING THIS FILE CAN RESULT IN CRC ERRORS.
-//YOU HAVE BEEN WARNED.
-
-//feel free to look though. :)
-
-
-
-
-
-/*
-==============================================================================
-
-			SOURCE FOR GLOBALVARS_T C STRUCTURE
-
-==============================================================================
-*/
-
-//
-// system globals
-//
-entity		self;
-entity		other;
-entity		world;
-float		time;
-float		frametime;
-
-float 		player_localentnum;	//the entnum
-float 		player_localnum;	//the playernum
-float		maxclients;	//a constant filled in by the engine. gah, portability eh?
-
-float		clientcommandframe;	//player movement
-float		servercommandframe;	//clientframe echoed off the server
-
-string		mapname;
-
-//
-// global variables set by built in functions
-//
-vector		v_forward, v_up, v_right;	// set by makevectors()
-
-// set by traceline / tracebox
-float		trace_allsolid;
-float		trace_startsolid;
-float		trace_fraction;
-vector		trace_endpos;
-vector		trace_plane_normal;
-float		trace_plane_dist;
-entity		trace_ent;
-float		trace_inopen;
-float		trace_inwater;
-
-//
-// required prog functions
-//
-void()		CSQC_Init;
-void()		CSQC_Shutdown;
-float(float f, float t, float n)	CSQC_InputEvent;
-void(float w, float h)		CSQC_UpdateView;
-float(string s)	CSQC_ConsoleCommand;
-
-//these fields are read and set by the default player physics
-vector		pmove_org;
-vector		pmove_vel;
-vector		pmove_mins;
-vector		pmove_maxs;
-//retrieved from the current movement commands (read by player physics)
-float		input_timelength;
-vector		input_angles;
-vector		input_movevalues;	//forwards, right, up.
-float		input_buttons;		//attack, use, jump (default physics only uses jump)
-
-float		movevar_gravity;
-float		movevar_stopspeed;
-float		movevar_maxspeed;
-float		movevar_spectatormaxspeed;	//used by NOCLIP movetypes.
-float		movevar_accelerate;
-float		movevar_airaccelerate;
-float		movevar_wateraccelerate;
-float		movevar_friction;
-float		movevar_waterfriction;
-float		movevar_entgravity;	//the local player's gravity field. Is a multiple (1 is the normal value)
-
-//================================================
-void		end_sys_globals;		// flag for structure dumping
-//================================================
-
-/*
-==============================================================================
-
-			SOURCE FOR ENTVARS_T C STRUCTURE
-
-==============================================================================
-*/
-
-//
-// system fields (*** = do not set in prog code, maintained by C code)
-//
-.float		modelindex;		// *** model index in the precached list
-.vector		absmin, absmax;	// *** origin + mins / maxs
-
-.float		entnum;	// *** the ent number as on the server
-.float		drawmask;
-.void()		predraw;
-
-.float		movetype;
-.float		solid;
-
-.vector		origin;			// ***
-.vector		oldorigin;		// ***
-.vector		velocity;
-.vector		angles;
-.vector		avelocity;
-
-.string		classname;		// spawn function
-.string		model;
-.float		frame;
-.float		skin;
-.float		effects;
-
-.vector		mins, maxs;		// bounding box extents reletive to origin
-.vector		size;			// maxs - mins
-
-.void()		touch;
-.void()		use;
-.void()		think;
-.void()		blocked;		// for doors or plats, called when can't push other
-
-.float		nextthink;
-
-.entity		chain;
-
-.string		netname;
-
-.entity 	enemy;
-
-.float		flags;
-
-.float		colormap;
-
-.entity		owner;		// who launched a missile
-
-//================================================
-void		end_sys_fields;			// flag for structure dumping
-//================================================
-
-// Additional OPTIONAL Fields and Globals
-float		intermission;
-float		sb_showscores;
-float		sb_showaccuracy;
-float		sbar_currentammo;
-.string		message;
-.float renderflags;
-// float		coop;
-// float		deathmatch;
-
-// float		dmg_take;
-// float		dmg_save;
-// vector		dmg_origin;
-
-// Darkplaces Render Modifications
-#if 0
-.float alpha;
-.float renderflags;
-.vector colormod;
-.float scale;
-#endif
-
-// Basic variables
-.float enttype; // entity type sent from server
-.float sv_entnum; // entity number sent from server
-.float team;
-.float team_size;
-
-float vid_conwidth, vid_conheight;
-float binddb;
-
-// QUALIFYING
-float race_checkpoint;
-float race_time;
-float race_laptime;
-float race_checkpointtime;
-float race_previousbesttime;
-string race_previousbestname;
-float race_nextcheckpoint;
-float race_nextbesttime;
-string race_nextbestname;
-
-// RACE
-float race_mycheckpoint;
-float race_mycheckpointtime;
-float race_mycheckpointdelta;
-float race_mycheckpointlapsdelta;
-string race_mycheckpointenemy;
-float race_othercheckpoint;
-float race_othercheckpointtime;
-float race_othercheckpointdelta;
-float race_othercheckpointlapsdelta;
-string race_othercheckpointenemy;
-float sb_showscores_force;
-
-// Nexball
-float nb_pb_period;
-
-// Spectating
-float spectatee_status;
-
-// short mapname
-string shortmapname;
-
-//remaining maptime announcer sounds, true when sound was already played
-float announcer_1min;
-float announcer_5min;
-
-// database for misc stuff
-float tempdb;
-vector hook_shotorigin;
-
-#ifdef BLURTEST
-float blurtest_time0, blurtest_time1, blurtest_radius, blurtest_power;
-#endif
-
-float servertime, serverprevtime, serverdeltatime;
-
-float ticrate;
-
-.float damageforcescale;
-.void(float thisdmg, float hittype, vector org, vector thisforce) event_damage;
-
-// only for Porto
-float angles_held_status;
-vector angles_held;
+#pragma flag off fastarrays // make dp behave with new fteqcc versions. remove when dp bug with fteqcc fastarrays is fixed
+
+
+//NOTE: THIS IS AN INTERFACE FILE. DO NOT EDIT.
+//MODIFYING THIS FILE CAN RESULT IN CRC ERRORS.
+//YOU HAVE BEEN WARNED.
+
+//feel free to look though. :)
+
+
+
+
+
+/*
+==============================================================================
+
+			SOURCE FOR GLOBALVARS_T C STRUCTURE
+
+==============================================================================
+*/
+
+//
+// system globals
+//
+entity		self;
+entity		other;
+entity		world;
+float		time;
+float		frametime;
+
+float 		player_localentnum;	//the entnum
+float 		player_localnum;	//the playernum
+float		maxclients;	//a constant filled in by the engine. gah, portability eh?
+
+float		clientcommandframe;	//player movement
+float		servercommandframe;	//clientframe echoed off the server
+
+string		mapname;
+
+//
+// global variables set by built in functions
+//
+vector		v_forward, v_up, v_right;	// set by makevectors()
+
+// set by traceline / tracebox
+float		trace_allsolid;
+float		trace_startsolid;
+float		trace_fraction;
+vector		trace_endpos;
+vector		trace_plane_normal;
+float		trace_plane_dist;
+entity		trace_ent;
+float		trace_inopen;
+float		trace_inwater;
+
+//
+// required prog functions
+//
+void()		CSQC_Init;
+void()		CSQC_Shutdown;
+float(float f, float t, float n)	CSQC_InputEvent;
+void(float w, float h)		CSQC_UpdateView;
+float(string s)	CSQC_ConsoleCommand;
+
+//these fields are read and set by the default player physics
+vector		pmove_org;
+vector		pmove_vel;
+vector		pmove_mins;
+vector		pmove_maxs;
+//retrieved from the current movement commands (read by player physics)
+float		input_timelength;
+vector		input_angles;
+vector		input_movevalues;	//forwards, right, up.
+float		input_buttons;		//attack, use, jump (default physics only uses jump)
+
+float		movevar_gravity;
+float		movevar_stopspeed;
+float		movevar_maxspeed;
+float		movevar_spectatormaxspeed;	//used by NOCLIP movetypes.
+float		movevar_accelerate;
+float		movevar_airaccelerate;
+float		movevar_wateraccelerate;
+float		movevar_friction;
+float		movevar_waterfriction;
+float		movevar_entgravity;	//the local player's gravity field. Is a multiple (1 is the normal value)
+
+//================================================
+void		end_sys_globals;		// flag for structure dumping
+//================================================
+
+/*
+==============================================================================
+
+			SOURCE FOR ENTVARS_T C STRUCTURE
+
+==============================================================================
+*/
+
+//
+// system fields (*** = do not set in prog code, maintained by C code)
+//
+.float		modelindex;		// *** model index in the precached list
+.vector		absmin, absmax;	// *** origin + mins / maxs
+
+.float		entnum;	// *** the ent number as on the server
+.float		drawmask;
+.void()		predraw;
+
+.float		movetype;
+.float		solid;
+
+.vector		origin;			// ***
+.vector		oldorigin;		// ***
+.vector		velocity;
+.vector		angles;
+.vector		avelocity;
+
+.string		classname;		// spawn function
+.string		model;
+.float		frame;
+.float		skin;
+.float		effects;
+
+.vector		mins, maxs;		// bounding box extents reletive to origin
+.vector		size;			// maxs - mins
+
+.void()		touch;
+.void()		use;
+.void()		think;
+.void()		blocked;		// for doors or plats, called when can't push other
+
+.float		nextthink;
+
+.entity		chain;
+
+.string		netname;
+
+.entity 	enemy;
+
+.float		flags;
+
+.float		colormap;
+
+.entity		owner;		// who launched a missile
+
+//================================================
+void		end_sys_fields;			// flag for structure dumping
+//================================================
+
+// Additional OPTIONAL Fields and Globals
+float		intermission;
+float		sb_showscores;
+float		sb_showaccuracy;
+float		sbar_currentammo;
+.string		message;
+.float renderflags;
+// float		coop;
+// float		deathmatch;
+
+// float		dmg_take;
+// float		dmg_save;
+// vector		dmg_origin;
+
+// Darkplaces Render Modifications
+#if 0
+.float alpha;
+.float renderflags;
+.vector colormod;
+.float scale;
+#endif
+
+// Basic variables
+.float enttype; // entity type sent from server
+.float sv_entnum; // entity number sent from server
+.float team;
+.float team_size;
+
+float vid_conwidth, vid_conheight;
+float binddb;
+
+// QUALIFYING
+float race_checkpoint;
+float race_time;
+float race_laptime;
+float race_checkpointtime;
+float race_previousbesttime;
+string race_previousbestname;
+float race_nextcheckpoint;
+float race_nextbesttime;
+string race_nextbestname;
+
+// RACE
+float race_mycheckpoint;
+float race_mycheckpointtime;
+float race_mycheckpointdelta;
+float race_mycheckpointlapsdelta;
+string race_mycheckpointenemy;
+float race_othercheckpoint;
+float race_othercheckpointtime;
+float race_othercheckpointdelta;
+float race_othercheckpointlapsdelta;
+string race_othercheckpointenemy;
+float sb_showscores_force;
+
+// Nexball
+float nb_pb_period;
+
+// Spectating
+float spectatee_status;
+
+// short mapname
+string shortmapname;
+
+//remaining maptime announcer sounds, true when sound was already played
+float announcer_1min;
+float announcer_5min;
+
+// database for misc stuff
+float tempdb;
+vector hook_shotorigin;
+
+#ifdef BLURTEST
+float blurtest_time0, blurtest_time1, blurtest_radius, blurtest_power;
+#endif
+
+float servertime, serverprevtime, serverdeltatime;
+
+float ticrate;
+
+.float damageforcescale;
+.void(float thisdmg, float hittype, vector org, vector thisforce) event_damage;
+
+// only for Porto
+float angles_held_status;
+vector angles_held;


Property changes on: trunk/data/qcsrc/client/Defs.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/client/Main.qc
===================================================================
--- trunk/data/qcsrc/client/Main.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/client/Main.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,1067 +1,1067 @@
-// --------------------------------------------------------------------------
-// BEGIN REQUIRED CSQC FUNCTIONS
-//include "main.qh"
-
-#define DP_CSQC_ENTITY_REMOVE_IS_B0RKED
-
-void cvar_clientsettemp(string cv, string val)
-{
-	entity e;
-	for(e = world; (e = find(e, classname, "saved_cvar_value")); )
-		if(e.netname == cv)
-			goto saved;
-	e = spawn();
-	e.classname = "saved_cvar_value";
-	e.netname = strzone(cv);
-	e.message = strzone(cvar_string(cv));
-:saved
-	cvar_set(cv, val);
-}
-
-void cvar_clientsettemp_restore()
-{
-	entity e;
-	for(e = world; (e = find(e, classname, "saved_cvar_value")); )
-			cvar_set(e.netname, e.message);
-}
-
-void() menu_show_error =
-{
-	drawstring('0 200 0', "ERROR - MENU IS VISIBLE BUT NO MENU WAS DEFINED!", '8 8 0', '1 0 0', 1, 0);
-};
-
-// CSQC_Init : Called every time the CSQC code is initialized (essentially at map load)
-// Useful for precaching things
-
-void() menu_sub_null =
-{
-};
-
-#ifdef USE_FTE
-float __engine_check;
-#endif
-
-string forcefog;
-void WaypointSprite_Load();
-void CSQC_Init(void)
-{
-#ifdef USE_FTE
-#pragma target ID
-	__engine_check = checkextension("DP_SV_WRITEPICTURE");
-	if(!__engine_check)
-	{
-		print("^3Your engine build is outdated\n^3This Server uses a newer QC VM. Please update!\n");
-		localcmd("\ndisconnect\n");
-		return;
-	}
-#pragma target FTE
-#endif
-	
-	check_unacceptable_compiler_bugs();
-
-	float i;
-	CSQC_CheckEngine();
-	dprint_load();
-
-	binddb = db_create();
-	tempdb = db_create();
-	compressShortVector_init();
-
-	drawfont = 0;
-	menu_visible = FALSE;
-	menu_show = menu_show_error;
-	menu_action = menu_sub_null;
-
-	for(i = 0; i < 255; ++i)
-		if(getplayerkey(i, "viewentity") == "")
-			break;
-	maxclients = i;
-
-	//ctf_temp_1 = "";
-	// localcmd("alias order \"cmd order $*\""); enable if ctf-command thingy is used
-	//registercmd("ctf_menu");
-	registercmd("ons_map");
-	//registercmd("menu_action");
-
-	registercmd("+button3");
-	registercmd("-button3");
-	registercmd("+button4");
-	registercmd("-button4");
-	registercmd("+showaccuracy");registercmd("-showaccuracy");
-
-#ifndef CAMERATEST
-	if(isdemo())
-	{
-#endif
-		registercmd("+forward");registercmd("-forward");
-		registercmd("+back");registercmd("-back");
-		registercmd("+moveup");registercmd("-moveup");
-		registercmd("+movedown");registercmd("-movedown");
-		registercmd("+moveright");registercmd("-moveright");
-		registercmd("+moveleft");registercmd("-moveleft");
-		registercmd("+roll_right");registercmd("-roll_right");
-		registercmd("+roll_left");registercmd("-roll_left");
-#ifndef CAMERATEST
-	}
-#endif
-	registercvar("sbar_usecsqc", "1");
-	registercvar("sbar_columns", "default", CVAR_SAVE);
-
-	gametype = 0;
-
-	// sbar_fields uses strunzone on the titles!
-	for(i = 0; i < MAX_SBAR_FIELDS; ++i)
-		sbar_title[i] = strzone("(null)");
-
-	postinit = false;
-
-	teams = Sort_Spawn();
-	players = Sort_Spawn();
-
-	GetTeam(COLOR_SPECTATOR, true); // add specs first
-
-	cvar_clientsettemp("_supports_weaponpriority", "1");
-
-
-
-
-	cs_project_is_b0rked = TRUE;
-	R_SetView(VF_VIEWPORT, '0 0 0', '640 480 0');
-	R_SetView(VF_FOV, '90 90 0');
-	R_SetView(VF_ORIGIN, '0 0 0');
-	R_SetView(VF_ANGLES, '0 0 0');
-	R_SetView(VF_PERSPECTIVE, 1);
-	makevectors('0 0 0');
-	vector v;
-	v = cs_project(v_forward);
-	if(v_x - 320 < +1)
-	if(v_x - 320 > -1)
-	if(v_y - 240 < +1)
-	if(v_y - 240 > -1)
-		cs_project_is_b0rked = FALSE;
-
-	RegisterWeapons();
-
-	WaypointSprite_Load();
-
-	Projectile_Precache();
-	GibSplash_Precache();
-	Casings_Precache();
-	DamageInfo_Precache();
-	Announcer_Precache();
-
-	get_mi_min_max_texcoords(1); // try the CLEVER way first
-	minimapname = strcat("gfx/", mi_shortname, "_radar.tga");
-	shortmapname = mi_shortname;
-
-	if(precache_pic(minimapname) == "")
-	{
-		// but maybe we have a non-clever minimap
-		minimapname = strcat("gfx/", mi_shortname, "_mini.tga");
-		if(precache_pic(minimapname) == "")
-			minimapname = ""; // FAIL
-		else
-			get_mi_min_max_texcoords(0); // load new texcoords
-	}
-
-	mi_center = (mi_min + mi_max) * 0.5;
-	mi_scale = mi_max - mi_min;
-	minimapname = strzone(minimapname);
-}
-
-// CSQC_Shutdown : Called every time the CSQC code is shutdown (changing maps, quitting, etc)
-void CSQC_Shutdown(void)
-{
-#ifdef USE_FTE
-#pragma TARGET id
-	if(!__engine_check)
-		return 0;
-#pragma TARGET fte
-#endif
-
-	remove(teams);
-	remove(players);
-	db_close(binddb);
-	db_close(tempdb);
-
-	cvar_clientsettemp_restore();
-
-	if(camera_active)
-		cvar_set("chase_active",ftos(chase_active_backup));
-}
-
-.float has_team;
-float SetTeam(entity o, float Team)
-{
-	entity tm;
-	if(Team == -1) // leave
-	{
-		if(o.has_team)
-		{
-			//print("(DISCONNECT) leave team ", ftos(o.team), "\n");
-			tm = GetTeam(o.team, false);
-			tm.team_size -= 1;
-			o.has_team = 0;
-			return TRUE;
-		}
-	}
-	else
-	{
-		if not(o.has_team)
-		{
-			//print("(CONNECT) enter team ", ftos(o.team), "\n");
-			o.team = Team;
-			tm = GetTeam(Team, true);
-			tm.team_size += 1;
-			o.has_team = 1;
-			return TRUE;
-		}
-		else if(Team != o.team)
-		{
-			//print("(CHANGE) leave team ", ftos(o.team), "\n");
-			tm = GetTeam(o.team, false);
-			tm.team_size -= 1;
-			o.team = Team;
-			//print("(CHANGE) enter team ", ftos(o.team), "\n");
-			tm = GetTeam(Team, true);
-			tm.team_size += 1;
-			return TRUE;
-		}
-	}
-	return FALSE;
-}
-
-void Playerchecker_Think()
-{
-	float i;
-	entity e;
-	for(i = 0; i < maxclients; ++i)
-	{
-		e = playerslots[i];
-		if(GetPlayerName(i) == "")
-		{
-			if(e.sort_prev)
-			{
-				//print("playerchecker: KILL KILL KILL\n");
-				// player disconnected
-				SetTeam(e, -1);
-				RemovePlayer(e);
-				e.sort_prev = world;
-				//e.gotscores = 0;
-			}
-		}
-		else
-		{
-			if not(e.sort_prev)
-			{
-				//print("playerchecker: SPAWN SPAWN SPAWN\n");
-				// player connected
-				if not(e)
-					playerslots[i] = e = spawn();
-				e.sv_entnum = i;
-				//e.gotscores = 0; // we might already have the scores...
-				SetTeam(e, GetPlayerColor(i)); // will not hurt; later updates come with Sbar_UpdatePlayerTeams
-				RegisterPlayer(e);
-				Sbar_UpdatePlayerPos(e);
-			}
-		}
-	}
-	self.nextthink = time + 0.2;
-}
-
-void Porto_Init();
-void TrueAim_Init();
-void PostInit(void)
-{
-	print(strcat("PostInit\n    maxclients = ", ftos(maxclients), "\n"));
-	localcmd(strcat("\nsbar_columns_set ", cvar_string("sbar_columns"), ";\n"));
-
-	entity playerchecker;
-	playerchecker = spawn();
-	playerchecker.think = Playerchecker_Think;
-	playerchecker.nextthink = time + 0.2;
-
-	Porto_Init();
-	TrueAim_Init();
-
-	postinit = true;
-}
-
-// CSQC_ConsoleCommand : Used to parse commands in the console that have been registered with the "registercmd" function
-// Return value should be 1 if CSQC handled the command, otherwise return 0 to have the engine handle it.
-float button_zoom;
-void Cmd_Sbar_SetFields(float);
-void Cmd_Sbar_Help(float);
-float CSQC_ConsoleCommand(string strMessage)
-{
-	float argc;
-	// Tokenize String
-	//argc = tokenize(strMessage);
-	argc = tokenize_console(strMessage);
-
-	// Acquire Command
-	local string strCmd;
-	strCmd = argv(0);
-
-	if(strCmd == "+button4") { // zoom
-		// return false, because the message shall be sent to the server anyway (for demos/speccing)
-		if(ignore_plus_zoom)
-		{
-			--ignore_plus_zoom;
-			return false;
-		}
-		button_zoom = 1;
-		return true;
-	} else if(strCmd == "-button4") { // zoom
-		if(ignore_minus_zoom)
-		{
-			--ignore_minus_zoom;
-			return false;
-		}
-		button_zoom = 0;
-		return true;
-	} else if(strCmd == "+button3") { // secondary
-		button_attack2 = 1;
-		return false;
-	} else if(strCmd == "-button3") { // secondary
-		button_attack2 = 0;
-		return false;
-	} else if(strCmd == "+showscores") {
-		sb_showscores = true;
-		return true;
-	} else if(strCmd == "-showscores") {
-		sb_showscores = false;
-		return true;
-	} else if(strCmd == "+showaccuracy") {
-		sb_showaccuracy = true;
-		return true;
-	} else if(strCmd == "-showaccuracy") {
-		sb_showaccuracy = false;
-		return true;
-	}
-
-	if(camera_active)
-	if(strCmd == "+forward" || strCmd == "-back") {
-		++camera_direction_x;
-		return true;
-	} else if(strCmd == "-forward" || strCmd == "+back") {
-		--camera_direction_x;
-		return true;
-	} else if(strCmd == "+moveright" || strCmd == "-moveleft") {
-		--camera_direction_y;
-		return true;
-	} else if(strCmd == "-moveright" || strCmd == "+moveleft") {
-		++camera_direction_y;
-		return true;
-	} else if(strCmd == "+moveup" || strCmd == "-movedown") {
-		++camera_direction_z;
-		return true;
-	} else if(strCmd == "-moveup" || strCmd == "+movedown") {
-		--camera_direction_z;
-		return true;
-	} else if(strCmd == "+roll_right" || strCmd == "-roll_left") {
-		++camera_roll;
-		return true;
-	} else if(strCmd == "+roll_left" || strCmd == "-roll_right") {
-		--camera_roll;
-		return true;
-	}
-
-	return false;
-}
-
-.vector view_ofs;
-entity debug_shotorg;
-void ShotOrg_Draw()
-{
-	self.origin = view_origin + view_forward * self.view_ofs_x + view_right * self.view_ofs_y + view_up * self.view_ofs_z;
-	self.angles = view_angles;
-	self.angles_x = -self.angles_x;
-	if not(self.cnt)
-		R_AddEntity(self);
-}
-void ShotOrg_Draw2D()
-{
-	vector coord2d_topleft, coord2d_topright, coord2d;
-	string s;
-	vector fs;
-
-	s = vtos(self.view_ofs);
-	s = substring(s, 1, strlen(s) - 2);
-	if(tokenize_console(s) == 3)
-		s = strcat(argv(0), " ", argv(1), " ", argv(2));
-
-	coord2d_topleft = project_3d_to_2d(self.origin + view_up * 4 - view_right * 4);
-	coord2d_topright = project_3d_to_2d(self.origin + view_up * 4 + view_right * 4);
-
-	fs = '1 1 0' * ((coord2d_topright_x - coord2d_topleft_x) / stringwidth(s, FALSE));
-
-	coord2d = coord2d_topleft;
-	if(fs_x < 8)
-	{
-		coord2d_x += (coord2d_topright_x - coord2d_topleft_x) * (1 - 8 / fs_x) * 0.5;
-		fs = '8 8 0';
-	}
-	coord2d_y -= fs_y;
-	coord2d_z = 0;
-	drawstring(coord2d, s, fs, '1 1 1', 1, 0);
-}
-
-void ShotOrg_Spawn()
-{
-	debug_shotorg = spawn();
-	debug_shotorg.draw = ShotOrg_Draw;
-	debug_shotorg.draw2d = ShotOrg_Draw2D;
-	debug_shotorg.renderflags = RF_VIEWMODEL;
-	debug_shotorg.effects = EF_FULLBRIGHT;
-	precache_model("models/shotorg_adjuster.md3");
-	setmodel(debug_shotorg, "models/shotorg_adjuster.md3");
-	debug_shotorg.scale = 2;
-	debug_shotorg.view_ofs = '25 8 -8';
-}
-
-void GameCommand(string msg)
-{
-	float argc;
-	argc = tokenize_console(msg);
-
-	if(argv(0) == "help" || argc == 0)
-	{
-		print("Usage: cl_cmd COMMAND..., where possible commands are:\n");
-		print("  settemp cvar value\n");
-		print("  radar\n");
-		print("  sbar_columns_set ...\n");
-		print("  sbar_columns_help\n");
-		GameCommand_Generic("help");
-		return;
-	}
-
-	if(GameCommand_Generic(msg))
-		return;
-
-	string cmd;
-	cmd = argv(0);
-	if(cmd == "mv_download") {
-		Cmd_MapVote_MapDownload(argc);
-	}
-	else if(cmd == "settemp") {
-		cvar_clientsettemp(argv(1), argv(2));
-	}
-	else if(cmd == "radar") {
-		ons_showmap = !ons_showmap;
-	}
-	else if(cmd == "sbar_columns_set") {
-		Cmd_Sbar_SetFields(argc);
-	}
-	else if(cmd == "sbar_columns_help") {
-		Cmd_Sbar_Help(argc);
-	}
-#ifdef BLURTEST
-	else if(cmd == "blurtest") {
-		blurtest_time0 = time;
-		blurtest_time1 = time + stof(argv(1));
-		blurtest_radius = stof(argv(2));
-		blurtest_power = stof(argv(3));
-	}
-#endif
-	else if(cmd == "shotorg_move") {
-		if(!debug_shotorg)
-			ShotOrg_Spawn();
-		else
-			debug_shotorg.view_ofs = debug_shotorg.view_ofs + stov(argv(1));
-		localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
-	}
-	else if(cmd == "shotorg_movez") {
-		if(!debug_shotorg)
-			ShotOrg_Spawn();
-		else
-			debug_shotorg.view_ofs = debug_shotorg.view_ofs + stof(argv(1)) * (debug_shotorg.view_ofs * (1 / debug_shotorg.view_ofs_x)); // closer/farther, same xy pos
-		localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
-	}
-	else if(cmd == "shotorg_set") {
-		if(!debug_shotorg)
-			ShotOrg_Spawn();
-		else
-			debug_shotorg.view_ofs = stov(argv(1));
-		localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
-	}
-	else if(cmd == "shotorg_setz") {
-		if(!debug_shotorg)
-			ShotOrg_Spawn();
-		else
-			debug_shotorg.view_ofs = debug_shotorg.view_ofs * (stof(argv(1)) / debug_shotorg.view_ofs_x); // closer/farther, same xy pos
-		localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
-	}
-	else if(cmd == "shotorg_toggle_hide") {
-		if(debug_shotorg)
-		{
-			debug_shotorg.cnt = !debug_shotorg.cnt;
-		}
-	}
-	else if(cmd == "shotorg_end") {
-		if(debug_shotorg)
-		{
-			print(vtos(debug_shotorg.view_ofs), "\n");
-			remove(debug_shotorg);
-			debug_shotorg = world;
-		}
-		localcmd("sv_cmd debug_shotorg\n");
-	}
-	else
-	{
-		print("Invalid command. For a list of supported commands, try cl_cmd help.\n");
-	}
-
-	return;
-}
-
-// CSQC_InputEvent : Used to perform actions based on any key pressed, key released and mouse on the client.
-// Return value should be 1 if CSQC handled the input, otherwise return 0 to have the input passed to the engine.
-// All keys are in ascii.
-// bInputType = 0 is key pressed, 1 is key released, 2 is mouse input.
-// In the case of keyboard input, nPrimary is the ascii code, and nSecondary is 0.
-// In the case of mouse input, nPrimary is xdelta, nSecondary is ydelta.
-float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
-{
-	local float bSkipKey;
-	bSkipKey = false;
-
-	if(menu_visible)
-		if(menu_action(bInputType, nPrimary, nSecondary))
-			return TRUE;
-	return bSkipKey;
-}
-
-// END REQUIRED CSQC FUNCTIONS
-// --------------------------------------------------------------------------
-
-// --------------------------------------------------------------------------
-// BEGIN OPTIONAL CSQC FUNCTIONS
-void Ent_ReadEntCS()
-{
-	InterpolateOrigin_Undo();
-
-	self.classname = "entcs_receiver";
-	self.sv_entnum = ReadByte() - 1;
-	self.origin_x = ReadShort();
-	self.origin_y = ReadShort();
-	self.origin_z = ReadShort();
-	self.angles_y = ReadByte() * 360.0 / 256;
-	self.origin_z = self.angles_x = self.angles_z = 0;
-
-	InterpolateOrigin_Note();
-}
-
-void Ent_Remove();
-
-void Ent_RemovePlayerScore()
-{
-	float i;
-
-	if(self.owner)
-	{
-		SetTeam(self.owner, -1);
-		self.owner.gotscores = 0;
-		for(i = 0; i < MAX_SCORE; ++i)
-			self.owner.(scores[i]) = 0; // clear all scores
-	}
-}
-
-void Ent_ReadPlayerScore()
-{
-	float i, n;
-	float isNew;
-	entity o;
-
-	// damnit -.- don't want to go change every single .sv_entnum in sbar.qc AGAIN
-	// (no I've never heard of M-x replace-string, sed, or anything like that)
-	isNew = !self.owner; // workaround for DP bug
-	n = ReadByte()-1;
-
-#ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
-	if(!isNew && n != self.sv_entnum)
-	{
-		print("A CSQC entity changed its owner!\n");
-		isNew = true;
-		Ent_Remove();
-		self.enttype = ENT_CLIENT_SCORES;
-	}
-#endif
-
-	self.sv_entnum = n;
-
-	if not(playerslots[self.sv_entnum])
-		playerslots[self.sv_entnum] = spawn();
-	o = self.owner = playerslots[self.sv_entnum];
-	o.sv_entnum = self.sv_entnum;
-	o.gotscores = 1;
-
-	//if not(o.sort_prev)
-	//	RegisterPlayer(o);
-	//playerchecker will do this for us later, if it has not already done so
-
-#if MAX_SCORE <= 3
-	for(i = 0; i < MAX_SCORE; ++i)
-		o.(scores[i]) = ReadShort();
-#else
-	float sf;
-#if MAX_SCORE <= 8
-	sf = ReadByte();
-#else
-	sf = ReadShort();
-#endif
-	float p;
-	for(i = 0, p = 1; i < MAX_SCORE; ++i, p *= 2)
-		if(sf & p)
-			o.(scores[i]) = ReadShort();
-#endif
-
-	if(o.sort_prev)
-		Sbar_UpdatePlayerPos(o); // if not registered, we cannot do this yet!
-
-	self.entremove = Ent_RemovePlayerScore;
-}
-
-void Ent_ReadTeamScore()
-{
-	float i;
-	entity o;
-
-	self.team = ReadByte();
-	o = self.owner = GetTeam(self.team, true);
-
-#if MAX_TEAMSCORE <= 3
-	for(i = 0; i < MAX_TEAMSCORE; ++i)
-		o.(teamscores[i]) = ReadShort();
-#else
-	float sf;
-#if MAX_TEAMSCORE <= 8
-	sf = ReadByte();
-#else
-	sf = ReadShort();
-#endif
-	float p;
-	for(i = 0, p = 1; i < MAX_TEAMSCORE; ++i, p *= 2)
-		if(sf & p)
-			o.(teamscores[i]) = ReadShort();
-#endif
-
-	Sbar_UpdateTeamPos(o);
-}
-
-void Net_Reset()
-{
-}
-
-void Ent_ClientData()
-{
-	float f;
-	float newspectatee_status;
-
-	f = ReadByte();
-
-	sb_showscores_force = (f & 1);
-
-	if(f & 2)
-	{
-		newspectatee_status = ReadByte();
-		if(newspectatee_status == player_localentnum)
-			newspectatee_status = -1; // observing
-	}
-	else
-		newspectatee_status = 0;
-
-	spectatorbutton_zoom = (f & 4);
-
-	if(f & 8)
-	{
-		angles_held_status = 1;
-		angles_held_x = ReadAngle();
-		angles_held_y = ReadAngle();
-		angles_held_z = 0;
-	}
-	else
-		angles_held_status = 0;
-
-	if(newspectatee_status != spectatee_status)
-	{
-		// clear race stuff
-		race_laptime = 0;
-		race_checkpointtime = 0;
-	}
-	spectatee_status = newspectatee_status;
-}
-
-void Ent_Nagger()
-{
-	float nags, i, j, b, f;
-
-	nags = ReadByte();
-
-	if(nags & 128)
-	{
-		if(vote_called_vote)
-			strunzone(vote_called_vote);
-		vote_called_vote = strzone(ColorTranslateRGB(ReadString()));
-	}
-
-	if(nags & 1)
-	{
-		for(j = 0; j < maxclients; ++j)
-			if(playerslots[j])
-				playerslots[j].ready = 1;
-		for(i = 1; i <= maxclients; i += 8)
-		{
-			f = ReadByte();
-			for(j = i-1, b = 1; b < 256; b *= 2, ++j)
-				if not(f & b)
-					if(playerslots[j])
-						playerslots[j].ready = 0;
-		}
-	}
-
-	ready_waiting = (nags & 1);
-	ready_waiting_for_me = (nags & 2);
-	vote_waiting = (nags & 4);
-	vote_waiting_for_me = (nags & 8);
-	warmup_stage = (nags & 16);
-}
-
-void Ent_RandomSeed()
-{
-	float s;
-	prandom_debug();
-	s = ReadShort();
-	psrandom(s);
-}
-
-// CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
-// The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS.
-void Ent_RadarLink();
-void Ent_Init();
-void Ent_ScoresInfo();
-void(float bIsNewEntity) CSQC_Ent_Update =
-{
-	float t;
-	float savetime;
-	t = ReadByte();
-
-	// set up the "time" global for received entities to be correct for interpolation purposes
-	savetime = time;
-	if(servertime)
-	{
-		time = servertime;
-	}
-	else
-	{
-		serverprevtime = time;
-		serverdeltatime = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
-		time = serverprevtime + serverdeltatime;
-	}
-
-#ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
-	if(self.enttype)
-		if(t != self.enttype)
-		{
-			print("A CSQC entity changed its type!\n");
-			Ent_Remove();
-		}
-#endif
-	self.enttype = t;
-	switch(t)
-	{
-		case ENT_CLIENT_ENTCS: Ent_ReadEntCS(); break;
-		case ENT_CLIENT_SCORES: Ent_ReadPlayerScore(); break;
-		case ENT_CLIENT_TEAMSCORES: Ent_ReadTeamScore(); break;
-		case ENT_CLIENT_POINTPARTICLES: Ent_PointParticles(); break;
-		case ENT_CLIENT_RAINSNOW: Ent_RainOrSnow(); break;
-		case ENT_CLIENT_LASER: Ent_Laser(); break;
-		case ENT_CLIENT_NAGGER: Ent_Nagger(); break;
-		case ENT_CLIENT_WAYPOINT: Ent_WaypointSprite(); break;
-		case ENT_CLIENT_RADARLINK: Ent_RadarLink(); break;
-		case ENT_CLIENT_PROJECTILE: Ent_Projectile(); break;
-		case ENT_CLIENT_GIBSPLASH: Ent_GibSplash(); break;
-		case ENT_CLIENT_DAMAGEINFO: Ent_DamageInfo(); break;
-		case ENT_CLIENT_CASING: Ent_Casing(); break;
-		case ENT_CLIENT_INIT: Ent_Init(); break;
-		case ENT_CLIENT_SCORES_INFO: Ent_ScoresInfo(); break;
-		case ENT_CLIENT_MAPVOTE: Ent_MapVote(); break;
-		case ENT_CLIENT_CLIENTDATA: Ent_ClientData(); break;
-		case ENT_CLIENT_RANDOMSEED: Ent_RandomSeed(); break;
-		case ENT_CLIENT_WALL: Ent_Wall(); break;
-		default:
-			error(strcat("unknown entity type in CSQC_Ent_Update: ", ftos(self.enttype), "\n"));
-			break;
-	}
-
-	time = savetime;
-};
-// Destructor, but does NOT deallocate the entity by calling remove(). Also
-// used when an entity changes its type. For an entity that someone interacts
-// with others, make sure it can no longer do so.
-void Ent_Remove()
-{
-	if(self.entremove)
-		self.entremove();
-
-	self.enttype = 0;
-	self.classname = "";
-	self.draw = menu_sub_null;
-	self.entremove = menu_sub_null;
-	// TODO possibly set more stuff to defaults
-}
-// CSQC_Ent_Remove : Called when the server requests a SSQC / CSQC entity to be removed.  Essentially call remove(self) as well.
-void CSQC_Ent_Remove()
-{
-	if(self.enttype)
-		Ent_Remove();
-	remove(self);
-}
-
-void Gamemode_Init()
-{
-	if(gametype == GAME_ONSLAUGHT) {
-		print(strcat("Using ", minimapname, " as minimap.\n"));
-		precache_pic("gfx/ons-cp-neutral.tga");
-		precache_pic("gfx/ons-cp-red.tga");
-		precache_pic("gfx/ons-cp-blue.tga");
-		precache_pic("gfx/ons-frame.tga");
-		precache_pic("gfx/ons-frame-team.tga");
-	} else if(gametype == GAME_KEYHUNT) {
-		precache_pic("gfx/sb_key_carrying");
-		precache_pic("gfx/sb_key_carrying_outline");
-	}
-}
-// CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided.  To execute standard behavior, simply execute localcmd with the string.
-void CSQC_Parse_StuffCmd(string strMessage)
-{
-	localcmd(strMessage);
-}
-// CSQC_Parse_Print : Provides the print string in the first parameter that the server provided.  To execute standard behavior, simply execute print with the string.
-void CSQC_Parse_Print(string strMessage)
-{
-	print(ColorTranslateRGB(strMessage));
-}
-
-// CSQC_Parse_CenterPrint : Provides the centerprint string in the first parameter that the server provided.
-void CSQC_Parse_CenterPrint(string strMessage)
-{
-	centerprint(strMessage);
-}
-
-void Fog_Force()
-{
-	// TODO somehow thwart prvm_globalset client ...
-
-	if(forcefog != "")
-		localcmd(strcat("\nfog ", forcefog, "\nr_fog_exp2 0\nr_drawfog 1\n"));
-}
-
-void Gamemode_Init();
-void Ent_ScoresInfo()
-{
-	float i;
-	self.classname = "ent_client_scores_info";
-	gametype = ReadByte();
-	for(i = 0; i < MAX_SCORE; ++i)
-	{
-		scores_label[i] = strzone(ReadString());
-		scores_flags[i] = ReadByte();
-	}
-	for(i = 0; i < MAX_TEAMSCORE; ++i)
-	{
-		teamscores_label[i] = strzone(ReadString());
-		teamscores_flags[i] = ReadByte();
-	}
-	Sbar_InitScores();
-	Gamemode_Init();
-}
-
-void Ent_Init()
-{
-	float i;
-	self.classname = "ent_client_init";
-
-	nb_pb_period = ReadByte() / 32; //Accuracy of 1/32th
-
-	for(i = 0; i < 24; ++i)
-		weaponimpulse[i] = ReadByte() - 1;
-	hook_shotorigin_x = ReadCoord();
-	hook_shotorigin_y = ReadCoord();
-	hook_shotorigin_z = ReadCoord();
-
-	if(forcefog)
-		strunzone(forcefog);
-	forcefog = strzone(ReadString());
-
-	armorblockpercent = ReadByte() / 255.0;
-
-	if(!postinit)
-		PostInit();
-}
-
-void Net_ReadRace()
-{
-	float b;
-
-	b = ReadByte();
-
-	switch(b)
-	{
-		case RACE_NET_CHECKPOINT_HIT_QUALIFYING:
-			race_checkpoint = ReadByte();
-			race_time = ReadShort();
-			race_previousbesttime = ReadShort();
-			if(race_previousbestname)
-				strunzone(race_previousbestname);
-			race_previousbestname = strzone(ColorTranslateRGB(ReadString()));
-
-			race_checkpointtime = time;
-
-			if(race_checkpoint == 0)
-				race_laptime = time; // valid
-
-			break;
-
-		case RACE_NET_CHECKPOINT_CLEAR:
-			race_laptime = 0;
-			race_checkpointtime = 0;
-			break;
-
-		case RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING:
-			race_laptime = ReadCoord();
-			race_checkpointtime = -99999;
-			// fall through
-		case RACE_NET_CHECKPOINT_NEXT_QUALIFYING:
-			race_nextcheckpoint = ReadByte();
-
-			race_nextbesttime = ReadShort();
-			if(race_nextbestname)
-				strunzone(race_nextbestname);
-			race_nextbestname = strzone(ColorTranslateRGB(ReadString()));
-			break;
-
-		case RACE_NET_CHECKPOINT_HIT_RACE:
-			race_mycheckpoint = ReadByte();
-			race_mycheckpointtime = time;
-			race_mycheckpointdelta = ReadShort();
-			race_mycheckpointlapsdelta = ReadByte();
-			if(race_mycheckpointlapsdelta >= 128)
-				race_mycheckpointlapsdelta -= 256;
-			if(race_mycheckpointenemy)
-				strunzone(race_mycheckpointenemy);
-			race_mycheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
-			break;
-
-		case RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT:
-			race_othercheckpoint = ReadByte();
-			race_othercheckpointtime = time;
-			race_othercheckpointdelta = ReadShort();
-			race_othercheckpointlapsdelta = ReadByte();
-			if(race_othercheckpointlapsdelta >= 128)
-				race_othercheckpointlapsdelta -= 256;
-			if(race_othercheckpointenemy)
-				strunzone(race_othercheckpointenemy);
-			race_othercheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
-			break;
-	}
-}
-
-void Net_ReadSpawn()
-{
-	zoomin_effect = 1;
-	current_viewzoom = 0.6;
-}
-
-// CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
-// You must ALWAYS first acquire the temporary ID, which is sent as a byte.
-// Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
-float CSQC_Parse_TempEntity()
-{
-	local float bHandled;
-		bHandled  = true;
-	// Acquire TE ID
-	local float nTEID;
-		nTEID = ReadByte();
-
-		// NOTE: Could just do return instead of break...
-	switch(nTEID)
-	{
-		case TE_CSQC_PICTURE:
-			Net_MapVote_Picture();
-			bHandled = true;
-			break;
-		case TE_CSQC_RACE:
-			Net_ReadRace();
-			bHandled = true;
-			break;
-		case 13: // TE_BEAM
-			Net_GrapplingHook();
-			bHandled = true;
-			break;
-		case TE_CSQC_SPAWN:
-			Net_ReadSpawn();
-			bHandled = true;
-			break;
-		case TE_CSQC_ZCURVEPARTICLES:
-			Net_ReadZCurveParticles();
-			bHandled = true;
-			break;
-		case TE_CSQC_NEXGUNBEAMPARTICLE:
-			Net_ReadNexgunBeamParticle();
-			bHandled = true;
-			break;
-        case TE_CSQC_LIGHTNINGARC:
-            Net_ReadLightningarc();
-            bHandled = true;
-            break;
-		default:
-			// No special logic for this temporary entity; return 0 so the engine can handle it
-			bHandled = false;
-			break;
-	}
-
-	return bHandled;
-}
-
-string getcommandkey(string text, string command)
-{
-	string keys;
-	float n, j, k, l;
-
-	if (!sbar_showbinds)
-		return text;
-
-	keys = db_get(binddb, command);
-	if (!keys)
-	{
-		n = tokenize(findkeysforcommand(command)); // uses '...' strings
-		for(j = 0; j < n; ++j)
-		{
-			k = stof(argv(j));
-			if(k != -1)
-			{
-				if ("" == keys)
-					keys = keynumtostring(k);
-				else
-					keys = strcat(keys, ", ", keynumtostring(k));
-
-				++l;
-				if (sbar_showbinds_limit > 0 && sbar_showbinds_limit >= l) break;
-			}
-
-		}
-		db_put(binddb, command, keys);
-	}
-
-	if ("" == keys) {
-		if (sbar_showbinds > 1)
-			return strcat(text, " (not bound)");
-		else
-			return text;
-	}
-	else if (sbar_showbinds > 1)
-		return strcat(text, " (", keys, ")");
-	else
-		return keys;
-}
+// --------------------------------------------------------------------------
+// BEGIN REQUIRED CSQC FUNCTIONS
+//include "main.qh"
+
+#define DP_CSQC_ENTITY_REMOVE_IS_B0RKED
+
+void cvar_clientsettemp(string cv, string val)
+{
+	entity e;
+	for(e = world; (e = find(e, classname, "saved_cvar_value")); )
+		if(e.netname == cv)
+			goto saved;
+	e = spawn();
+	e.classname = "saved_cvar_value";
+	e.netname = strzone(cv);
+	e.message = strzone(cvar_string(cv));
+:saved
+	cvar_set(cv, val);
+}
+
+void cvar_clientsettemp_restore()
+{
+	entity e;
+	for(e = world; (e = find(e, classname, "saved_cvar_value")); )
+			cvar_set(e.netname, e.message);
+}
+
+void() menu_show_error =
+{
+	drawstring('0 200 0', "ERROR - MENU IS VISIBLE BUT NO MENU WAS DEFINED!", '8 8 0', '1 0 0', 1, 0);
+};
+
+// CSQC_Init : Called every time the CSQC code is initialized (essentially at map load)
+// Useful for precaching things
+
+void() menu_sub_null =
+{
+};
+
+#ifdef USE_FTE
+float __engine_check;
+#endif
+
+string forcefog;
+void WaypointSprite_Load();
+void CSQC_Init(void)
+{
+#ifdef USE_FTE
+#pragma target ID
+	__engine_check = checkextension("DP_SV_WRITEPICTURE");
+	if(!__engine_check)
+	{
+		print("^3Your engine build is outdated\n^3This Server uses a newer QC VM. Please update!\n");
+		localcmd("\ndisconnect\n");
+		return;
+	}
+#pragma target FTE
+#endif
+	
+	check_unacceptable_compiler_bugs();
+
+	float i;
+	CSQC_CheckEngine();
+	dprint_load();
+
+	binddb = db_create();
+	tempdb = db_create();
+	compressShortVector_init();
+
+	drawfont = 0;
+	menu_visible = FALSE;
+	menu_show = menu_show_error;
+	menu_action = menu_sub_null;
+
+	for(i = 0; i < 255; ++i)
+		if(getplayerkey(i, "viewentity") == "")
+			break;
+	maxclients = i;
+
+	//ctf_temp_1 = "";
+	// localcmd("alias order \"cmd order $*\""); enable if ctf-command thingy is used
+	//registercmd("ctf_menu");
+	registercmd("ons_map");
+	//registercmd("menu_action");
+
+	registercmd("+button3");
+	registercmd("-button3");
+	registercmd("+button4");
+	registercmd("-button4");
+	registercmd("+showaccuracy");registercmd("-showaccuracy");
+
+#ifndef CAMERATEST
+	if(isdemo())
+	{
+#endif
+		registercmd("+forward");registercmd("-forward");
+		registercmd("+back");registercmd("-back");
+		registercmd("+moveup");registercmd("-moveup");
+		registercmd("+movedown");registercmd("-movedown");
+		registercmd("+moveright");registercmd("-moveright");
+		registercmd("+moveleft");registercmd("-moveleft");
+		registercmd("+roll_right");registercmd("-roll_right");
+		registercmd("+roll_left");registercmd("-roll_left");
+#ifndef CAMERATEST
+	}
+#endif
+	registercvar("sbar_usecsqc", "1");
+	registercvar("sbar_columns", "default", CVAR_SAVE);
+
+	gametype = 0;
+
+	// sbar_fields uses strunzone on the titles!
+	for(i = 0; i < MAX_SBAR_FIELDS; ++i)
+		sbar_title[i] = strzone("(null)");
+
+	postinit = false;
+
+	teams = Sort_Spawn();
+	players = Sort_Spawn();
+
+	GetTeam(COLOR_SPECTATOR, true); // add specs first
+
+	cvar_clientsettemp("_supports_weaponpriority", "1");
+
+
+
+
+	cs_project_is_b0rked = TRUE;
+	R_SetView(VF_VIEWPORT, '0 0 0', '640 480 0');
+	R_SetView(VF_FOV, '90 90 0');
+	R_SetView(VF_ORIGIN, '0 0 0');
+	R_SetView(VF_ANGLES, '0 0 0');
+	R_SetView(VF_PERSPECTIVE, 1);
+	makevectors('0 0 0');
+	vector v;
+	v = cs_project(v_forward);
+	if(v_x - 320 < +1)
+	if(v_x - 320 > -1)
+	if(v_y - 240 < +1)
+	if(v_y - 240 > -1)
+		cs_project_is_b0rked = FALSE;
+
+	RegisterWeapons();
+
+	WaypointSprite_Load();
+
+	Projectile_Precache();
+	GibSplash_Precache();
+	Casings_Precache();
+	DamageInfo_Precache();
+	Announcer_Precache();
+
+	get_mi_min_max_texcoords(1); // try the CLEVER way first
+	minimapname = strcat("gfx/", mi_shortname, "_radar.tga");
+	shortmapname = mi_shortname;
+
+	if(precache_pic(minimapname) == "")
+	{
+		// but maybe we have a non-clever minimap
+		minimapname = strcat("gfx/", mi_shortname, "_mini.tga");
+		if(precache_pic(minimapname) == "")
+			minimapname = ""; // FAIL
+		else
+			get_mi_min_max_texcoords(0); // load new texcoords
+	}
+
+	mi_center = (mi_min + mi_max) * 0.5;
+	mi_scale = mi_max - mi_min;
+	minimapname = strzone(minimapname);
+}
+
+// CSQC_Shutdown : Called every time the CSQC code is shutdown (changing maps, quitting, etc)
+void CSQC_Shutdown(void)
+{
+#ifdef USE_FTE
+#pragma TARGET id
+	if(!__engine_check)
+		return 0;
+#pragma TARGET fte
+#endif
+
+	remove(teams);
+	remove(players);
+	db_close(binddb);
+	db_close(tempdb);
+
+	cvar_clientsettemp_restore();
+
+	if(camera_active)
+		cvar_set("chase_active",ftos(chase_active_backup));
+}
+
+.float has_team;
+float SetTeam(entity o, float Team)
+{
+	entity tm;
+	if(Team == -1) // leave
+	{
+		if(o.has_team)
+		{
+			//print("(DISCONNECT) leave team ", ftos(o.team), "\n");
+			tm = GetTeam(o.team, false);
+			tm.team_size -= 1;
+			o.has_team = 0;
+			return TRUE;
+		}
+	}
+	else
+	{
+		if not(o.has_team)
+		{
+			//print("(CONNECT) enter team ", ftos(o.team), "\n");
+			o.team = Team;
+			tm = GetTeam(Team, true);
+			tm.team_size += 1;
+			o.has_team = 1;
+			return TRUE;
+		}
+		else if(Team != o.team)
+		{
+			//print("(CHANGE) leave team ", ftos(o.team), "\n");
+			tm = GetTeam(o.team, false);
+			tm.team_size -= 1;
+			o.team = Team;
+			//print("(CHANGE) enter team ", ftos(o.team), "\n");
+			tm = GetTeam(Team, true);
+			tm.team_size += 1;
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+void Playerchecker_Think()
+{
+	float i;
+	entity e;
+	for(i = 0; i < maxclients; ++i)
+	{
+		e = playerslots[i];
+		if(GetPlayerName(i) == "")
+		{
+			if(e.sort_prev)
+			{
+				//print("playerchecker: KILL KILL KILL\n");
+				// player disconnected
+				SetTeam(e, -1);
+				RemovePlayer(e);
+				e.sort_prev = world;
+				//e.gotscores = 0;
+			}
+		}
+		else
+		{
+			if not(e.sort_prev)
+			{
+				//print("playerchecker: SPAWN SPAWN SPAWN\n");
+				// player connected
+				if not(e)
+					playerslots[i] = e = spawn();
+				e.sv_entnum = i;
+				//e.gotscores = 0; // we might already have the scores...
+				SetTeam(e, GetPlayerColor(i)); // will not hurt; later updates come with Sbar_UpdatePlayerTeams
+				RegisterPlayer(e);
+				Sbar_UpdatePlayerPos(e);
+			}
+		}
+	}
+	self.nextthink = time + 0.2;
+}
+
+void Porto_Init();
+void TrueAim_Init();
+void PostInit(void)
+{
+	print(strcat("PostInit\n    maxclients = ", ftos(maxclients), "\n"));
+	localcmd(strcat("\nsbar_columns_set ", cvar_string("sbar_columns"), ";\n"));
+
+	entity playerchecker;
+	playerchecker = spawn();
+	playerchecker.think = Playerchecker_Think;
+	playerchecker.nextthink = time + 0.2;
+
+	Porto_Init();
+	TrueAim_Init();
+
+	postinit = true;
+}
+
+// CSQC_ConsoleCommand : Used to parse commands in the console that have been registered with the "registercmd" function
+// Return value should be 1 if CSQC handled the command, otherwise return 0 to have the engine handle it.
+float button_zoom;
+void Cmd_Sbar_SetFields(float);
+void Cmd_Sbar_Help(float);
+float CSQC_ConsoleCommand(string strMessage)
+{
+	float argc;
+	// Tokenize String
+	//argc = tokenize(strMessage);
+	argc = tokenize_console(strMessage);
+
+	// Acquire Command
+	local string strCmd;
+	strCmd = argv(0);
+
+	if(strCmd == "+button4") { // zoom
+		// return false, because the message shall be sent to the server anyway (for demos/speccing)
+		if(ignore_plus_zoom)
+		{
+			--ignore_plus_zoom;
+			return false;
+		}
+		button_zoom = 1;
+		return true;
+	} else if(strCmd == "-button4") { // zoom
+		if(ignore_minus_zoom)
+		{
+			--ignore_minus_zoom;
+			return false;
+		}
+		button_zoom = 0;
+		return true;
+	} else if(strCmd == "+button3") { // secondary
+		button_attack2 = 1;
+		return false;
+	} else if(strCmd == "-button3") { // secondary
+		button_attack2 = 0;
+		return false;
+	} else if(strCmd == "+showscores") {
+		sb_showscores = true;
+		return true;
+	} else if(strCmd == "-showscores") {
+		sb_showscores = false;
+		return true;
+	} else if(strCmd == "+showaccuracy") {
+		sb_showaccuracy = true;
+		return true;
+	} else if(strCmd == "-showaccuracy") {
+		sb_showaccuracy = false;
+		return true;
+	}
+
+	if(camera_active)
+	if(strCmd == "+forward" || strCmd == "-back") {
+		++camera_direction_x;
+		return true;
+	} else if(strCmd == "-forward" || strCmd == "+back") {
+		--camera_direction_x;
+		return true;
+	} else if(strCmd == "+moveright" || strCmd == "-moveleft") {
+		--camera_direction_y;
+		return true;
+	} else if(strCmd == "-moveright" || strCmd == "+moveleft") {
+		++camera_direction_y;
+		return true;
+	} else if(strCmd == "+moveup" || strCmd == "-movedown") {
+		++camera_direction_z;
+		return true;
+	} else if(strCmd == "-moveup" || strCmd == "+movedown") {
+		--camera_direction_z;
+		return true;
+	} else if(strCmd == "+roll_right" || strCmd == "-roll_left") {
+		++camera_roll;
+		return true;
+	} else if(strCmd == "+roll_left" || strCmd == "-roll_right") {
+		--camera_roll;
+		return true;
+	}
+
+	return false;
+}
+
+.vector view_ofs;
+entity debug_shotorg;
+void ShotOrg_Draw()
+{
+	self.origin = view_origin + view_forward * self.view_ofs_x + view_right * self.view_ofs_y + view_up * self.view_ofs_z;
+	self.angles = view_angles;
+	self.angles_x = -self.angles_x;
+	if not(self.cnt)
+		R_AddEntity(self);
+}
+void ShotOrg_Draw2D()
+{
+	vector coord2d_topleft, coord2d_topright, coord2d;
+	string s;
+	vector fs;
+
+	s = vtos(self.view_ofs);
+	s = substring(s, 1, strlen(s) - 2);
+	if(tokenize_console(s) == 3)
+		s = strcat(argv(0), " ", argv(1), " ", argv(2));
+
+	coord2d_topleft = project_3d_to_2d(self.origin + view_up * 4 - view_right * 4);
+	coord2d_topright = project_3d_to_2d(self.origin + view_up * 4 + view_right * 4);
+
+	fs = '1 1 0' * ((coord2d_topright_x - coord2d_topleft_x) / stringwidth(s, FALSE));
+
+	coord2d = coord2d_topleft;
+	if(fs_x < 8)
+	{
+		coord2d_x += (coord2d_topright_x - coord2d_topleft_x) * (1 - 8 / fs_x) * 0.5;
+		fs = '8 8 0';
+	}
+	coord2d_y -= fs_y;
+	coord2d_z = 0;
+	drawstring(coord2d, s, fs, '1 1 1', 1, 0);
+}
+
+void ShotOrg_Spawn()
+{
+	debug_shotorg = spawn();
+	debug_shotorg.draw = ShotOrg_Draw;
+	debug_shotorg.draw2d = ShotOrg_Draw2D;
+	debug_shotorg.renderflags = RF_VIEWMODEL;
+	debug_shotorg.effects = EF_FULLBRIGHT;
+	precache_model("models/shotorg_adjuster.md3");
+	setmodel(debug_shotorg, "models/shotorg_adjuster.md3");
+	debug_shotorg.scale = 2;
+	debug_shotorg.view_ofs = '25 8 -8';
+}
+
+void GameCommand(string msg)
+{
+	float argc;
+	argc = tokenize_console(msg);
+
+	if(argv(0) == "help" || argc == 0)
+	{
+		print("Usage: cl_cmd COMMAND..., where possible commands are:\n");
+		print("  settemp cvar value\n");
+		print("  radar\n");
+		print("  sbar_columns_set ...\n");
+		print("  sbar_columns_help\n");
+		GameCommand_Generic("help");
+		return;
+	}
+
+	if(GameCommand_Generic(msg))
+		return;
+
+	string cmd;
+	cmd = argv(0);
+	if(cmd == "mv_download") {
+		Cmd_MapVote_MapDownload(argc);
+	}
+	else if(cmd == "settemp") {
+		cvar_clientsettemp(argv(1), argv(2));
+	}
+	else if(cmd == "radar") {
+		ons_showmap = !ons_showmap;
+	}
+	else if(cmd == "sbar_columns_set") {
+		Cmd_Sbar_SetFields(argc);
+	}
+	else if(cmd == "sbar_columns_help") {
+		Cmd_Sbar_Help(argc);
+	}
+#ifdef BLURTEST
+	else if(cmd == "blurtest") {
+		blurtest_time0 = time;
+		blurtest_time1 = time + stof(argv(1));
+		blurtest_radius = stof(argv(2));
+		blurtest_power = stof(argv(3));
+	}
+#endif
+	else if(cmd == "shotorg_move") {
+		if(!debug_shotorg)
+			ShotOrg_Spawn();
+		else
+			debug_shotorg.view_ofs = debug_shotorg.view_ofs + stov(argv(1));
+		localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
+	}
+	else if(cmd == "shotorg_movez") {
+		if(!debug_shotorg)
+			ShotOrg_Spawn();
+		else
+			debug_shotorg.view_ofs = debug_shotorg.view_ofs + stof(argv(1)) * (debug_shotorg.view_ofs * (1 / debug_shotorg.view_ofs_x)); // closer/farther, same xy pos
+		localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
+	}
+	else if(cmd == "shotorg_set") {
+		if(!debug_shotorg)
+			ShotOrg_Spawn();
+		else
+			debug_shotorg.view_ofs = stov(argv(1));
+		localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
+	}
+	else if(cmd == "shotorg_setz") {
+		if(!debug_shotorg)
+			ShotOrg_Spawn();
+		else
+			debug_shotorg.view_ofs = debug_shotorg.view_ofs * (stof(argv(1)) / debug_shotorg.view_ofs_x); // closer/farther, same xy pos
+		localcmd("sv_cmd debug_shotorg \"", vtos(debug_shotorg.view_ofs), "\"\n");
+	}
+	else if(cmd == "shotorg_toggle_hide") {
+		if(debug_shotorg)
+		{
+			debug_shotorg.cnt = !debug_shotorg.cnt;
+		}
+	}
+	else if(cmd == "shotorg_end") {
+		if(debug_shotorg)
+		{
+			print(vtos(debug_shotorg.view_ofs), "\n");
+			remove(debug_shotorg);
+			debug_shotorg = world;
+		}
+		localcmd("sv_cmd debug_shotorg\n");
+	}
+	else
+	{
+		print("Invalid command. For a list of supported commands, try cl_cmd help.\n");
+	}
+
+	return;
+}
+
+// CSQC_InputEvent : Used to perform actions based on any key pressed, key released and mouse on the client.
+// Return value should be 1 if CSQC handled the input, otherwise return 0 to have the input passed to the engine.
+// All keys are in ascii.
+// bInputType = 0 is key pressed, 1 is key released, 2 is mouse input.
+// In the case of keyboard input, nPrimary is the ascii code, and nSecondary is 0.
+// In the case of mouse input, nPrimary is xdelta, nSecondary is ydelta.
+float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
+{
+	local float bSkipKey;
+	bSkipKey = false;
+
+	if(menu_visible)
+		if(menu_action(bInputType, nPrimary, nSecondary))
+			return TRUE;
+	return bSkipKey;
+}
+
+// END REQUIRED CSQC FUNCTIONS
+// --------------------------------------------------------------------------
+
+// --------------------------------------------------------------------------
+// BEGIN OPTIONAL CSQC FUNCTIONS
+void Ent_ReadEntCS()
+{
+	InterpolateOrigin_Undo();
+
+	self.classname = "entcs_receiver";
+	self.sv_entnum = ReadByte() - 1;
+	self.origin_x = ReadShort();
+	self.origin_y = ReadShort();
+	self.origin_z = ReadShort();
+	self.angles_y = ReadByte() * 360.0 / 256;
+	self.origin_z = self.angles_x = self.angles_z = 0;
+
+	InterpolateOrigin_Note();
+}
+
+void Ent_Remove();
+
+void Ent_RemovePlayerScore()
+{
+	float i;
+
+	if(self.owner)
+	{
+		SetTeam(self.owner, -1);
+		self.owner.gotscores = 0;
+		for(i = 0; i < MAX_SCORE; ++i)
+			self.owner.(scores[i]) = 0; // clear all scores
+	}
+}
+
+void Ent_ReadPlayerScore()
+{
+	float i, n;
+	float isNew;
+	entity o;
+
+	// damnit -.- don't want to go change every single .sv_entnum in sbar.qc AGAIN
+	// (no I've never heard of M-x replace-string, sed, or anything like that)
+	isNew = !self.owner; // workaround for DP bug
+	n = ReadByte()-1;
+
+#ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
+	if(!isNew && n != self.sv_entnum)
+	{
+		print("A CSQC entity changed its owner!\n");
+		isNew = true;
+		Ent_Remove();
+		self.enttype = ENT_CLIENT_SCORES;
+	}
+#endif
+
+	self.sv_entnum = n;
+
+	if not(playerslots[self.sv_entnum])
+		playerslots[self.sv_entnum] = spawn();
+	o = self.owner = playerslots[self.sv_entnum];
+	o.sv_entnum = self.sv_entnum;
+	o.gotscores = 1;
+
+	//if not(o.sort_prev)
+	//	RegisterPlayer(o);
+	//playerchecker will do this for us later, if it has not already done so
+
+#if MAX_SCORE <= 3
+	for(i = 0; i < MAX_SCORE; ++i)
+		o.(scores[i]) = ReadShort();
+#else
+	float sf;
+#if MAX_SCORE <= 8
+	sf = ReadByte();
+#else
+	sf = ReadShort();
+#endif
+	float p;
+	for(i = 0, p = 1; i < MAX_SCORE; ++i, p *= 2)
+		if(sf & p)
+			o.(scores[i]) = ReadShort();
+#endif
+
+	if(o.sort_prev)
+		Sbar_UpdatePlayerPos(o); // if not registered, we cannot do this yet!
+
+	self.entremove = Ent_RemovePlayerScore;
+}
+
+void Ent_ReadTeamScore()
+{
+	float i;
+	entity o;
+
+	self.team = ReadByte();
+	o = self.owner = GetTeam(self.team, true);
+
+#if MAX_TEAMSCORE <= 3
+	for(i = 0; i < MAX_TEAMSCORE; ++i)
+		o.(teamscores[i]) = ReadShort();
+#else
+	float sf;
+#if MAX_TEAMSCORE <= 8
+	sf = ReadByte();
+#else
+	sf = ReadShort();
+#endif
+	float p;
+	for(i = 0, p = 1; i < MAX_TEAMSCORE; ++i, p *= 2)
+		if(sf & p)
+			o.(teamscores[i]) = ReadShort();
+#endif
+
+	Sbar_UpdateTeamPos(o);
+}
+
+void Net_Reset()
+{
+}
+
+void Ent_ClientData()
+{
+	float f;
+	float newspectatee_status;
+
+	f = ReadByte();
+
+	sb_showscores_force = (f & 1);
+
+	if(f & 2)
+	{
+		newspectatee_status = ReadByte();
+		if(newspectatee_status == player_localentnum)
+			newspectatee_status = -1; // observing
+	}
+	else
+		newspectatee_status = 0;
+
+	spectatorbutton_zoom = (f & 4);
+
+	if(f & 8)
+	{
+		angles_held_status = 1;
+		angles_held_x = ReadAngle();
+		angles_held_y = ReadAngle();
+		angles_held_z = 0;
+	}
+	else
+		angles_held_status = 0;
+
+	if(newspectatee_status != spectatee_status)
+	{
+		// clear race stuff
+		race_laptime = 0;
+		race_checkpointtime = 0;
+	}
+	spectatee_status = newspectatee_status;
+}
+
+void Ent_Nagger()
+{
+	float nags, i, j, b, f;
+
+	nags = ReadByte();
+
+	if(nags & 128)
+	{
+		if(vote_called_vote)
+			strunzone(vote_called_vote);
+		vote_called_vote = strzone(ColorTranslateRGB(ReadString()));
+	}
+
+	if(nags & 1)
+	{
+		for(j = 0; j < maxclients; ++j)
+			if(playerslots[j])
+				playerslots[j].ready = 1;
+		for(i = 1; i <= maxclients; i += 8)
+		{
+			f = ReadByte();
+			for(j = i-1, b = 1; b < 256; b *= 2, ++j)
+				if not(f & b)
+					if(playerslots[j])
+						playerslots[j].ready = 0;
+		}
+	}
+
+	ready_waiting = (nags & 1);
+	ready_waiting_for_me = (nags & 2);
+	vote_waiting = (nags & 4);
+	vote_waiting_for_me = (nags & 8);
+	warmup_stage = (nags & 16);
+}
+
+void Ent_RandomSeed()
+{
+	float s;
+	prandom_debug();
+	s = ReadShort();
+	psrandom(s);
+}
+
+// CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured.
+// The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS.
+void Ent_RadarLink();
+void Ent_Init();
+void Ent_ScoresInfo();
+void(float bIsNewEntity) CSQC_Ent_Update =
+{
+	float t;
+	float savetime;
+	t = ReadByte();
+
+	// set up the "time" global for received entities to be correct for interpolation purposes
+	savetime = time;
+	if(servertime)
+	{
+		time = servertime;
+	}
+	else
+	{
+		serverprevtime = time;
+		serverdeltatime = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
+		time = serverprevtime + serverdeltatime;
+	}
+
+#ifdef DP_CSQC_ENTITY_REMOVE_IS_B0RKED
+	if(self.enttype)
+		if(t != self.enttype)
+		{
+			print("A CSQC entity changed its type!\n");
+			Ent_Remove();
+		}
+#endif
+	self.enttype = t;
+	switch(t)
+	{
+		case ENT_CLIENT_ENTCS: Ent_ReadEntCS(); break;
+		case ENT_CLIENT_SCORES: Ent_ReadPlayerScore(); break;
+		case ENT_CLIENT_TEAMSCORES: Ent_ReadTeamScore(); break;
+		case ENT_CLIENT_POINTPARTICLES: Ent_PointParticles(); break;
+		case ENT_CLIENT_RAINSNOW: Ent_RainOrSnow(); break;
+		case ENT_CLIENT_LASER: Ent_Laser(); break;
+		case ENT_CLIENT_NAGGER: Ent_Nagger(); break;
+		case ENT_CLIENT_WAYPOINT: Ent_WaypointSprite(); break;
+		case ENT_CLIENT_RADARLINK: Ent_RadarLink(); break;
+		case ENT_CLIENT_PROJECTILE: Ent_Projectile(); break;
+		case ENT_CLIENT_GIBSPLASH: Ent_GibSplash(); break;
+		case ENT_CLIENT_DAMAGEINFO: Ent_DamageInfo(); break;
+		case ENT_CLIENT_CASING: Ent_Casing(); break;
+		case ENT_CLIENT_INIT: Ent_Init(); break;
+		case ENT_CLIENT_SCORES_INFO: Ent_ScoresInfo(); break;
+		case ENT_CLIENT_MAPVOTE: Ent_MapVote(); break;
+		case ENT_CLIENT_CLIENTDATA: Ent_ClientData(); break;
+		case ENT_CLIENT_RANDOMSEED: Ent_RandomSeed(); break;
+		case ENT_CLIENT_WALL: Ent_Wall(); break;
+		default:
+			error(strcat("unknown entity type in CSQC_Ent_Update: ", ftos(self.enttype), "\n"));
+			break;
+	}
+
+	time = savetime;
+};
+// Destructor, but does NOT deallocate the entity by calling remove(). Also
+// used when an entity changes its type. For an entity that someone interacts
+// with others, make sure it can no longer do so.
+void Ent_Remove()
+{
+	if(self.entremove)
+		self.entremove();
+
+	self.enttype = 0;
+	self.classname = "";
+	self.draw = menu_sub_null;
+	self.entremove = menu_sub_null;
+	// TODO possibly set more stuff to defaults
+}
+// CSQC_Ent_Remove : Called when the server requests a SSQC / CSQC entity to be removed.  Essentially call remove(self) as well.
+void CSQC_Ent_Remove()
+{
+	if(self.enttype)
+		Ent_Remove();
+	remove(self);
+}
+
+void Gamemode_Init()
+{
+	if(gametype == GAME_ONSLAUGHT) {
+		print(strcat("Using ", minimapname, " as minimap.\n"));
+		precache_pic("gfx/ons-cp-neutral.tga");
+		precache_pic("gfx/ons-cp-red.tga");
+		precache_pic("gfx/ons-cp-blue.tga");
+		precache_pic("gfx/ons-frame.tga");
+		precache_pic("gfx/ons-frame-team.tga");
+	} else if(gametype == GAME_KEYHUNT) {
+		precache_pic("gfx/sb_key_carrying");
+		precache_pic("gfx/sb_key_carrying_outline");
+	}
+}
+// CSQC_Parse_StuffCmd : Provides the stuffcmd string in the first parameter that the server provided.  To execute standard behavior, simply execute localcmd with the string.
+void CSQC_Parse_StuffCmd(string strMessage)
+{
+	localcmd(strMessage);
+}
+// CSQC_Parse_Print : Provides the print string in the first parameter that the server provided.  To execute standard behavior, simply execute print with the string.
+void CSQC_Parse_Print(string strMessage)
+{
+	print(ColorTranslateRGB(strMessage));
+}
+
+// CSQC_Parse_CenterPrint : Provides the centerprint string in the first parameter that the server provided.
+void CSQC_Parse_CenterPrint(string strMessage)
+{
+	centerprint(strMessage);
+}
+
+void Fog_Force()
+{
+	// TODO somehow thwart prvm_globalset client ...
+
+	if(forcefog != "")
+		localcmd(strcat("\nfog ", forcefog, "\nr_fog_exp2 0\nr_drawfog 1\n"));
+}
+
+void Gamemode_Init();
+void Ent_ScoresInfo()
+{
+	float i;
+	self.classname = "ent_client_scores_info";
+	gametype = ReadByte();
+	for(i = 0; i < MAX_SCORE; ++i)
+	{
+		scores_label[i] = strzone(ReadString());
+		scores_flags[i] = ReadByte();
+	}
+	for(i = 0; i < MAX_TEAMSCORE; ++i)
+	{
+		teamscores_label[i] = strzone(ReadString());
+		teamscores_flags[i] = ReadByte();
+	}
+	Sbar_InitScores();
+	Gamemode_Init();
+}
+
+void Ent_Init()
+{
+	float i;
+	self.classname = "ent_client_init";
+
+	nb_pb_period = ReadByte() / 32; //Accuracy of 1/32th
+
+	for(i = 0; i < 24; ++i)
+		weaponimpulse[i] = ReadByte() - 1;
+	hook_shotorigin_x = ReadCoord();
+	hook_shotorigin_y = ReadCoord();
+	hook_shotorigin_z = ReadCoord();
+
+	if(forcefog)
+		strunzone(forcefog);
+	forcefog = strzone(ReadString());
+
+	armorblockpercent = ReadByte() / 255.0;
+
+	if(!postinit)
+		PostInit();
+}
+
+void Net_ReadRace()
+{
+	float b;
+
+	b = ReadByte();
+
+	switch(b)
+	{
+		case RACE_NET_CHECKPOINT_HIT_QUALIFYING:
+			race_checkpoint = ReadByte();
+			race_time = ReadShort();
+			race_previousbesttime = ReadShort();
+			if(race_previousbestname)
+				strunzone(race_previousbestname);
+			race_previousbestname = strzone(ColorTranslateRGB(ReadString()));
+
+			race_checkpointtime = time;
+
+			if(race_checkpoint == 0)
+				race_laptime = time; // valid
+
+			break;
+
+		case RACE_NET_CHECKPOINT_CLEAR:
+			race_laptime = 0;
+			race_checkpointtime = 0;
+			break;
+
+		case RACE_NET_CHECKPOINT_NEXT_SPEC_QUALIFYING:
+			race_laptime = ReadCoord();
+			race_checkpointtime = -99999;
+			// fall through
+		case RACE_NET_CHECKPOINT_NEXT_QUALIFYING:
+			race_nextcheckpoint = ReadByte();
+
+			race_nextbesttime = ReadShort();
+			if(race_nextbestname)
+				strunzone(race_nextbestname);
+			race_nextbestname = strzone(ColorTranslateRGB(ReadString()));
+			break;
+
+		case RACE_NET_CHECKPOINT_HIT_RACE:
+			race_mycheckpoint = ReadByte();
+			race_mycheckpointtime = time;
+			race_mycheckpointdelta = ReadShort();
+			race_mycheckpointlapsdelta = ReadByte();
+			if(race_mycheckpointlapsdelta >= 128)
+				race_mycheckpointlapsdelta -= 256;
+			if(race_mycheckpointenemy)
+				strunzone(race_mycheckpointenemy);
+			race_mycheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
+			break;
+
+		case RACE_NET_CHECKPOINT_HIT_RACE_BY_OPPONENT:
+			race_othercheckpoint = ReadByte();
+			race_othercheckpointtime = time;
+			race_othercheckpointdelta = ReadShort();
+			race_othercheckpointlapsdelta = ReadByte();
+			if(race_othercheckpointlapsdelta >= 128)
+				race_othercheckpointlapsdelta -= 256;
+			if(race_othercheckpointenemy)
+				strunzone(race_othercheckpointenemy);
+			race_othercheckpointenemy = strzone(ColorTranslateRGB(ReadString()));
+			break;
+	}
+}
+
+void Net_ReadSpawn()
+{
+	zoomin_effect = 1;
+	current_viewzoom = 0.6;
+}
+
+// CSQC_Parse_TempEntity : Handles all temporary entity network data in the CSQC layer.
+// You must ALWAYS first acquire the temporary ID, which is sent as a byte.
+// Return value should be 1 if CSQC handled the temporary entity, otherwise return 0 to have the engine process the event.
+float CSQC_Parse_TempEntity()
+{
+	local float bHandled;
+		bHandled  = true;
+	// Acquire TE ID
+	local float nTEID;
+		nTEID = ReadByte();
+
+		// NOTE: Could just do return instead of break...
+	switch(nTEID)
+	{
+		case TE_CSQC_PICTURE:
+			Net_MapVote_Picture();
+			bHandled = true;
+			break;
+		case TE_CSQC_RACE:
+			Net_ReadRace();
+			bHandled = true;
+			break;
+		case 13: // TE_BEAM
+			Net_GrapplingHook();
+			bHandled = true;
+			break;
+		case TE_CSQC_SPAWN:
+			Net_ReadSpawn();
+			bHandled = true;
+			break;
+		case TE_CSQC_ZCURVEPARTICLES:
+			Net_ReadZCurveParticles();
+			bHandled = true;
+			break;
+		case TE_CSQC_NEXGUNBEAMPARTICLE:
+			Net_ReadNexgunBeamParticle();
+			bHandled = true;
+			break;
+        case TE_CSQC_LIGHTNINGARC:
+            Net_ReadLightningarc();
+            bHandled = true;
+            break;
+		default:
+			// No special logic for this temporary entity; return 0 so the engine can handle it
+			bHandled = false;
+			break;
+	}
+
+	return bHandled;
+}
+
+string getcommandkey(string text, string command)
+{
+	string keys;
+	float n, j, k, l;
+
+	if (!sbar_showbinds)
+		return text;
+
+	keys = db_get(binddb, command);
+	if (!keys)
+	{
+		n = tokenize(findkeysforcommand(command)); // uses '...' strings
+		for(j = 0; j < n; ++j)
+		{
+			k = stof(argv(j));
+			if(k != -1)
+			{
+				if ("" == keys)
+					keys = keynumtostring(k);
+				else
+					keys = strcat(keys, ", ", keynumtostring(k));
+
+				++l;
+				if (sbar_showbinds_limit > 0 && sbar_showbinds_limit >= l) break;
+			}
+
+		}
+		db_put(binddb, command, keys);
+	}
+
+	if ("" == keys) {
+		if (sbar_showbinds > 1)
+			return strcat(text, " (not bound)");
+		else
+			return text;
+	}
+	else if (sbar_showbinds > 1)
+		return strcat(text, " (", keys, ")");
+	else
+		return keys;
+}


Property changes on: trunk/data/qcsrc/client/Main.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/client/View.qc
===================================================================
--- trunk/data/qcsrc/client/View.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/client/View.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,863 +1,863 @@
-#define spider_rocket_icon "gfx/spiderbot/rocket_ico.tga"
-#define spider_rocket_targ "gfx/spiderbot/target.tga"
-#define SPIDER_CROSS "textures/spiderbot/cross.tga"
-#define rkt_size 32
-#define rld_size_x 256
-#define rld_size_y 16
-
-entity porto;
-vector polyline[16];
-float trace_dphitcontents;
-float trace_networkentity;
-float Q3SURFACEFLAG_SLICK = 2; // low friction surface
-float DPCONTENTS_SOLID = 1; // blocks player movement
-float DPCONTENTS_BODY = 32; // blocks player movement
-float DPCONTENTS_CORPSE = 64; // blocks player movement
-float DPCONTENTS_PLAYERCLIP = 256; // blocks player movement
-void Porto_Draw()
-{
-	vector p, dir, ang, q, nextdir;
-	float idx, portal_number, portal1_idx;
-
-	if(activeweapon != WEP_PORTO || spectatee_status || gametype == GAME_NEXBALL)
-		return;
-	if(intermission == 1)
-		return;
-	if(intermission == 2)
-		return;
-	if (getstati(STAT_HEALTH) <= 0)
-		return;
-
-	dir = view_forward;
-
-	if(angles_held_status)
-	{
-		makevectors(angles_held);
-		dir = v_forward;
-	}
-
-	p = view_origin;
-
-	polyline[0] = p;
-	idx = 1;
-	portal_number = 0;
-	nextdir = dir;
-
-	for(;;)
-	{
-		dir = nextdir;
-		traceline(p, p + 65536 * dir, TRUE, porto);
-		if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
-			return;
-		nextdir = dir - 2 * (dir * trace_plane_normal) * trace_plane_normal; // mirror dir at trace_plane_normal
-		p = trace_endpos;
-		polyline[idx] = p;
-		++idx;
-		if(idx >= 16)
-			return;
-		if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP)
-			continue;
-		++portal_number;
-		ang = vectoangles2(trace_plane_normal, dir);
-		ang_x = -ang_x;
-		makevectors(ang);
-		if(!CheckWireframeBox(porto, p - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward))
-			return;
-		if(portal_number == 1)
-			portal1_idx = idx;
-		if(portal_number >= 2)
-			break;
-	}
-
-	while(idx >= 2)
-	{
-		p = polyline[idx-2];
-		q = polyline[idx-1];
-		if(idx == 2)
-			p = p - view_up * 16;
-		if(idx-1 >= portal1_idx)
-		{
-			Draw_CylindricLine(p, q, 4, "", 1, 0, '0 0 1', 0.5, DRAWFLAG_NORMAL);
-		}
-		else
-		{
-			Draw_CylindricLine(p, q, 4, "", 1, 0, '1 0 0', 0.5, DRAWFLAG_NORMAL);
-		}
-		--idx;
-	}
-}
-
-/**
- * Checks whether the server initiated a map restart (stat_game_starttime changed)
- *
- * TODO: Use a better solution where a common shared entitiy is used that contains
- * timelimit, fraglimit and game_starttime! Requires engine changes (remove STAT_TIMELIMIT
- * and STAT_FRAGLIMIT to be auto-sent)
- */
-void CheckForGamestartChange() {
-	float startTime;
-	startTime = getstatf(STAT_GAMESTARTTIME);
-	if (previous_game_starttime != startTime) {
-		if ((time + 5.0) < startTime) {
-			//if connecting to server while restart was active don't always play prepareforbattle
-			sound(self, CHAN_VOICE, "announcer/robotic/prepareforbattle.wav", VOL_BASEVOICE, ATTN_NONE);
-		}
-		if (time < startTime) {
-			restartAnnouncer = spawn();
-			restartAnnouncer.think = restartAnnouncer_Think;
-			restartAnnouncer.nextthink = startTime - floor(startTime - time); //synchronize nextthink to startTime
-		}
-	}
-	previous_game_starttime = startTime;
-}
-
-void Porto_Init()
-{
-	porto = spawn();
-	porto.classname = "porto";
-	porto.draw = Porto_Draw;
-	porto.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
-}
-
-float drawtime;
-
-float tan(float x)
-{
-	return sin(x) / cos(x);
-}
-float atan2(float y, float x)
-{
-	vector v;
-	v = '1 0 0' * x + '0 1 0' * y;
-	v = vectoangles(v);
-	return v_y * 0.01745329251994329576;
-}
-
-vector GetCurrentFov(float fov)
-{
-	float zoomsensitivity, zoomspeed, zoomfactor, zoomdir;
-
-	zoomsensitivity = cvar("cl_zoomsensitivity");
-	zoomfactor = cvar("cl_zoomfactor");
-	if(zoomfactor < 1 || zoomfactor > 16)
-		zoomfactor = 2.5;
-	zoomspeed = cvar("cl_zoomspeed");
-	if(zoomspeed >= 0)
-		if(zoomspeed < 0.5 || zoomspeed > 16)
-			zoomspeed = 3.5;
-
-	zoomdir = button_zoom;
-	if(getstati(STAT_ACTIVEWEAPON) == WEP_NEX) // do NOT use switchweapon here
-		zoomdir += button_attack2;
-	if(spectatee_status > 0 || isdemo())
-	{
-		if(spectatorbutton_zoom)
-			zoomdir = 0 + !zoomdir;
-			// do not even THINK about removing this 0
-			// _I_ know what I am doing
-			// fteqcc does not
-	}
-
-	if(zoomdir)
-		zoomin_effect = 0;
-
-	if(zoomin_effect || camera_active)
-	{
-		current_viewzoom = min(1, current_viewzoom + drawframetime);
-	}
-	else
-	{
-		if(zoomspeed < 0) // instant zoom
-		{
-			if(zoomdir)
-				current_viewzoom = 1 / zoomfactor;
-			else
-				current_viewzoom = 1;
-		}
-		else
-		{
-			if(zoomdir)
-				current_viewzoom = 1 / bound(1, 1 / current_viewzoom + drawframetime * zoomspeed * (zoomfactor - 1), zoomfactor);
-			else
-				current_viewzoom = bound(1 / zoomfactor, current_viewzoom + drawframetime * zoomspeed * (1 - 1 / zoomfactor), 1);
-		}
-	}
-
-	if(almost_equals(current_viewzoom, 1))
-		current_zoomfraction = 0;
-	else if(almost_equals(current_viewzoom, 1/zoomfactor))
-		current_zoomfraction = 1;
-	else
-		current_zoomfraction = (current_viewzoom - 1) / (1/zoomfactor - 1);
-
-	if(zoomsensitivity < 1)
-		setsensitivityscale(pow(current_viewzoom, 1 - zoomsensitivity));
-	else
-		setsensitivityscale(1);
-
-	float frustumx, frustumy, fovx, fovy;
-	frustumy = tan(fov * 0.00872664625997164788) * 0.75 * current_viewzoom;
-	frustumx = frustumy * vid_width / vid_height / vid_pixelheight;
-	fovx = atan2(frustumx, 1) / 0.00872664625997164788;
-	fovy = atan2(frustumy, 1) / 0.00872664625997164788;
-
-	return '1 0 0' * fovx + '0 1 0' * fovy;
-}
-
-// this function must match W_SetupShot!
-float zoomscript_caught;
-entity trueaim;
-
-#define SHOTTYPE_HITTEAM 1
-#define SHOTTYPE_HITOBSTRUCTION 2
-#define SHOTTYPE_HITWORLD 3
-#define SHOTTYPE_HITENEMY 4
-
-void TrueAim_Init()
-{
-	trueaim = spawn();
-	trueaim.classname = "trueaim";
-	trueaim.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
-}
-
-float EnemyHitCheck(vector start, vector mi, vector ma, vector end)
-{
-	float t;
-	tracebox(start, mi, ma, end, MOVE_NORMAL, trueaim);
-	if(trace_networkentity < 1)
-		return SHOTTYPE_HITWORLD;
-	if(trace_networkentity > maxclients)
-		return SHOTTYPE_HITWORLD;
-	t = GetPlayerColor(trace_networkentity - 1);
-	if(teamplay)
-	if(t == myteam)
-		return SHOTTYPE_HITTEAM;
-	if(t == COLOR_SPECTATOR)
-		return SHOTTYPE_HITWORLD;
-	return SHOTTYPE_HITENEMY;
-}
-
-float TrueAimCheck()
-{
-	float nudge = 1; // added to traceline target and subtracted from result
-	vector vecs, trueaimpoint, w_shotorg;
-	vector mi, ma, dv;
-	float shottype;
-
-	mi = ma = '0 0 0';
-
-	switch(activeweapon)
-	{
-		case WEP_TUBA: // no aim
-		case WEP_PORTO: // shoots from eye
-		case WEP_HOOK: // no trueaim
-		case WEP_GRENADE_LAUNCHER: // toss curve
-			return SHOTTYPE_HITWORLD;
-		case WEP_CAMPINGRIFLE:
-			if(zoomscript_caught)
-				return EnemyHitCheck(view_origin, '0 0 0', '0 0 0', view_origin + view_forward * MAX_SHOT_DISTANCE);
-			break;
-		case WEP_ROCKET_LAUNCHER: // projectile has a size!
-			mi = '-3 -3 -3';
-			ma = '3 3 3';
-			break;
-		case WEP_SEEKER: // projectile has a size!
-			mi = '-2 -2 -2';
-			ma = '2 2 2';
-			break;
-		case WEP_ELECTRO: // projectile has a size!
-			mi = '0 0 -3';
-			ma = '0 0 -3';
-			break;
-	}
-
-	vecs = decompressShotOrigin(getstati(STAT_SHOTORG));
-
-	traceline(view_origin, view_origin + view_forward * MAX_SHOT_DISTANCE, MOVE_NOMONSTERS, trueaim);
-	trueaimpoint = trace_endpos;
-
-	if(vecs_x > 0)
-		vecs_y = -vecs_y;
-	else
-		vecs = '0 0 0';
-
-	dv = view_right * vecs_y + view_up * vecs_z;
-	w_shotorg = view_origin + dv;
-
-	// now move the vecs forward as much as requested if possible
-	tracebox(w_shotorg, mi, ma, w_shotorg + view_forward * (vecs_x + nudge), MOVE_NORMAL, trueaim); // FIXME this MOVE_NORMAL part will misbehave a little in csqc
-	w_shotorg = trace_endpos - view_forward * nudge;
-
-	shottype = EnemyHitCheck(w_shotorg, mi, ma, trueaimpoint);
-	if(shottype != SHOTTYPE_HITWORLD)
-		return shottype;
-
-	// now test whether we will actually hit the trueaimpoint...
-	tracebox(w_shotorg, mi, ma, trueaimpoint, MOVE_NOMONSTERS, trueaim);
-
-	if(vlen(trace_endpos - trueaimpoint) > vlen(ma - mi) + 1)
-		// yes, this is an ugly hack... but it seems good enough to find out whether the test hits the same place as the initial trace
-		return SHOTTYPE_HITOBSTRUCTION;
-	
-	return SHOTTYPE_HITWORLD;
-}
-
-void CSQC_common_hud(void);
-
-void CSQC_kh_hud(void);
-void CSQC_ctf_hud(void);
-void PostInit(void);
-void CSQC_Demo_Camera();
-float Sbar_WouldDrawScoreboard ();
-float view_set;
-float camera_mode;
-string NextFrameCommand;
-void CSQC_spider_HUD();
-void CSQC_UpdateView(float w, float h)
-{
-	entity e;
-	float fov;
-	float f, i, j;
-
-	dprint_load();
-	WaypointSprite_Load();
-
-	myteam = GetPlayerColor(player_localentnum - 1);
-
-	ticrate = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
-
-	// Render the Scene
-	if(!intermission || !view_set)
-	{
-		view_origin = pmove_org + '0 0 1' * getstati(STAT_VIEWHEIGHT);
-		view_angles = input_angles;
-		makevectors(view_angles);
-		view_forward = v_forward;
-		view_right = v_right;
-		view_up = v_up;
-		view_set = 1;
-	}
-
-	vid_width = w;
-	vid_height = h;
-
-#ifdef BLURTEST
-	if(time > blurtest_time0 && time < blurtest_time1)
-	{
-		float r, t;
-
-		t = (time - blurtest_time0) / (blurtest_time1 - blurtest_time0);
-		r = t * blurtest_radius;
-		f = 1 / pow(t, blurtest_power) - 1;
-
-		cvar_set("r_glsl_postprocess", "1");
-		cvar_set("r_glsl_postprocess_uservec1", strcat(ftos(r), " ", ftos(f), " 0 0"));
-	}
-	else
-	{
-		cvar_set("r_glsl_postprocess", "0");
-		cvar_set("r_glsl_postprocess_uservec1", "0 0 0 0");
-	}
-#endif
-
-	Fog_Force();
-
-	drawframetime = max(0.000001, time - drawtime);
-	drawtime = time;
-
-	// watch for gametype changes here...
-	// in ParseStuffCMD the cmd isn't executed yet :/
-	// might even be better to add the gametype to TE_CSQC_INIT...?
-	if(!postinit)
-		PostInit();
-
-	CheckForGamestartChange();
-	maptimeAnnouncer();
-
-	fov = cvar("fov");
-	if(button_zoom || fov <= 59.5)
-	{
-		if(!zoomscript_caught)
-		{
-			localcmd("+button4\n");
-			zoomscript_caught = 1;
-			ignore_plus_zoom += 1;
-		}
-	}
-	else
-	{
-		if(zoomscript_caught)
-		{
-			localcmd("-button4\n");
-			zoomscript_caught = 0;
-			ignore_minus_zoom += 1;
-		}
-	}
-
-	sbar_alpha_fg = cvar("sbar_alpha_fg" );
-	sbar_currentammo = cvar("sbar_showcurrentammo");
-	sbar_hudselector = cvar("sbar_hudselector");
-	sbar_hud_accuracy = cvar("sbar_hud_accuracy");
-	ColorTranslateMode = cvar("cl_stripcolorcodes");
-	activeweapon = getstati(STAT_SWITCHWEAPON);
-	f = cvar("teamplay");
-	if(f != teamplay)
-	{
-		teamplay = f;
-		Sbar_InitScores();
-	}
-
-	if(last_weapon != activeweapon) {
-		weapontime = time;
-		last_weapon = activeweapon;
-	}
-
-	// ALWAYS Clear Current Scene First
-	R_ClearScene();
-
-	// Assign Standard Viewflags
-	// Draw the World (and sky)
-	R_SetView(VF_DRAWWORLD, 1);
-
-	// Set the console size vars
-	vid_conwidth = cvar("vid_conwidth");
-	vid_conheight = cvar("vid_conheight");
-	vid_pixelheight = cvar("vid_pixelheight");
-
-	R_SetView(VF_FOV, GetCurrentFov(fov));
-
-	// Camera for demo playback
-	if(camera_active)
-	{
-		if(cvar("camera_enable"))
-			CSQC_Demo_Camera();
-		else
-		{
-			cvar_set("chase_active", ftos(chase_active_backup));
-			cvar_set("cl_demo_mousegrab", "0");
-			camera_active = FALSE;
-		}
-	}
-#ifdef CAMERATEST
-	else if(cvar("camera_enable"))
-#else
-	else if(cvar("camera_enable") && isdemo())
-#endif
-	{
-		// Enable required Darkplaces cvars
-		chase_active_backup = cvar("chase_active");
-		cvar_set("chase_active", "2");
-		cvar_set("cl_demo_mousegrab", "1");
-		camera_active = TRUE;
-		camera_mode = FALSE;
-	}
-
-	// Draw the Crosshair
-	float scoreboard_active;
-	scoreboard_active = Sbar_WouldDrawScoreboard();
-	R_SetView(VF_DRAWCROSSHAIR, 0); //Make sure engine crosshairs are always hidden
-
-	// Draw the Engine Status Bar (the default Quake HUD)
-	R_SetView(VF_DRAWENGINESBAR, 0);
-
-	// fetch this one only once per frame
-	sbar_showbinds = cvar("sbar_showbinds");
-	sbar_showbinds_limit = cvar("sbar_showbinds_limit");
-
-	// Update the mouse position
-	/*
-	mousepos_x = vid_conwidth;
-	mousepos_y = vid_conheight;
-	mousepos = mousepos*0.5 + getmousepos();
-	*/
-
-	R_AddEntities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);
-
-	e = self;
-	for(self = world; (self = nextent(self)); )
-		if(self.draw)
-			self.draw();
-	self = e;
-	R_RenderScene();
-
-	// now switch to 2D drawing mode by calling a 2D drawing function
-	// then polygon drawing will draw as 2D stuff, and NOT get queued until the
-	// next R_RenderScene call
-	drawstring('0 0 0', "", '1 1 0', '1 1 1', 0, 0);
-
-	// Draw the mouse cursor
-	// NOTE: drawpic must happen after R_RenderScene for some reason
-	//drawpic(getmousepos(), "gfx/cursor.tga", '11 14 0', '1 1 1', 1, 0);
-	//drawstring('50 50', ftos(game), '10 10 0', '1 1 1', 1, 0);
-	//self = edict_num(player_localnum);
-	//drawstring('0 0', vtos(pmove_org), '8 8 0', '1 1 1', 1, 0);
-	//drawstring('0 8', strcat("ORG: ", vtos(self.origin), " state: ", ftos(self.ctf_state), " HP: ", ftos(self.health)), '8 8 0', '1 1 1', 1, 0);
-	// as long as the ctf part isn't in, this is useless
-	if(menu_visible)
-		menu_show();
-
-	/*if(gametype == GAME_CTF)
-	{
-		ctf_view();
-	} else */
-
-	// draw 2D entities
-	e = self;
-	for(self = world; (self = nextent(self)); )
-		if(self.draw2d)
-			self.draw2d();
-	self = e;
-
-	// draw radar
-	if(
-		ons_showmap
-		||
-		(
-			!scoreboard_active
-			&&
-			cvar_string("cl_teamradar") != "0"
-			&&
-			(
-				cvar("cl_teamradar") == 2
-				||
-				teamplay
-			)
-		)
-	)
-		teamradar_view();
-
-	if (cvar("cl_showpressedkeys")) // draw pressed keys when spectating and playing
-	{
-		if(spectatee_status > 0 || cvar("cl_showpressedkeys") >= 2)
-			Sbar_DrawPressedKeys();
-	}
-	
-	if (cvar("cl_showspeed"))
-		Sbar_ShowSpeed();
-	
-	// draw sbar
- 	if(cvar("r_letterbox") == 0)
- 		Sbar_DrawCenterPrint(); // draw centerprint messages even if viewsize >= 120
-
-    float hud;
-    hud = getstati(STAT_HUD);
-    if(hud == HUD_SPIDEBOT)
-    {
-        vector sz;
-        CSQC_spider_HUD();
-        sz = drawgetimagesize(SPIDER_CROSS);
-        sz_x *= cvar_or("cl_vehicle_spiderbot_cross_size",1);
-        sz_y *= cvar_or("cl_vehicle_spiderbot_cross_size",1);
-        drawpic('0.5 0 0' * (vid_conwidth - sz_x) + '0 0.5 0' * (vid_conheight - sz_y), SPIDER_CROSS, sz, '1 1 1', cvar_or("cl_vehicle_spiderbot_cross_alpha",0.6), DRAWFLAG_NORMAL);
-    }
-    else
-    {
-        if(cvar("r_letterbox") == 0)
-            if(cvar("viewsize") < 120)
-                CSQC_common_hud();
-
-        // crosshair goes VERY LAST
-        if(!scoreboard_active && !ons_showmap && !camera_active) {
-            // TrueAim check
-            float shottype;
-
-            if(cvar("crosshair_hittest"))
-                shottype = TrueAimCheck();
-            else
-                shottype = SHOTTYPE_HITWORLD;
-
-            string wcross_style;
-            wcross_style = cvar_string("crosshair");
-
-            if (wcross_style != "0") {
-                vector wcross_color, wcross_size;
-                string wcross_wep, wcross_name;
-                float wcross_alpha, wcross_sizefloat;
-
-                wcross_color_x = cvar("crosshair_color_red");
-                wcross_color_y = cvar("crosshair_color_green");
-                wcross_color_z = cvar("crosshair_color_blue");
-                wcross_alpha = cvar("crosshair_color_alpha");
-                wcross_sizefloat = cvar("crosshair_size");
-                if (cvar("crosshair_per_weapon")) {
-                    e = get_weaponinfo(activeweapon);
-                    if (e && e.netname != "")
-                    {
-                        wcross_wep = e.netname;
-                        wcross_style = cvar_string(strcat("crosshair_", wcross_wep));
-                        if(wcross_style == "")
-                            wcross_style = e.netname;
-
-                        if(!cvar("crosshair_color_override"))
-                        {
-                            wcross_color_x = cvar(strcat("crosshair_", wcross_wep, "_color_red"));
-                            wcross_color_y = cvar(strcat("crosshair_", wcross_wep, "_color_green"));
-                            wcross_color_z = cvar(strcat("crosshair_", wcross_wep, "_color_blue"));
-                        }
-
-                        wcross_alpha *= cvar(strcat("crosshair_", wcross_wep, "_color_alpha"));
-                        wcross_sizefloat *= cvar(strcat("crosshair_", wcross_wep, "_size"));
-                    }
-                }
-
-                wcross_name = strcat("gfx/crosshair", wcross_style);
-
-				if(shottype == SHOTTYPE_HITENEMY)
-					wcross_sizefloat *= cvar("crosshair_hittest"); // is not queried if hittest is 0
-				if(shottype == SHOTTYPE_HITTEAM)
-					wcross_sizefloat /= cvar("crosshair_hittest"); // is not queried if hittest is 0
-
-                wcross_size = drawgetimagesize(wcross_name);
-                wcross_size_x *= wcross_sizefloat;
-                wcross_size_y *= wcross_sizefloat;
-
-                if(shottype == SHOTTYPE_HITENEMY || shottype == SHOTTYPE_HITWORLD)
-                {
-                    drawpic('0.5 0 0' * (vid_conwidth - wcross_size_x) + '0 0.5 0' * (vid_conheight - wcross_size_y), wcross_name, wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
-                }
-                else
-                {
-                    wcross_alpha *= 0.04 * 0.75;
-                    for(i = -2; i <= 2; ++i)
-                        for(j = -2; j <= 2; ++j)
-                            drawpic('0.5 0 0' * (vid_conwidth - wcross_size_x + i) + '0 0.5 0' * (vid_conheight - wcross_size_y + j), wcross_name, wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
-                }
-            }
-        }
-    }
-
-	if(NextFrameCommand)
-	{
-		localcmd("\n", NextFrameCommand, "\n");
-		NextFrameCommand = string_null;
-	}
-}
-
-void Sbar_Draw();
-void CSQC_spider_HUD()
-{
-    float rockets,reload,heat,hp,shield,i;
-    vector p,pp;
-
-    rockets = getstati(STAT_SPIDERBOT_ROCKETS);
-    heat    = min(getstatf(STAT_SPIDERBOT_HEAT),1);
-    reload  = min(getstatf(STAT_SPIDERBOT_RELOAD),1);
-    hp      = min(getstatf(STAT_SPIDERBOT_HEALTH),1);
-    shield  = min(getstatf(STAT_SPIDERBOT_SHIELD),1);
-
-    // Draw health bar
-    p = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));
-    p = p + '0 1 0' * vid_conheight - '0 32 0';
-    //pp = ('0 1 0' * hp) + ('1 0 0' * (1-hp));
-    drawfill(p, '256 0 0' * shield + '0 8 0' , '0.5 0.5 1', 0.75, DRAWFLAG_NORMAL);
-    p_y += 8;
-    drawfill(p, '256 0 0' * hp + '0 8 0' , '0 1 0', 0.75, DRAWFLAG_NORMAL);
-    p_x += 256 * hp;
-    drawfill(p, '256 0 0' * (1-hp) + '0 8 0' , '0 0 0', 0.75, DRAWFLAG_NORMAL);
-
-    // Draw minigun heat indicator
-    p = '0.5 0 0' * (vid_conwidth - 256);
-    p = p + '0 1 0' * vid_conheight - '0 34  0';
-    drawfill(p, '256 0 0' * (1-heat) + '0 2 0' ,'0 0 1', 0.5, DRAWFLAG_NORMAL);
-    p_x += 256 * (1-heat);
-    drawfill(p, '256 0 0' * heat  + '0 2 0' , '1 0 0', 0.5, DRAWFLAG_NORMAL);
-
-    // Draw rocket icons for loaded/empty tubes.
-    pp = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));
-    pp += '0 1 0' * vid_conheight - '0 64 0';
-    for(i = 0; i < 8; ++i)
-    {
-        p = pp + '1 0 0' * (rkt_size * i);
-        if(rockets == 8)
-        {
-            if(floor(reload * 8) == i)
-            {
-                drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '1 0 0' + '0 1 0' * ((reload*8)-i), 0.75 , DRAWFLAG_NORMAL);
-            }
-            else if(i < reload * 8)
-                drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '1 1 0', 0.75 , DRAWFLAG_NORMAL);
-            else
-                drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0.5 0.5 0.5', 0.75, DRAWFLAG_NORMAL);
-        }
-        else
-        {
-            if(i < rockets)
-                drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0 0 0', 0.25, DRAWFLAG_NORMAL);
-            else
-                drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0 1 0' * reload, 0.75, DRAWFLAG_NORMAL);
-        }
-    }
-
-	if (sb_showscores)
-	{
-		Sbar_DrawScoreboard();
-		Sbar_DrawCenterPrint();
-	}
-
-}
-void CSQC_common_hud(void)
-{
-
-	// Sbar_SortFrags(); done in Sbar_Draw
-    float hud;
-    hud = getstati(STAT_HUD);
-
-    //hud = 10;
-    switch(hud)
-    {
-        case HUD_NORMAL:
-            Sbar_Draw();
-            break;
-
-        case HUD_SPIDEBOT:
-            CSQC_spider_HUD();
-            break;
-    }
-}
-
-
-// following vectors must be global to allow seamless switching between camera modes
-vector camera_offset, current_camera_offset, mouse_angles, current_angles, current_origin, current_position;
-void CSQC_Demo_Camera()
-{
-	float speed, attenuation, dimensions;
-	vector tmp, delta;
-
-	if( cvar("camera_reset") || !camera_mode )
-	{
-		camera_offset = '0 0 0';
-		current_angles = '0 0 0';
-		camera_direction = '0 0 0';
-		camera_offset_z += 30;
-		camera_offset_x += 30 * -cos(current_angles_y * DEG2RAD);
-		camera_offset_y += 30 * -sin(current_angles_y * DEG2RAD);
-		current_origin = view_origin;
-		current_camera_offset  = camera_offset;
-		cvar_set("camera_reset", "0");
-		camera_mode = CAMERA_CHASE;
-	}
-
-	// Camera angles
-	if( camera_roll )
-		mouse_angles_z += camera_roll * cvar("camera_speed_roll");
-
-	if(cvar("camera_look_player"))
-	{
-		local vector dir;
-		local float n;
-
-		dir = normalize(view_origin - current_position);
-		n = mouse_angles_z;
-		mouse_angles = vectoangles(dir);
-		mouse_angles_x = mouse_angles_x * -1;
-		mouse_angles_z = n;
-	}
-	else
-	{
-		tmp = getmousepos() * 0.1;
-		if(vlen(tmp)>cvar("camera_mouse_treshold"))
-		{
-			mouse_angles_x += tmp_y * cos(mouse_angles_z * DEG2RAD) + (tmp_x * sin(mouse_angles_z * DEG2RAD));
-			mouse_angles_y -= tmp_x * cos(mouse_angles_z * DEG2RAD) + (tmp_y * -sin(mouse_angles_z * DEG2RAD));
-		}
-	}
-
-	while (mouse_angles_x < -180) mouse_angles_x = mouse_angles_x + 360;
-	while (mouse_angles_x > 180) mouse_angles_x = mouse_angles_x - 360;
-	while (mouse_angles_y < -180) mouse_angles_y = mouse_angles_y + 360;
-	while (mouse_angles_y > 180) mouse_angles_y = mouse_angles_y - 360;
-
-	// Fix difference when angles don't have the same sign
-	delta = '0 0 0';
-	if(mouse_angles_y < -60 && current_angles_y > 60)
-		delta = '0 360 0';
-	if(mouse_angles_y > 60 && current_angles_y < -60)
-		delta = '0 -360 0';
-
-	if(cvar("camera_look_player"))
-		attenuation = cvar("camera_look_attenuation");
-	else
-		attenuation = cvar("camera_speed_attenuation");
-
-	attenuation = 1 / max(1, attenuation);
-	current_angles += (mouse_angles - current_angles + delta) * attenuation;
-
-	while (current_angles_x < -180) current_angles_x = current_angles_x + 360;
-	while (current_angles_x > 180) current_angles_x = current_angles_x - 360;
-	while (current_angles_y < -180) current_angles_y = current_angles_y + 360;
-	while (current_angles_y > 180) current_angles_y = current_angles_y - 360;
-
-	// Camera position
-	tmp = '0 0 0';
-	dimensions = 0;
-
-	if( camera_direction_x )
-	{
-		tmp_x = camera_direction_x * cos(current_angles_y * DEG2RAD);
-		tmp_y = camera_direction_x * sin(current_angles_y * DEG2RAD);
-		if( cvar("camera_forward_follows") && !cvar("camera_look_player") )
-			tmp_z = camera_direction_x * -sin(current_angles_x * DEG2RAD);
-		++dimensions;
-	}
-
-	if( camera_direction_y )
-	{
-		tmp_x += camera_direction_y * -sin(current_angles_y * DEG2RAD);
-		tmp_y += camera_direction_y * cos(current_angles_y * DEG2RAD) * cos(current_angles_z * DEG2RAD);
-		tmp_z += camera_direction_y * sin(current_angles_z * DEG2RAD);
-		++dimensions;
-	}
-
-	if( camera_direction_z )
-	{
-		tmp_z += camera_direction_z * cos(current_angles_z * DEG2RAD);
-		++dimensions;
-	}
-
-	if(cvar("camera_free"))
-		speed = cvar("camera_speed_free");
-	else
-		speed = cvar("camera_speed_chase");
-
-	if(dimensions)
-	{
-		speed = speed * sqrt(1 / dimensions);
-		camera_offset += tmp * speed;
-	}
-
-	current_camera_offset += (camera_offset - current_camera_offset) * attenuation;
-
-	// Camera modes
-	if( cvar("camera_free") )
-	{
-		if ( camera_mode == CAMERA_CHASE )
-		{
-			current_camera_offset = current_origin + current_camera_offset;
-			camera_offset = current_origin + camera_offset;
-		}
-
-		camera_mode = CAMERA_FREE;
-		current_position = current_camera_offset;
-	}
-	else
-	{
-		if ( camera_mode == CAMERA_FREE )
-		{
-			current_origin = view_origin;
-			camera_offset = camera_offset - current_origin;
-			current_camera_offset = current_camera_offset - current_origin;
-		}
-
-		camera_mode = CAMERA_CHASE;
-
-		if(cvar("camera_chase_smoothly"))
-			current_origin += (view_origin - current_origin) * attenuation;
-		else
-			current_origin = view_origin;
-
-		current_position = current_origin + current_camera_offset;
-	}
-
-	R_SetView(VF_ANGLES, current_angles);
-	R_SetView(VF_ORIGIN, current_position);
-}
+#define spider_rocket_icon "gfx/spiderbot/rocket_ico.tga"
+#define spider_rocket_targ "gfx/spiderbot/target.tga"
+#define SPIDER_CROSS "textures/spiderbot/cross.tga"
+#define rkt_size 32
+#define rld_size_x 256
+#define rld_size_y 16
+
+entity porto;
+vector polyline[16];
+float trace_dphitcontents;
+float trace_networkentity;
+float Q3SURFACEFLAG_SLICK = 2; // low friction surface
+float DPCONTENTS_SOLID = 1; // blocks player movement
+float DPCONTENTS_BODY = 32; // blocks player movement
+float DPCONTENTS_CORPSE = 64; // blocks player movement
+float DPCONTENTS_PLAYERCLIP = 256; // blocks player movement
+void Porto_Draw()
+{
+	vector p, dir, ang, q, nextdir;
+	float idx, portal_number, portal1_idx;
+
+	if(activeweapon != WEP_PORTO || spectatee_status || gametype == GAME_NEXBALL)
+		return;
+	if(intermission == 1)
+		return;
+	if(intermission == 2)
+		return;
+	if (getstati(STAT_HEALTH) <= 0)
+		return;
+
+	dir = view_forward;
+
+	if(angles_held_status)
+	{
+		makevectors(angles_held);
+		dir = v_forward;
+	}
+
+	p = view_origin;
+
+	polyline[0] = p;
+	idx = 1;
+	portal_number = 0;
+	nextdir = dir;
+
+	for(;;)
+	{
+		dir = nextdir;
+		traceline(p, p + 65536 * dir, TRUE, porto);
+		if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
+			return;
+		nextdir = dir - 2 * (dir * trace_plane_normal) * trace_plane_normal; // mirror dir at trace_plane_normal
+		p = trace_endpos;
+		polyline[idx] = p;
+		++idx;
+		if(idx >= 16)
+			return;
+		if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP)
+			continue;
+		++portal_number;
+		ang = vectoangles2(trace_plane_normal, dir);
+		ang_x = -ang_x;
+		makevectors(ang);
+		if(!CheckWireframeBox(porto, p - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward))
+			return;
+		if(portal_number == 1)
+			portal1_idx = idx;
+		if(portal_number >= 2)
+			break;
+	}
+
+	while(idx >= 2)
+	{
+		p = polyline[idx-2];
+		q = polyline[idx-1];
+		if(idx == 2)
+			p = p - view_up * 16;
+		if(idx-1 >= portal1_idx)
+		{
+			Draw_CylindricLine(p, q, 4, "", 1, 0, '0 0 1', 0.5, DRAWFLAG_NORMAL);
+		}
+		else
+		{
+			Draw_CylindricLine(p, q, 4, "", 1, 0, '1 0 0', 0.5, DRAWFLAG_NORMAL);
+		}
+		--idx;
+	}
+}
+
+/**
+ * Checks whether the server initiated a map restart (stat_game_starttime changed)
+ *
+ * TODO: Use a better solution where a common shared entitiy is used that contains
+ * timelimit, fraglimit and game_starttime! Requires engine changes (remove STAT_TIMELIMIT
+ * and STAT_FRAGLIMIT to be auto-sent)
+ */
+void CheckForGamestartChange() {
+	float startTime;
+	startTime = getstatf(STAT_GAMESTARTTIME);
+	if (previous_game_starttime != startTime) {
+		if ((time + 5.0) < startTime) {
+			//if connecting to server while restart was active don't always play prepareforbattle
+			sound(self, CHAN_VOICE, "announcer/robotic/prepareforbattle.wav", VOL_BASEVOICE, ATTN_NONE);
+		}
+		if (time < startTime) {
+			restartAnnouncer = spawn();
+			restartAnnouncer.think = restartAnnouncer_Think;
+			restartAnnouncer.nextthink = startTime - floor(startTime - time); //synchronize nextthink to startTime
+		}
+	}
+	previous_game_starttime = startTime;
+}
+
+void Porto_Init()
+{
+	porto = spawn();
+	porto.classname = "porto";
+	porto.draw = Porto_Draw;
+	porto.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
+}
+
+float drawtime;
+
+float tan(float x)
+{
+	return sin(x) / cos(x);
+}
+float atan2(float y, float x)
+{
+	vector v;
+	v = '1 0 0' * x + '0 1 0' * y;
+	v = vectoangles(v);
+	return v_y * 0.01745329251994329576;
+}
+
+vector GetCurrentFov(float fov)
+{
+	float zoomsensitivity, zoomspeed, zoomfactor, zoomdir;
+
+	zoomsensitivity = cvar("cl_zoomsensitivity");
+	zoomfactor = cvar("cl_zoomfactor");
+	if(zoomfactor < 1 || zoomfactor > 16)
+		zoomfactor = 2.5;
+	zoomspeed = cvar("cl_zoomspeed");
+	if(zoomspeed >= 0)
+		if(zoomspeed < 0.5 || zoomspeed > 16)
+			zoomspeed = 3.5;
+
+	zoomdir = button_zoom;
+	if(getstati(STAT_ACTIVEWEAPON) == WEP_NEX) // do NOT use switchweapon here
+		zoomdir += button_attack2;
+	if(spectatee_status > 0 || isdemo())
+	{
+		if(spectatorbutton_zoom)
+			zoomdir = 0 + !zoomdir;
+			// do not even THINK about removing this 0
+			// _I_ know what I am doing
+			// fteqcc does not
+	}
+
+	if(zoomdir)
+		zoomin_effect = 0;
+
+	if(zoomin_effect || camera_active)
+	{
+		current_viewzoom = min(1, current_viewzoom + drawframetime);
+	}
+	else
+	{
+		if(zoomspeed < 0) // instant zoom
+		{
+			if(zoomdir)
+				current_viewzoom = 1 / zoomfactor;
+			else
+				current_viewzoom = 1;
+		}
+		else
+		{
+			if(zoomdir)
+				current_viewzoom = 1 / bound(1, 1 / current_viewzoom + drawframetime * zoomspeed * (zoomfactor - 1), zoomfactor);
+			else
+				current_viewzoom = bound(1 / zoomfactor, current_viewzoom + drawframetime * zoomspeed * (1 - 1 / zoomfactor), 1);
+		}
+	}
+
+	if(almost_equals(current_viewzoom, 1))
+		current_zoomfraction = 0;
+	else if(almost_equals(current_viewzoom, 1/zoomfactor))
+		current_zoomfraction = 1;
+	else
+		current_zoomfraction = (current_viewzoom - 1) / (1/zoomfactor - 1);
+
+	if(zoomsensitivity < 1)
+		setsensitivityscale(pow(current_viewzoom, 1 - zoomsensitivity));
+	else
+		setsensitivityscale(1);
+
+	float frustumx, frustumy, fovx, fovy;
+	frustumy = tan(fov * 0.00872664625997164788) * 0.75 * current_viewzoom;
+	frustumx = frustumy * vid_width / vid_height / vid_pixelheight;
+	fovx = atan2(frustumx, 1) / 0.00872664625997164788;
+	fovy = atan2(frustumy, 1) / 0.00872664625997164788;
+
+	return '1 0 0' * fovx + '0 1 0' * fovy;
+}
+
+// this function must match W_SetupShot!
+float zoomscript_caught;
+entity trueaim;
+
+#define SHOTTYPE_HITTEAM 1
+#define SHOTTYPE_HITOBSTRUCTION 2
+#define SHOTTYPE_HITWORLD 3
+#define SHOTTYPE_HITENEMY 4
+
+void TrueAim_Init()
+{
+	trueaim = spawn();
+	trueaim.classname = "trueaim";
+	trueaim.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
+}
+
+float EnemyHitCheck(vector start, vector mi, vector ma, vector end)
+{
+	float t;
+	tracebox(start, mi, ma, end, MOVE_NORMAL, trueaim);
+	if(trace_networkentity < 1)
+		return SHOTTYPE_HITWORLD;
+	if(trace_networkentity > maxclients)
+		return SHOTTYPE_HITWORLD;
+	t = GetPlayerColor(trace_networkentity - 1);
+	if(teamplay)
+	if(t == myteam)
+		return SHOTTYPE_HITTEAM;
+	if(t == COLOR_SPECTATOR)
+		return SHOTTYPE_HITWORLD;
+	return SHOTTYPE_HITENEMY;
+}
+
+float TrueAimCheck()
+{
+	float nudge = 1; // added to traceline target and subtracted from result
+	vector vecs, trueaimpoint, w_shotorg;
+	vector mi, ma, dv;
+	float shottype;
+
+	mi = ma = '0 0 0';
+
+	switch(activeweapon)
+	{
+		case WEP_TUBA: // no aim
+		case WEP_PORTO: // shoots from eye
+		case WEP_HOOK: // no trueaim
+		case WEP_GRENADE_LAUNCHER: // toss curve
+			return SHOTTYPE_HITWORLD;
+		case WEP_CAMPINGRIFLE:
+			if(zoomscript_caught)
+				return EnemyHitCheck(view_origin, '0 0 0', '0 0 0', view_origin + view_forward * MAX_SHOT_DISTANCE);
+			break;
+		case WEP_ROCKET_LAUNCHER: // projectile has a size!
+			mi = '-3 -3 -3';
+			ma = '3 3 3';
+			break;
+		case WEP_SEEKER: // projectile has a size!
+			mi = '-2 -2 -2';
+			ma = '2 2 2';
+			break;
+		case WEP_ELECTRO: // projectile has a size!
+			mi = '0 0 -3';
+			ma = '0 0 -3';
+			break;
+	}
+
+	vecs = decompressShotOrigin(getstati(STAT_SHOTORG));
+
+	traceline(view_origin, view_origin + view_forward * MAX_SHOT_DISTANCE, MOVE_NOMONSTERS, trueaim);
+	trueaimpoint = trace_endpos;
+
+	if(vecs_x > 0)
+		vecs_y = -vecs_y;
+	else
+		vecs = '0 0 0';
+
+	dv = view_right * vecs_y + view_up * vecs_z;
+	w_shotorg = view_origin + dv;
+
+	// now move the vecs forward as much as requested if possible
+	tracebox(w_shotorg, mi, ma, w_shotorg + view_forward * (vecs_x + nudge), MOVE_NORMAL, trueaim); // FIXME this MOVE_NORMAL part will misbehave a little in csqc
+	w_shotorg = trace_endpos - view_forward * nudge;
+
+	shottype = EnemyHitCheck(w_shotorg, mi, ma, trueaimpoint);
+	if(shottype != SHOTTYPE_HITWORLD)
+		return shottype;
+
+	// now test whether we will actually hit the trueaimpoint...
+	tracebox(w_shotorg, mi, ma, trueaimpoint, MOVE_NOMONSTERS, trueaim);
+
+	if(vlen(trace_endpos - trueaimpoint) > vlen(ma - mi) + 1)
+		// yes, this is an ugly hack... but it seems good enough to find out whether the test hits the same place as the initial trace
+		return SHOTTYPE_HITOBSTRUCTION;
+	
+	return SHOTTYPE_HITWORLD;
+}
+
+void CSQC_common_hud(void);
+
+void CSQC_kh_hud(void);
+void CSQC_ctf_hud(void);
+void PostInit(void);
+void CSQC_Demo_Camera();
+float Sbar_WouldDrawScoreboard ();
+float view_set;
+float camera_mode;
+string NextFrameCommand;
+void CSQC_spider_HUD();
+void CSQC_UpdateView(float w, float h)
+{
+	entity e;
+	float fov;
+	float f, i, j;
+
+	dprint_load();
+	WaypointSprite_Load();
+
+	myteam = GetPlayerColor(player_localentnum - 1);
+
+	ticrate = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
+
+	// Render the Scene
+	if(!intermission || !view_set)
+	{
+		view_origin = pmove_org + '0 0 1' * getstati(STAT_VIEWHEIGHT);
+		view_angles = input_angles;
+		makevectors(view_angles);
+		view_forward = v_forward;
+		view_right = v_right;
+		view_up = v_up;
+		view_set = 1;
+	}
+
+	vid_width = w;
+	vid_height = h;
+
+#ifdef BLURTEST
+	if(time > blurtest_time0 && time < blurtest_time1)
+	{
+		float r, t;
+
+		t = (time - blurtest_time0) / (blurtest_time1 - blurtest_time0);
+		r = t * blurtest_radius;
+		f = 1 / pow(t, blurtest_power) - 1;
+
+		cvar_set("r_glsl_postprocess", "1");
+		cvar_set("r_glsl_postprocess_uservec1", strcat(ftos(r), " ", ftos(f), " 0 0"));
+	}
+	else
+	{
+		cvar_set("r_glsl_postprocess", "0");
+		cvar_set("r_glsl_postprocess_uservec1", "0 0 0 0");
+	}
+#endif
+
+	Fog_Force();
+
+	drawframetime = max(0.000001, time - drawtime);
+	drawtime = time;
+
+	// watch for gametype changes here...
+	// in ParseStuffCMD the cmd isn't executed yet :/
+	// might even be better to add the gametype to TE_CSQC_INIT...?
+	if(!postinit)
+		PostInit();
+
+	CheckForGamestartChange();
+	maptimeAnnouncer();
+
+	fov = cvar("fov");
+	if(button_zoom || fov <= 59.5)
+	{
+		if(!zoomscript_caught)
+		{
+			localcmd("+button4\n");
+			zoomscript_caught = 1;
+			ignore_plus_zoom += 1;
+		}
+	}
+	else
+	{
+		if(zoomscript_caught)
+		{
+			localcmd("-button4\n");
+			zoomscript_caught = 0;
+			ignore_minus_zoom += 1;
+		}
+	}
+
+	sbar_alpha_fg = cvar("sbar_alpha_fg" );
+	sbar_currentammo = cvar("sbar_showcurrentammo");
+	sbar_hudselector = cvar("sbar_hudselector");
+	sbar_hud_accuracy = cvar("sbar_hud_accuracy");
+	ColorTranslateMode = cvar("cl_stripcolorcodes");
+	activeweapon = getstati(STAT_SWITCHWEAPON);
+	f = cvar("teamplay");
+	if(f != teamplay)
+	{
+		teamplay = f;
+		Sbar_InitScores();
+	}
+
+	if(last_weapon != activeweapon) {
+		weapontime = time;
+		last_weapon = activeweapon;
+	}
+
+	// ALWAYS Clear Current Scene First
+	R_ClearScene();
+
+	// Assign Standard Viewflags
+	// Draw the World (and sky)
+	R_SetView(VF_DRAWWORLD, 1);
+
+	// Set the console size vars
+	vid_conwidth = cvar("vid_conwidth");
+	vid_conheight = cvar("vid_conheight");
+	vid_pixelheight = cvar("vid_pixelheight");
+
+	R_SetView(VF_FOV, GetCurrentFov(fov));
+
+	// Camera for demo playback
+	if(camera_active)
+	{
+		if(cvar("camera_enable"))
+			CSQC_Demo_Camera();
+		else
+		{
+			cvar_set("chase_active", ftos(chase_active_backup));
+			cvar_set("cl_demo_mousegrab", "0");
+			camera_active = FALSE;
+		}
+	}
+#ifdef CAMERATEST
+	else if(cvar("camera_enable"))
+#else
+	else if(cvar("camera_enable") && isdemo())
+#endif
+	{
+		// Enable required Darkplaces cvars
+		chase_active_backup = cvar("chase_active");
+		cvar_set("chase_active", "2");
+		cvar_set("cl_demo_mousegrab", "1");
+		camera_active = TRUE;
+		camera_mode = FALSE;
+	}
+
+	// Draw the Crosshair
+	float scoreboard_active;
+	scoreboard_active = Sbar_WouldDrawScoreboard();
+	R_SetView(VF_DRAWCROSSHAIR, 0); //Make sure engine crosshairs are always hidden
+
+	// Draw the Engine Status Bar (the default Quake HUD)
+	R_SetView(VF_DRAWENGINESBAR, 0);
+
+	// fetch this one only once per frame
+	sbar_showbinds = cvar("sbar_showbinds");
+	sbar_showbinds_limit = cvar("sbar_showbinds_limit");
+
+	// Update the mouse position
+	/*
+	mousepos_x = vid_conwidth;
+	mousepos_y = vid_conheight;
+	mousepos = mousepos*0.5 + getmousepos();
+	*/
+
+	R_AddEntities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);
+
+	e = self;
+	for(self = world; (self = nextent(self)); )
+		if(self.draw)
+			self.draw();
+	self = e;
+	R_RenderScene();
+
+	// now switch to 2D drawing mode by calling a 2D drawing function
+	// then polygon drawing will draw as 2D stuff, and NOT get queued until the
+	// next R_RenderScene call
+	drawstring('0 0 0', "", '1 1 0', '1 1 1', 0, 0);
+
+	// Draw the mouse cursor
+	// NOTE: drawpic must happen after R_RenderScene for some reason
+	//drawpic(getmousepos(), "gfx/cursor.tga", '11 14 0', '1 1 1', 1, 0);
+	//drawstring('50 50', ftos(game), '10 10 0', '1 1 1', 1, 0);
+	//self = edict_num(player_localnum);
+	//drawstring('0 0', vtos(pmove_org), '8 8 0', '1 1 1', 1, 0);
+	//drawstring('0 8', strcat("ORG: ", vtos(self.origin), " state: ", ftos(self.ctf_state), " HP: ", ftos(self.health)), '8 8 0', '1 1 1', 1, 0);
+	// as long as the ctf part isn't in, this is useless
+	if(menu_visible)
+		menu_show();
+
+	/*if(gametype == GAME_CTF)
+	{
+		ctf_view();
+	} else */
+
+	// draw 2D entities
+	e = self;
+	for(self = world; (self = nextent(self)); )
+		if(self.draw2d)
+			self.draw2d();
+	self = e;
+
+	// draw radar
+	if(
+		ons_showmap
+		||
+		(
+			!scoreboard_active
+			&&
+			cvar_string("cl_teamradar") != "0"
+			&&
+			(
+				cvar("cl_teamradar") == 2
+				||
+				teamplay
+			)
+		)
+	)
+		teamradar_view();
+
+	if (cvar("cl_showpressedkeys")) // draw pressed keys when spectating and playing
+	{
+		if(spectatee_status > 0 || cvar("cl_showpressedkeys") >= 2)
+			Sbar_DrawPressedKeys();
+	}
+	
+	if (cvar("cl_showspeed"))
+		Sbar_ShowSpeed();
+	
+	// draw sbar
+ 	if(cvar("r_letterbox") == 0)
+ 		Sbar_DrawCenterPrint(); // draw centerprint messages even if viewsize >= 120
+
+    float hud;
+    hud = getstati(STAT_HUD);
+    if(hud == HUD_SPIDEBOT)
+    {
+        vector sz;
+        CSQC_spider_HUD();
+        sz = drawgetimagesize(SPIDER_CROSS);
+        sz_x *= cvar_or("cl_vehicle_spiderbot_cross_size",1);
+        sz_y *= cvar_or("cl_vehicle_spiderbot_cross_size",1);
+        drawpic('0.5 0 0' * (vid_conwidth - sz_x) + '0 0.5 0' * (vid_conheight - sz_y), SPIDER_CROSS, sz, '1 1 1', cvar_or("cl_vehicle_spiderbot_cross_alpha",0.6), DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        if(cvar("r_letterbox") == 0)
+            if(cvar("viewsize") < 120)
+                CSQC_common_hud();
+
+        // crosshair goes VERY LAST
+        if(!scoreboard_active && !ons_showmap && !camera_active) {
+            // TrueAim check
+            float shottype;
+
+            if(cvar("crosshair_hittest"))
+                shottype = TrueAimCheck();
+            else
+                shottype = SHOTTYPE_HITWORLD;
+
+            string wcross_style;
+            wcross_style = cvar_string("crosshair");
+
+            if (wcross_style != "0") {
+                vector wcross_color, wcross_size;
+                string wcross_wep, wcross_name;
+                float wcross_alpha, wcross_sizefloat;
+
+                wcross_color_x = cvar("crosshair_color_red");
+                wcross_color_y = cvar("crosshair_color_green");
+                wcross_color_z = cvar("crosshair_color_blue");
+                wcross_alpha = cvar("crosshair_color_alpha");
+                wcross_sizefloat = cvar("crosshair_size");
+                if (cvar("crosshair_per_weapon")) {
+                    e = get_weaponinfo(activeweapon);
+                    if (e && e.netname != "")
+                    {
+                        wcross_wep = e.netname;
+                        wcross_style = cvar_string(strcat("crosshair_", wcross_wep));
+                        if(wcross_style == "")
+                            wcross_style = e.netname;
+
+                        if(!cvar("crosshair_color_override"))
+                        {
+                            wcross_color_x = cvar(strcat("crosshair_", wcross_wep, "_color_red"));
+                            wcross_color_y = cvar(strcat("crosshair_", wcross_wep, "_color_green"));
+                            wcross_color_z = cvar(strcat("crosshair_", wcross_wep, "_color_blue"));
+                        }
+
+                        wcross_alpha *= cvar(strcat("crosshair_", wcross_wep, "_color_alpha"));
+                        wcross_sizefloat *= cvar(strcat("crosshair_", wcross_wep, "_size"));
+                    }
+                }
+
+                wcross_name = strcat("gfx/crosshair", wcross_style);
+
+				if(shottype == SHOTTYPE_HITENEMY)
+					wcross_sizefloat *= cvar("crosshair_hittest"); // is not queried if hittest is 0
+				if(shottype == SHOTTYPE_HITTEAM)
+					wcross_sizefloat /= cvar("crosshair_hittest"); // is not queried if hittest is 0
+
+                wcross_size = drawgetimagesize(wcross_name);
+                wcross_size_x *= wcross_sizefloat;
+                wcross_size_y *= wcross_sizefloat;
+
+                if(shottype == SHOTTYPE_HITENEMY || shottype == SHOTTYPE_HITWORLD)
+                {
+                    drawpic('0.5 0 0' * (vid_conwidth - wcross_size_x) + '0 0.5 0' * (vid_conheight - wcross_size_y), wcross_name, wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
+                }
+                else
+                {
+                    wcross_alpha *= 0.04 * 0.75;
+                    for(i = -2; i <= 2; ++i)
+                        for(j = -2; j <= 2; ++j)
+                            drawpic('0.5 0 0' * (vid_conwidth - wcross_size_x + i) + '0 0.5 0' * (vid_conheight - wcross_size_y + j), wcross_name, wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL);
+                }
+            }
+        }
+    }
+
+	if(NextFrameCommand)
+	{
+		localcmd("\n", NextFrameCommand, "\n");
+		NextFrameCommand = string_null;
+	}
+}
+
+void Sbar_Draw();
+void CSQC_spider_HUD()
+{
+    float rockets,reload,heat,hp,shield,i;
+    vector p,pp;
+
+    rockets = getstati(STAT_SPIDERBOT_ROCKETS);
+    heat    = min(getstatf(STAT_SPIDERBOT_HEAT),1);
+    reload  = min(getstatf(STAT_SPIDERBOT_RELOAD),1);
+    hp      = min(getstatf(STAT_SPIDERBOT_HEALTH),1);
+    shield  = min(getstatf(STAT_SPIDERBOT_SHIELD),1);
+
+    // Draw health bar
+    p = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));
+    p = p + '0 1 0' * vid_conheight - '0 32 0';
+    //pp = ('0 1 0' * hp) + ('1 0 0' * (1-hp));
+    drawfill(p, '256 0 0' * shield + '0 8 0' , '0.5 0.5 1', 0.75, DRAWFLAG_NORMAL);
+    p_y += 8;
+    drawfill(p, '256 0 0' * hp + '0 8 0' , '0 1 0', 0.75, DRAWFLAG_NORMAL);
+    p_x += 256 * hp;
+    drawfill(p, '256 0 0' * (1-hp) + '0 8 0' , '0 0 0', 0.75, DRAWFLAG_NORMAL);
+
+    // Draw minigun heat indicator
+    p = '0.5 0 0' * (vid_conwidth - 256);
+    p = p + '0 1 0' * vid_conheight - '0 34  0';
+    drawfill(p, '256 0 0' * (1-heat) + '0 2 0' ,'0 0 1', 0.5, DRAWFLAG_NORMAL);
+    p_x += 256 * (1-heat);
+    drawfill(p, '256 0 0' * heat  + '0 2 0' , '1 0 0', 0.5, DRAWFLAG_NORMAL);
+
+    // Draw rocket icons for loaded/empty tubes.
+    pp = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));
+    pp += '0 1 0' * vid_conheight - '0 64 0';
+    for(i = 0; i < 8; ++i)
+    {
+        p = pp + '1 0 0' * (rkt_size * i);
+        if(rockets == 8)
+        {
+            if(floor(reload * 8) == i)
+            {
+                drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '1 0 0' + '0 1 0' * ((reload*8)-i), 0.75 , DRAWFLAG_NORMAL);
+            }
+            else if(i < reload * 8)
+                drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '1 1 0', 0.75 , DRAWFLAG_NORMAL);
+            else
+                drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0.5 0.5 0.5', 0.75, DRAWFLAG_NORMAL);
+        }
+        else
+        {
+            if(i < rockets)
+                drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0 0 0', 0.25, DRAWFLAG_NORMAL);
+            else
+                drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0 1 0' * reload, 0.75, DRAWFLAG_NORMAL);
+        }
+    }
+
+	if (sb_showscores)
+	{
+		Sbar_DrawScoreboard();
+		Sbar_DrawCenterPrint();
+	}
+
+}
+void CSQC_common_hud(void)
+{
+
+	// Sbar_SortFrags(); done in Sbar_Draw
+    float hud;
+    hud = getstati(STAT_HUD);
+
+    //hud = 10;
+    switch(hud)
+    {
+        case HUD_NORMAL:
+            Sbar_Draw();
+            break;
+
+        case HUD_SPIDEBOT:
+            CSQC_spider_HUD();
+            break;
+    }
+}
+
+
+// following vectors must be global to allow seamless switching between camera modes
+vector camera_offset, current_camera_offset, mouse_angles, current_angles, current_origin, current_position;
+void CSQC_Demo_Camera()
+{
+	float speed, attenuation, dimensions;
+	vector tmp, delta;
+
+	if( cvar("camera_reset") || !camera_mode )
+	{
+		camera_offset = '0 0 0';
+		current_angles = '0 0 0';
+		camera_direction = '0 0 0';
+		camera_offset_z += 30;
+		camera_offset_x += 30 * -cos(current_angles_y * DEG2RAD);
+		camera_offset_y += 30 * -sin(current_angles_y * DEG2RAD);
+		current_origin = view_origin;
+		current_camera_offset  = camera_offset;
+		cvar_set("camera_reset", "0");
+		camera_mode = CAMERA_CHASE;
+	}
+
+	// Camera angles
+	if( camera_roll )
+		mouse_angles_z += camera_roll * cvar("camera_speed_roll");
+
+	if(cvar("camera_look_player"))
+	{
+		local vector dir;
+		local float n;
+
+		dir = normalize(view_origin - current_position);
+		n = mouse_angles_z;
+		mouse_angles = vectoangles(dir);
+		mouse_angles_x = mouse_angles_x * -1;
+		mouse_angles_z = n;
+	}
+	else
+	{
+		tmp = getmousepos() * 0.1;
+		if(vlen(tmp)>cvar("camera_mouse_treshold"))
+		{
+			mouse_angles_x += tmp_y * cos(mouse_angles_z * DEG2RAD) + (tmp_x * sin(mouse_angles_z * DEG2RAD));
+			mouse_angles_y -= tmp_x * cos(mouse_angles_z * DEG2RAD) + (tmp_y * -sin(mouse_angles_z * DEG2RAD));
+		}
+	}
+
+	while (mouse_angles_x < -180) mouse_angles_x = mouse_angles_x + 360;
+	while (mouse_angles_x > 180) mouse_angles_x = mouse_angles_x - 360;
+	while (mouse_angles_y < -180) mouse_angles_y = mouse_angles_y + 360;
+	while (mouse_angles_y > 180) mouse_angles_y = mouse_angles_y - 360;
+
+	// Fix difference when angles don't have the same sign
+	delta = '0 0 0';
+	if(mouse_angles_y < -60 && current_angles_y > 60)
+		delta = '0 360 0';
+	if(mouse_angles_y > 60 && current_angles_y < -60)
+		delta = '0 -360 0';
+
+	if(cvar("camera_look_player"))
+		attenuation = cvar("camera_look_attenuation");
+	else
+		attenuation = cvar("camera_speed_attenuation");
+
+	attenuation = 1 / max(1, attenuation);
+	current_angles += (mouse_angles - current_angles + delta) * attenuation;
+
+	while (current_angles_x < -180) current_angles_x = current_angles_x + 360;
+	while (current_angles_x > 180) current_angles_x = current_angles_x - 360;
+	while (current_angles_y < -180) current_angles_y = current_angles_y + 360;
+	while (current_angles_y > 180) current_angles_y = current_angles_y - 360;
+
+	// Camera position
+	tmp = '0 0 0';
+	dimensions = 0;
+
+	if( camera_direction_x )
+	{
+		tmp_x = camera_direction_x * cos(current_angles_y * DEG2RAD);
+		tmp_y = camera_direction_x * sin(current_angles_y * DEG2RAD);
+		if( cvar("camera_forward_follows") && !cvar("camera_look_player") )
+			tmp_z = camera_direction_x * -sin(current_angles_x * DEG2RAD);
+		++dimensions;
+	}
+
+	if( camera_direction_y )
+	{
+		tmp_x += camera_direction_y * -sin(current_angles_y * DEG2RAD);
+		tmp_y += camera_direction_y * cos(current_angles_y * DEG2RAD) * cos(current_angles_z * DEG2RAD);
+		tmp_z += camera_direction_y * sin(current_angles_z * DEG2RAD);
+		++dimensions;
+	}
+
+	if( camera_direction_z )
+	{
+		tmp_z += camera_direction_z * cos(current_angles_z * DEG2RAD);
+		++dimensions;
+	}
+
+	if(cvar("camera_free"))
+		speed = cvar("camera_speed_free");
+	else
+		speed = cvar("camera_speed_chase");
+
+	if(dimensions)
+	{
+		speed = speed * sqrt(1 / dimensions);
+		camera_offset += tmp * speed;
+	}
+
+	current_camera_offset += (camera_offset - current_camera_offset) * attenuation;
+
+	// Camera modes
+	if( cvar("camera_free") )
+	{
+		if ( camera_mode == CAMERA_CHASE )
+		{
+			current_camera_offset = current_origin + current_camera_offset;
+			camera_offset = current_origin + camera_offset;
+		}
+
+		camera_mode = CAMERA_FREE;
+		current_position = current_camera_offset;
+	}
+	else
+	{
+		if ( camera_mode == CAMERA_FREE )
+		{
+			current_origin = view_origin;
+			camera_offset = camera_offset - current_origin;
+			current_camera_offset = current_camera_offset - current_origin;
+		}
+
+		camera_mode = CAMERA_CHASE;
+
+		if(cvar("camera_chase_smoothly"))
+			current_origin += (view_origin - current_origin) * attenuation;
+		else
+			current_origin = view_origin;
+
+		current_position = current_origin + current_camera_offset;
+	}
+
+	R_SetView(VF_ANGLES, current_angles);
+	R_SetView(VF_ORIGIN, current_position);
+}


Property changes on: trunk/data/qcsrc/client/View.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/bgmscript.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/bgmscript.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/casings.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/client/csqc_builtins.qc
===================================================================
--- trunk/data/qcsrc/client/csqc_builtins.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/client/csqc_builtins.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,287 +1,287 @@
-void (vector ang)							makevectors = #1;
-void(entity e, vector o) setorigin	= #2;
-void (entity e, string m)						setmodel = #3;
-void(entity e, vector min, vector max) setsize = #4;
-
-void ()									break = #6;
-float ()								random = #7;
-void (entity e, float chan, string samp, float vol, float atten)	sound = #8;
-vector (vector v)							normalize = #9;
-void (string e)								error = #10;
-void (string e)								objerror = #11;
-float (vector v)							vlen = #12;
-float (vector v)							vectoyaw = #13;
-entity ()								spawn = #14;
-void (entity e)								remove = #15;
-
-void (vector v1, vector v2, float nomonsters, entity forent)		traceline = #16;
-
-entity (entity start, .string fld, string match)			find = #18;
-string (string s)							precache_sound = #19;
-string (string s)							precache_model = #20;
-
-//void (string s)								dprint = #25;
-string (float f)							ftos = #26;
-string (vector v)							vtos = #27;
-void ()									coredump = #28;
-void ()									traceon = #29;
-void ()									traceoff = #30;
-void (entity e)								eprint = #31;
-
-float (float v)								rint = #36;
-float (float v)								floor = #37;
-float (float v)								ceil = #38;
-
-float (vector v)							pointcontents = #41;
-float (float f)								fabs = #43;
-
-float (string s)							cvar = #45;
-void (string s, ...)							localcmd = #46;
-entity (entity e)							nextent = #47;
-
-vector (vector v)							vectoangles = #51;
-vector (vector v, vector w)							vectoangles2 = #51;
-
-void (string var, string val)						cvar_set = #72;
-
-
-float()									ReadByte = #360;
-float()									ReadChar = #361;
-float()									ReadShort = #362;
-float()									ReadLong = #363;
-float()									ReadCoord = #364;
-float()									ReadAngle = #365;
-string()								ReadString = #366;	//warning: this returns a temporary!
-
-float(string s)								stof = #81;
-
-
-void (vector v1, vector min, vector max, vector v2, float nomonsters, entity forent)	tracebox = #90;
-float (string name, string value, ...)					registercvar = #93;
-
-entity (entity start, .entity fld, entity match)			findentity = #98;
-entity (entity start, .float fld, float match)				findfloat = #98;
-
-float (string s)							checkextension = #99;
-
-float (string filename, float mode)					fopen = #110;
-void (float fhandle)							fclose = #111;
-string (float fhandle)							fgets = #112;
-void (float fhandle, string s)						fputs = #113;
-float (string s)							strlen = #114;
-string (...)								strcat = #115;
-string (string s, float start, float length)				substring = #116;
-vector (string s)							stov = #117;
-string (string s)							strzone = #118;
-void (string s)								strunzone = #119;
-
-void ()									R_ClearScene = #300;
-void (float mask)							R_AddEntities = #301;
-void (entity e)								R_AddEntity = #302;
-float (float property, ...)						R_SetView = #303;
-void ()									R_RenderScene = #304;
-void (vector org, float radius, vector rgb)				R_AddDynamicLight = #305;
-void ()									R_CalcRefDef = #306;
-
-vector (vector v)							cs_unproject = #310;
-vector (vector v)							cs_project = #311;
-
-void	drawline(float width, vector pos1, vector pos2, vector rgb, float alpha, float flags) = #315;
-float	iscachedpic(string name)	= #316;
-string	precache_pic(string name, ...)	= #317;
-vector	drawgetimagesize(string pic) = #318;
-void	freepic(string name)		= #319;
-float	drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag) = #320;
-float	drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #321;
-float	drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) = #322;
-float	drawfill(vector position, vector size, vector rgb, float alpha, float flag) = #323;
-void	drawsetcliparea(float x, float y, float width, float height) = #324;
-void	drawresetcliparea(void) = #325;
-float	drawcolorcodedstring(vector position, string text, vector scale, float alpha, float flag) = #326;
-float	stringwidth(string text, float handleColors) = #327;
-float	drawsubpic(vector position, vector size, string pic, vector srcPosition, vector srcSize, vector rgb, float alpha, float flag) = #328;
-
-
-float (float statnum)							getstatf = #330;
-float (float statnum)							getstati = #331;
-string (float statnum)							getstats = #332;
-
-void (entity e, float i)						setmodelindex = #333;
-string (float i)							modelnameforindex = #334;
-
-float(string efname)							particleeffectnum = #335;
-void(entity ent, float effectnum, vector start, vector end, ...)	trailparticles = #336;
-void (float efnum, vector org, vector vel, float countmultiplier, ...)	pointparticles = #337;
-
-void (string s, ...)							cprint = #338;
-void (string s, ...)							print = #339;
-
-void (float scale)							setsensitivityscale = #346;
-
-
-void (float framenum)							RetrieveMovementFrame = #345;
-void ()									DefaultPlayerPhysics = #347;
-
-string (float playernum, string key)					getplayerkey = #348;
-void (string cmdname)							registercmd = #352;
-vector ()								getmousepos = #344;
-
-string (string s) 							uncolorstring = #170;
-
-void (vector org, vector forward, vector right, vector up)		setlistener = #351;
-
-float (vector start, vector end, float ignore, float csqcents)		selecttraceline = #355;
-float ()								isdemo = #349;
-float ()								isserver = #350;
-
-void (float f)								setwantsmousemove = #343;
-string (float key)							getkeybind = #342;
-//string (float f)							chr = #78;
-string (float f)							chr = #78;
-float(string str, float ofs)						str2chr = #222;
-string(float c, ...)							chr2str = #223;
-
-vector (vector org)							getlight = #92;
-
-entity (.string fld, string match)					findchain = #402;
-entity (.float fld, float match)					findchainflags = #450;
-entity (.entity fld, entity match)					findchainentity = #403;
-entity (.float fld, float match)					findchainfloat = #403;
-entity (entity start, .float fld, float match)				findflags = #449;
-
-float (string pattern, float caseinsensitive, float quiet)		search_begin = #444;
-void (float handle)							search_end = #445;
-float (float handle)							search_getsize = #446;
-string (float handle, float num)					search_getfilename = #447;
-
-
-float (entity e, float s)						getsurfacenumpoints = #434;
-vector (entity e, float s, float n)					getsurfacepoint = #435;
-vector (entity e, float s)						getsurfacenormal = #436;
-string (entity e, float s)						getsurfacetexture = #437;
-float (entity e, vector p)						getsurfacenearpoint = #438;
-vector (entity e, float s, vector p)					getsurfaceclippedpoint = #439;
-
-float (float a, float b) min = #94;
-float (float a, float b, float c) min3 = #94;
-float (float a, float b, float c, float d) min4 = #94;
-float (float a, float b, float c, float d, float e) min5 = #94;
-float (float a, float b, float c, float d, float e, float f) min6 = #94;
-float (float a, float b, float c, float d, float e, float f, float g) min7 = #94;
-float (float a, float b, float c, float d, float e, float f, float g, float h) min8 = #94;
-float (float a, float b) max = #95;
-float (float a, float b, float c) max3 = #95;
-float (float a, float b, float c, float d) max4 = #95;
-float (float a, float b, float c, float d, float e) max5 = #95;
-float (float a, float b, float c, float d, float e, float f) max6 = #95;
-float (float a, float b, float c, float d, float e, float f, float g) max7 = #95;
-float (float a, float b, float c, float d, float e, float f, float g, float h) max8 = #95;
-float (float minimum, float val, float maximum) bound = #96;
-
-vector () randomvec = #91;
-
-float (float val)		sin = #60;
-float (float val)		cos = #61;
-float (float val)		sqrt = #62;
-float (float a, float b)	pow = #97;
-
-void (vector org, string modelname, float startframe, float endframe, float framerate) effect = #404;
-
-void (vector org, vector velocity, float howmany) te_blood = #405;
-void (vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower = #406;
-void (vector org, float radius, float lifetime, vector color) te_customflash = #417;
-void(vector org, vector color) te_explosionrgb = #407;
-void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube = #408;
-void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain = #409;
-void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow = #410;
-void(vector org) te_plasmaburn = #433;
-void(vector org) te_gunshotquad = #412;
-void(vector org) te_spikequad = #413;
-void(vector org) te_superspikequad = #414;
-void(vector org) te_explosionquad = #415;
-void(vector org) te_smallflash = #416;
-void(vector org, vector vel, float howmany) te_spark = #411;
-
-void(vector org) te_gunshot = #418;
-void(vector org) te_spike = #419;
-void(vector org) te_superspike = #420;
-void(vector org) te_explosion = #421;
-void(vector org) te_tarexplosion = #422;
-void(vector org) te_wizspike = #423;
-void(vector org) te_knightspike = #424;
-void(vector org) te_lavasplash = #425;
-void(vector org) te_teleport = #426;
-void(vector org, float color, float colorlength) te_explosion2 = #427;
-void(entity own, vector start, vector end) te_lightning1 = #428;
-void(entity own, vector start, vector end) te_lightning2 = #429;
-void(entity own, vector start, vector end) te_lightning3 = #430;
-void(entity own, vector start, vector end) te_beam = #431;
-
-float (entity ent, string tagname)	gettagindex = #451;
-vector (entity ent, float tagindex)	gettaginfo = #452;
-
-float (string s)	tokenize = #441;
-string (float argnum)	argv = #442;
-
-string (string s) cvar_string = #448;
-
-float ()						buf_create = #460;
-void (float bufhandle)					buf_del = #461;
-float (float bufhandle)					buf_getsize = #462;
-void (float bufhandle_from, float bufhandle_to)		buf_copy = #463;
-void (float bufhandle, float sortpower, float backward)	buf_sort = #464;
-string (float bufhandle, string glue)			buf_implode = #465;
-string (float bufhandle, float string_index)		bufstr_get = #466;
-void (float bufhandle, float string_index, string str)	bufstr_set = #467;
-float (float bufhandle, string str, float order)	bufstr_add = #468;
-void (float bufhandle, float string_index)		bufstr_free = #469;
-
-float () onground = #355;
-
-void(string texturename, ...) R_BeginPolygon = #306;
-void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex = #307;
-void() R_EndPolygon = #308;
-
-float(string s, float num) charindex = #356;
-
-// Darkplaces Additional Functions
-string(string s) strdecolorize = #477;
-string(string s) strtolower = #480; // returns the passed in string in pure lowercase form
-string(string s) strtoupper = #481; // returns the passed in string in pure uppercase form
-float(string s) strlennocol = #476;
-
-void(vector origin, string sample, float volume, float attenuation) pointsound = #483;
-
-// added by blub
-
-string(string key)					serverkey = #354;
-float(string s1, string s2)				strcasecmp = #229;
-float(string s1, string s2, float len)			strncasecmp = #230;
-float(string str, string sub, float startoffs)		strstrofs = #221;
-//float(string str, string sub) 	    		strstrofs = #221;
-entity(float num)   	   				edict_num = #459;
-string(void)						ReadPicture = #501;
-string(string filename)					whichpack = #503;
-float(entity ent)					num_for_edict = #512;
-float(string s, string separator1, ...) tokenizebyseparator = #479;
-string(string in) uri_unescape = #511;
-float(float caseinsensitive, string s, ...) crc16 = #494;
-string(string info, string key) infoget = #227;
-string(string info, string key, string value, ...) infoadd = #226;
-string(string in) uri_escape = #510;
-
-string	keynumtostring(float keynum) = #520;
-string	findkeysforcommand(string command) = #521;
-
-string(float ccase, float calpha, float cnum, string s, ...) strconv = #224;
-float(entity ent) wasfreed = #353;
-
-entity(vector org, float rad) findradius = #22;
-
-string(float uselocaltime, string format, ...) strftime = #478;
-float(float timer) gettime = #519;
-#define GETTIME_CDTRACK 4
-
-float(string s) tokenize_console = #514;
-float(float i) argv_start_index = #515;
-float(float i) argv_end_index = #516;
+void (vector ang)							makevectors = #1;
+void(entity e, vector o) setorigin	= #2;
+void (entity e, string m)						setmodel = #3;
+void(entity e, vector min, vector max) setsize = #4;
+
+void ()									break = #6;
+float ()								random = #7;
+void (entity e, float chan, string samp, float vol, float atten)	sound = #8;
+vector (vector v)							normalize = #9;
+void (string e)								error = #10;
+void (string e)								objerror = #11;
+float (vector v)							vlen = #12;
+float (vector v)							vectoyaw = #13;
+entity ()								spawn = #14;
+void (entity e)								remove = #15;
+
+void (vector v1, vector v2, float nomonsters, entity forent)		traceline = #16;
+
+entity (entity start, .string fld, string match)			find = #18;
+string (string s)							precache_sound = #19;
+string (string s)							precache_model = #20;
+
+//void (string s)								dprint = #25;
+string (float f)							ftos = #26;
+string (vector v)							vtos = #27;
+void ()									coredump = #28;
+void ()									traceon = #29;
+void ()									traceoff = #30;
+void (entity e)								eprint = #31;
+
+float (float v)								rint = #36;
+float (float v)								floor = #37;
+float (float v)								ceil = #38;
+
+float (vector v)							pointcontents = #41;
+float (float f)								fabs = #43;
+
+float (string s)							cvar = #45;
+void (string s, ...)							localcmd = #46;
+entity (entity e)							nextent = #47;
+
+vector (vector v)							vectoangles = #51;
+vector (vector v, vector w)							vectoangles2 = #51;
+
+void (string var, string val)						cvar_set = #72;
+
+
+float()									ReadByte = #360;
+float()									ReadChar = #361;
+float()									ReadShort = #362;
+float()									ReadLong = #363;
+float()									ReadCoord = #364;
+float()									ReadAngle = #365;
+string()								ReadString = #366;	//warning: this returns a temporary!
+
+float(string s)								stof = #81;
+
+
+void (vector v1, vector min, vector max, vector v2, float nomonsters, entity forent)	tracebox = #90;
+float (string name, string value, ...)					registercvar = #93;
+
+entity (entity start, .entity fld, entity match)			findentity = #98;
+entity (entity start, .float fld, float match)				findfloat = #98;
+
+float (string s)							checkextension = #99;
+
+float (string filename, float mode)					fopen = #110;
+void (float fhandle)							fclose = #111;
+string (float fhandle)							fgets = #112;
+void (float fhandle, string s)						fputs = #113;
+float (string s)							strlen = #114;
+string (...)								strcat = #115;
+string (string s, float start, float length)				substring = #116;
+vector (string s)							stov = #117;
+string (string s)							strzone = #118;
+void (string s)								strunzone = #119;
+
+void ()									R_ClearScene = #300;
+void (float mask)							R_AddEntities = #301;
+void (entity e)								R_AddEntity = #302;
+float (float property, ...)						R_SetView = #303;
+void ()									R_RenderScene = #304;
+void (vector org, float radius, vector rgb)				R_AddDynamicLight = #305;
+void ()									R_CalcRefDef = #306;
+
+vector (vector v)							cs_unproject = #310;
+vector (vector v)							cs_project = #311;
+
+void	drawline(float width, vector pos1, vector pos2, vector rgb, float alpha, float flags) = #315;
+float	iscachedpic(string name)	= #316;
+string	precache_pic(string name, ...)	= #317;
+vector	drawgetimagesize(string pic) = #318;
+void	freepic(string name)		= #319;
+float	drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag) = #320;
+float	drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) = #321;
+float	drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) = #322;
+float	drawfill(vector position, vector size, vector rgb, float alpha, float flag) = #323;
+void	drawsetcliparea(float x, float y, float width, float height) = #324;
+void	drawresetcliparea(void) = #325;
+float	drawcolorcodedstring(vector position, string text, vector scale, float alpha, float flag) = #326;
+float	stringwidth(string text, float handleColors) = #327;
+float	drawsubpic(vector position, vector size, string pic, vector srcPosition, vector srcSize, vector rgb, float alpha, float flag) = #328;
+
+
+float (float statnum)							getstatf = #330;
+float (float statnum)							getstati = #331;
+string (float statnum)							getstats = #332;
+
+void (entity e, float i)						setmodelindex = #333;
+string (float i)							modelnameforindex = #334;
+
+float(string efname)							particleeffectnum = #335;
+void(entity ent, float effectnum, vector start, vector end, ...)	trailparticles = #336;
+void (float efnum, vector org, vector vel, float countmultiplier, ...)	pointparticles = #337;
+
+void (string s, ...)							cprint = #338;
+void (string s, ...)							print = #339;
+
+void (float scale)							setsensitivityscale = #346;
+
+
+void (float framenum)							RetrieveMovementFrame = #345;
+void ()									DefaultPlayerPhysics = #347;
+
+string (float playernum, string key)					getplayerkey = #348;
+void (string cmdname)							registercmd = #352;
+vector ()								getmousepos = #344;
+
+string (string s) 							uncolorstring = #170;
+
+void (vector org, vector forward, vector right, vector up)		setlistener = #351;
+
+float (vector start, vector end, float ignore, float csqcents)		selecttraceline = #355;
+float ()								isdemo = #349;
+float ()								isserver = #350;
+
+void (float f)								setwantsmousemove = #343;
+string (float key)							getkeybind = #342;
+//string (float f)							chr = #78;
+string (float f)							chr = #78;
+float(string str, float ofs)						str2chr = #222;
+string(float c, ...)							chr2str = #223;
+
+vector (vector org)							getlight = #92;
+
+entity (.string fld, string match)					findchain = #402;
+entity (.float fld, float match)					findchainflags = #450;
+entity (.entity fld, entity match)					findchainentity = #403;
+entity (.float fld, float match)					findchainfloat = #403;
+entity (entity start, .float fld, float match)				findflags = #449;
+
+float (string pattern, float caseinsensitive, float quiet)		search_begin = #444;
+void (float handle)							search_end = #445;
+float (float handle)							search_getsize = #446;
+string (float handle, float num)					search_getfilename = #447;
+
+
+float (entity e, float s)						getsurfacenumpoints = #434;
+vector (entity e, float s, float n)					getsurfacepoint = #435;
+vector (entity e, float s)						getsurfacenormal = #436;
+string (entity e, float s)						getsurfacetexture = #437;
+float (entity e, vector p)						getsurfacenearpoint = #438;
+vector (entity e, float s, vector p)					getsurfaceclippedpoint = #439;
+
+float (float a, float b) min = #94;
+float (float a, float b, float c) min3 = #94;
+float (float a, float b, float c, float d) min4 = #94;
+float (float a, float b, float c, float d, float e) min5 = #94;
+float (float a, float b, float c, float d, float e, float f) min6 = #94;
+float (float a, float b, float c, float d, float e, float f, float g) min7 = #94;
+float (float a, float b, float c, float d, float e, float f, float g, float h) min8 = #94;
+float (float a, float b) max = #95;
+float (float a, float b, float c) max3 = #95;
+float (float a, float b, float c, float d) max4 = #95;
+float (float a, float b, float c, float d, float e) max5 = #95;
+float (float a, float b, float c, float d, float e, float f) max6 = #95;
+float (float a, float b, float c, float d, float e, float f, float g) max7 = #95;
+float (float a, float b, float c, float d, float e, float f, float g, float h) max8 = #95;
+float (float minimum, float val, float maximum) bound = #96;
+
+vector () randomvec = #91;
+
+float (float val)		sin = #60;
+float (float val)		cos = #61;
+float (float val)		sqrt = #62;
+float (float a, float b)	pow = #97;
+
+void (vector org, string modelname, float startframe, float endframe, float framerate) effect = #404;
+
+void (vector org, vector velocity, float howmany) te_blood = #405;
+void (vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower = #406;
+void (vector org, float radius, float lifetime, vector color) te_customflash = #417;
+void(vector org, vector color) te_explosionrgb = #407;
+void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube = #408;
+void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain = #409;
+void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow = #410;
+void(vector org) te_plasmaburn = #433;
+void(vector org) te_gunshotquad = #412;
+void(vector org) te_spikequad = #413;
+void(vector org) te_superspikequad = #414;
+void(vector org) te_explosionquad = #415;
+void(vector org) te_smallflash = #416;
+void(vector org, vector vel, float howmany) te_spark = #411;
+
+void(vector org) te_gunshot = #418;
+void(vector org) te_spike = #419;
+void(vector org) te_superspike = #420;
+void(vector org) te_explosion = #421;
+void(vector org) te_tarexplosion = #422;
+void(vector org) te_wizspike = #423;
+void(vector org) te_knightspike = #424;
+void(vector org) te_lavasplash = #425;
+void(vector org) te_teleport = #426;
+void(vector org, float color, float colorlength) te_explosion2 = #427;
+void(entity own, vector start, vector end) te_lightning1 = #428;
+void(entity own, vector start, vector end) te_lightning2 = #429;
+void(entity own, vector start, vector end) te_lightning3 = #430;
+void(entity own, vector start, vector end) te_beam = #431;
+
+float (entity ent, string tagname)	gettagindex = #451;
+vector (entity ent, float tagindex)	gettaginfo = #452;
+
+float (string s)	tokenize = #441;
+string (float argnum)	argv = #442;
+
+string (string s) cvar_string = #448;
+
+float ()						buf_create = #460;
+void (float bufhandle)					buf_del = #461;
+float (float bufhandle)					buf_getsize = #462;
+void (float bufhandle_from, float bufhandle_to)		buf_copy = #463;
+void (float bufhandle, float sortpower, float backward)	buf_sort = #464;
+string (float bufhandle, string glue)			buf_implode = #465;
+string (float bufhandle, float string_index)		bufstr_get = #466;
+void (float bufhandle, float string_index, string str)	bufstr_set = #467;
+float (float bufhandle, string str, float order)	bufstr_add = #468;
+void (float bufhandle, float string_index)		bufstr_free = #469;
+
+float () onground = #355;
+
+void(string texturename, ...) R_BeginPolygon = #306;
+void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex = #307;
+void() R_EndPolygon = #308;
+
+float(string s, float num) charindex = #356;
+
+// Darkplaces Additional Functions
+string(string s) strdecolorize = #477;
+string(string s) strtolower = #480; // returns the passed in string in pure lowercase form
+string(string s) strtoupper = #481; // returns the passed in string in pure uppercase form
+float(string s) strlennocol = #476;
+
+void(vector origin, string sample, float volume, float attenuation) pointsound = #483;
+
+// added by blub
+
+string(string key)					serverkey = #354;
+float(string s1, string s2)				strcasecmp = #229;
+float(string s1, string s2, float len)			strncasecmp = #230;
+float(string str, string sub, float startoffs)		strstrofs = #221;
+//float(string str, string sub) 	    		strstrofs = #221;
+entity(float num)   	   				edict_num = #459;
+string(void)						ReadPicture = #501;
+string(string filename)					whichpack = #503;
+float(entity ent)					num_for_edict = #512;
+float(string s, string separator1, ...) tokenizebyseparator = #479;
+string(string in) uri_unescape = #511;
+float(float caseinsensitive, string s, ...) crc16 = #494;
+string(string info, string key) infoget = #227;
+string(string info, string key, string value, ...) infoadd = #226;
+string(string in) uri_escape = #510;
+
+string	keynumtostring(float keynum) = #520;
+string	findkeysforcommand(string command) = #521;
+
+string(float ccase, float calpha, float cnum, string s, ...) strconv = #224;
+float(entity ent) wasfreed = #353;
+
+entity(vector org, float rad) findradius = #22;
+
+string(float uselocaltime, string format, ...) strftime = #478;
+float(float timer) gettime = #519;
+#define GETTIME_CDTRACK 4
+
+float(string s) tokenize_console = #514;
+float(float i) argv_start_index = #515;
+float(float i) argv_end_index = #516;


Property changes on: trunk/data/qcsrc/client/csqc_builtins.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/client/csqc_constants.qc
===================================================================
--- trunk/data/qcsrc/client/csqc_constants.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/client/csqc_constants.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,192 +1,192 @@
-const entity	NULL							= world;
-
-// Mask Constants (set .drawmask on entities; use R_AddEntities to add all entities based on mask)
-const float		MASK_ENGINE						= 1;
-const float		MASK_ENGINEVIEWMODELS			= 2;
-const float		MASK_NORMAL						= 4;
-
-// Renderflag Constants (used for CSQC entities)
-const float		RF_VIEWMODEL					= 1;
-const float		RF_EXTERNALMODEL				= 2;
-const float		RF_DEPTHHACK					= 4;
-const float		RF_ADDITIVE						= 8;
-const float		RF_USEAXIS						= 16;
-
-// Viewflag Constants (use with R_SetView)
-const float		VF_MIN							= 1;	//(vector)
-const float		VF_MIN_X						= 2;	//(float)
-const float		VF_MIN_Y						= 3;	//(float)
-const float		VF_SIZE							= 4;	//(vector) (viewport size)
-const float		VF_SIZE_Y						= 5;	//(float)
-const float		VF_SIZE_X						= 6;	//(float)
-const float		VF_VIEWPORT						= 7;	//(vector, vector)
-const float		VF_FOV							= 8;	//(vector)
-const float		VF_FOVX							= 9;	//(float)
-const float		VF_FOVY							= 10;	//(float)
-const float		VF_ORIGIN						= 11;	//(vector)
-const float		VF_ORIGIN_X						= 12;	//(float)
-const float		VF_ORIGIN_Y						= 13;	//(float)
-const float		VF_ORIGIN_Z						= 14;	//(float)
-const float		VF_ANGLES						= 15;	//(vector)
-const float		VF_ANGLES_X						= 16;	//(float)
-const float		VF_ANGLES_Y						= 17;	//(float)
-const float		VF_ANGLES_Z						= 18;	//(float)
-const float		VF_DRAWWORLD					= 19;	//(float)
-const float		VF_DRAWENGINESBAR				= 20;	//(float)
-const float		VF_DRAWCROSSHAIR				= 21;	//(float)
-const float		VF_PERSPECTIVE					= 200;	//(float)
-
-const float		VF_CL_VIEWANGLES				= 33;	//(vector)
-const float		VF_CL_VIEWANGLES_X				= 34;	//(float)
-const float		VF_CL_VIEWANGLES_Y				= 35;	//(float)
-const float		VF_CL_VIEWANGLES_Z				= 36;	//(float) 
-
-// Server Autosent Stat Constants
-const float		STAT_HEALTH						= 0;
-const float		STAT_WEAPONMODEL				= 2;
-const float		STAT_AMMO						= 3;
-const float		STAT_ARMOR						= 4;
-const float		STAT_WEAPONFRAME				= 5;
-const float		STAT_SHELLS						= 6;
-const float		STAT_NAILS						= 7;
-const float		STAT_ROCKETS					= 8;
-const float		STAT_CELLS						= 9;
-const float		STAT_ACTIVEWEAPON				= 10;
-const float		STAT_TOTALSECRETS				= 11;
-const float		STAT_TOTALMONSTERS				= 12;
-const float		STAT_SECRETS					= 13;
-const float		STAT_MONSTERS					= 14;
-const float		STAT_ITEMS						= 15;
-const float		STAT_VIEWHEIGHT					= 16;
-const float		STAT_MOVEVARS_TICRATE           = 240;
-const float		STAT_MOVEVARS_TIMESCALE         = 241;
-const float		STAT_FRAGLIMIT					= 235;
-const float		STAT_TIMELIMIT					= 236;
-const float     STAT_MOVEVARS_GRAVITY           = 242;
-
-// Sound Constants
-//const float		CHAN_AUTO						= 0;
-//const float		CHAN_WEAPON						= 1;
-//const float		CHAN_VOICE						= 2;
-//const float		CHAN_ITEM						= 3;
-//const float		CHAN_BODY						= 4;
-
-//const float		ATTN_NONE						= 0;
-//const float		ATTN_NORM						= 1;
-//const float		ATTN_IDLE						= 2;
-//const float		ATTN_STATIC						= 3;
-
-// Quake-style Point Contents
-const float		CONTENT_EMPTY					= -1;
-const float		CONTENT_SOLID					= -2;
-const float		CONTENT_WATER					= -3;
-const float		CONTENT_SLIME					= -4;
-const float		CONTENT_LAVA					= -5;
-const float		CONTENT_SKY						= -6;
-
-// Boolean Constants
-const float		true							= 1;
-const float		false							= 0;
-const float 	TRUE							= 1;
-const float 	FALSE							= 0;
-
-// Vector / Hull Constants
-const vector	VEC_1							= '1 1 1';
-const vector	VEC_0							= '0 0 0';
-const vector	VEC_M1							= '-1 -1 -1';
-
-const vector	VEC_HULL_MIN 					= '-16 -16 -24';
-const vector	VEC_HULL_MAX 					= '16 16 32';
-
-// Effect Constants
-const float 	EF_NODRAW						= 16;
-const float 	EF_ADDITIVE						= 32;
-const float 	EF_BLUE							= 64;
-const float 	EF_RED							= 128;
-const float 	EF_FULLBRIGHT					= 512;
-const float 	EF_FLAME						= 1024;
-const float 	EF_STARDUST						= 2048;
-const float 	EF_NOSHADOW						= 4096;
-const float 	EF_NODEPTHTEST					= 8192;
-
-// Quake Player Flag Constants
-const float 	PFL_ONGROUND					= 1;
-const float 	PFL_CROUCH						= 2;
-const float 	PFL_DEAD						= 4;
-const float 	PFL_GIBBED						= 8;
-
-// Quake Temporary Entity Constants
-const float		TE_SPIKE						= 0;
-const float		TE_SUPERSPIKE					= 1;
-const float		TE_GUNSHOT						= 2;
-const float		TE_EXPLOSION					= 3;
-const float		TE_TAREXPLOSION					= 4;
-const float		TE_LIGHTNING1					= 5;
-const float		TE_LIGHTNING2					= 6;
-const float		TE_WIZSPIKE						= 7;
-const float		TE_KNIGHTSPIKE					= 8;
-const float		TE_LIGHTNING3					= 9;
-const float		TE_LAVASPLASH					= 10;
-const float		TE_TELEPORT						= 11;
-const float 	TE_EXPLOSION2					= 12;
-// Darkplaces Additions
-const float 	TE_EXPLOSIONRGB					= 53;
-const float		TE_GUNSHOTQUAD					= 57;
-const float		TE_EXPLOSIONQUAD 				= 70;
-
-// Math Constants
-const float 	M_PI 							= 3.14159265358979323846;
-const float 	EXTRA_LOW 						= -99999999;
-const float 	EXTRA_HIGH 						= 99999999;
-
-// Frik File Constants
-const float		FILE_READ						= 0;
-const float		FILE_APPEND						= 1;
-const float		FILE_WRITE						= 2;
-
-// Button values used by input_buttons
-const float BUTTON_ATTACK = 1;
-const float BUTTON_JUMP = 2;
-const float BUTTON_3 = 4;
-const float BUTTON_4 = 8;
-const float BUTTON_5 = 16;
-const float BUTTON_6 = 32;
-const float BUTTON7 = 64;
-const float BUTTON8 = 128;
-const float BUTTON_USE = 256;
-const float BUTTON_CHAT = 512;
-const float BUTTON_PRYDONCURSOR = 1024;
-const float BUTTON_9 = 2048;
-const float BUTTON_10 = 4096;
-const float BUTTON_11 = 8192;
-const float BUTTON_12 = 16384;
-const float BUTTON_13 = 32768;
-const float BUTTON_14 = 65536;
-const float BUTTON_15 = 131072;
-const float BUTTON_16 = 262144;
-
-
-const float DRAWFLAG_NORMAL = 0;
-const float DRAWFLAG_ADDITIVE = 1;
-const float DRAWFLAG_MODULATE = 2;
-const float DRAWFLAG_2XMODULATE = 3;
-const float DRAWFLAG_SCREEN = 4;
-const float DRAWFLAG_MIPMAP = 0x100; // only for R_BeginPolygon
-
-#define        SOLID_NOT                               0               // no interaction with other objects
-#define        SOLID_TRIGGER                   1               // touch on edge, but not blocking
-#define        SOLID_BBOX                              2               // touch on edge, block
-#define        SOLID_SLIDEBOX                  3               // touch on edge, but not an onground
-#define        SOLID_BSP                               4               // bsp clip, touch on edge, block
-#define        SOLID_CORPSE                    5               // same as SOLID_BBOX, except it behaves as SOLID_NOT against SOLID_SLIDEBOX objects (players/monsters)
-
-float MOVE_NORMAL = 0; // same as FALSE
-float MOVE_NOMONSTERS = 1; // same as TRUE
-float MOVE_MISSILE = 2; // save as movement with .movetype == MOVETYPE_FLYMISSILE
-float MOVE_HITMODEL = 4;
-float MOVE_WORLDONLY = 3;
-
-float CAMERA_FREE = 1;
-float CAMERA_CHASE = 2;
-
-float EF_NOMODELFLAGS = 8388608;
+const entity	NULL							= world;
+
+// Mask Constants (set .drawmask on entities; use R_AddEntities to add all entities based on mask)
+const float		MASK_ENGINE						= 1;
+const float		MASK_ENGINEVIEWMODELS			= 2;
+const float		MASK_NORMAL						= 4;
+
+// Renderflag Constants (used for CSQC entities)
+const float		RF_VIEWMODEL					= 1;
+const float		RF_EXTERNALMODEL				= 2;
+const float		RF_DEPTHHACK					= 4;
+const float		RF_ADDITIVE						= 8;
+const float		RF_USEAXIS						= 16;
+
+// Viewflag Constants (use with R_SetView)
+const float		VF_MIN							= 1;	//(vector)
+const float		VF_MIN_X						= 2;	//(float)
+const float		VF_MIN_Y						= 3;	//(float)
+const float		VF_SIZE							= 4;	//(vector) (viewport size)
+const float		VF_SIZE_Y						= 5;	//(float)
+const float		VF_SIZE_X						= 6;	//(float)
+const float		VF_VIEWPORT						= 7;	//(vector, vector)
+const float		VF_FOV							= 8;	//(vector)
+const float		VF_FOVX							= 9;	//(float)
+const float		VF_FOVY							= 10;	//(float)
+const float		VF_ORIGIN						= 11;	//(vector)
+const float		VF_ORIGIN_X						= 12;	//(float)
+const float		VF_ORIGIN_Y						= 13;	//(float)
+const float		VF_ORIGIN_Z						= 14;	//(float)
+const float		VF_ANGLES						= 15;	//(vector)
+const float		VF_ANGLES_X						= 16;	//(float)
+const float		VF_ANGLES_Y						= 17;	//(float)
+const float		VF_ANGLES_Z						= 18;	//(float)
+const float		VF_DRAWWORLD					= 19;	//(float)
+const float		VF_DRAWENGINESBAR				= 20;	//(float)
+const float		VF_DRAWCROSSHAIR				= 21;	//(float)
+const float		VF_PERSPECTIVE					= 200;	//(float)
+
+const float		VF_CL_VIEWANGLES				= 33;	//(vector)
+const float		VF_CL_VIEWANGLES_X				= 34;	//(float)
+const float		VF_CL_VIEWANGLES_Y				= 35;	//(float)
+const float		VF_CL_VIEWANGLES_Z				= 36;	//(float) 
+
+// Server Autosent Stat Constants
+const float		STAT_HEALTH						= 0;
+const float		STAT_WEAPONMODEL				= 2;
+const float		STAT_AMMO						= 3;
+const float		STAT_ARMOR						= 4;
+const float		STAT_WEAPONFRAME				= 5;
+const float		STAT_SHELLS						= 6;
+const float		STAT_NAILS						= 7;
+const float		STAT_ROCKETS					= 8;
+const float		STAT_CELLS						= 9;
+const float		STAT_ACTIVEWEAPON				= 10;
+const float		STAT_TOTALSECRETS				= 11;
+const float		STAT_TOTALMONSTERS				= 12;
+const float		STAT_SECRETS					= 13;
+const float		STAT_MONSTERS					= 14;
+const float		STAT_ITEMS						= 15;
+const float		STAT_VIEWHEIGHT					= 16;
+const float		STAT_MOVEVARS_TICRATE           = 240;
+const float		STAT_MOVEVARS_TIMESCALE         = 241;
+const float		STAT_FRAGLIMIT					= 235;
+const float		STAT_TIMELIMIT					= 236;
+const float     STAT_MOVEVARS_GRAVITY           = 242;
+
+// Sound Constants
+//const float		CHAN_AUTO						= 0;
+//const float		CHAN_WEAPON						= 1;
+//const float		CHAN_VOICE						= 2;
+//const float		CHAN_ITEM						= 3;
+//const float		CHAN_BODY						= 4;
+
+//const float		ATTN_NONE						= 0;
+//const float		ATTN_NORM						= 1;
+//const float		ATTN_IDLE						= 2;
+//const float		ATTN_STATIC						= 3;
+
+// Quake-style Point Contents
+const float		CONTENT_EMPTY					= -1;
+const float		CONTENT_SOLID					= -2;
+const float		CONTENT_WATER					= -3;
+const float		CONTENT_SLIME					= -4;
+const float		CONTENT_LAVA					= -5;
+const float		CONTENT_SKY						= -6;
+
+// Boolean Constants
+const float		true							= 1;
+const float		false							= 0;
+const float 	TRUE							= 1;
+const float 	FALSE							= 0;
+
+// Vector / Hull Constants
+const vector	VEC_1							= '1 1 1';
+const vector	VEC_0							= '0 0 0';
+const vector	VEC_M1							= '-1 -1 -1';
+
+const vector	VEC_HULL_MIN 					= '-16 -16 -24';
+const vector	VEC_HULL_MAX 					= '16 16 32';
+
+// Effect Constants
+const float 	EF_NODRAW						= 16;
+const float 	EF_ADDITIVE						= 32;
+const float 	EF_BLUE							= 64;
+const float 	EF_RED							= 128;
+const float 	EF_FULLBRIGHT					= 512;
+const float 	EF_FLAME						= 1024;
+const float 	EF_STARDUST						= 2048;
+const float 	EF_NOSHADOW						= 4096;
+const float 	EF_NODEPTHTEST					= 8192;
+
+// Quake Player Flag Constants
+const float 	PFL_ONGROUND					= 1;
+const float 	PFL_CROUCH						= 2;
+const float 	PFL_DEAD						= 4;
+const float 	PFL_GIBBED						= 8;
+
+// Quake Temporary Entity Constants
+const float		TE_SPIKE						= 0;
+const float		TE_SUPERSPIKE					= 1;
+const float		TE_GUNSHOT						= 2;
+const float		TE_EXPLOSION					= 3;
+const float		TE_TAREXPLOSION					= 4;
+const float		TE_LIGHTNING1					= 5;
+const float		TE_LIGHTNING2					= 6;
+const float		TE_WIZSPIKE						= 7;
+const float		TE_KNIGHTSPIKE					= 8;
+const float		TE_LIGHTNING3					= 9;
+const float		TE_LAVASPLASH					= 10;
+const float		TE_TELEPORT						= 11;
+const float 	TE_EXPLOSION2					= 12;
+// Darkplaces Additions
+const float 	TE_EXPLOSIONRGB					= 53;
+const float		TE_GUNSHOTQUAD					= 57;
+const float		TE_EXPLOSIONQUAD 				= 70;
+
+// Math Constants
+const float 	M_PI 							= 3.14159265358979323846;
+const float 	EXTRA_LOW 						= -99999999;
+const float 	EXTRA_HIGH 						= 99999999;
+
+// Frik File Constants
+const float		FILE_READ						= 0;
+const float		FILE_APPEND						= 1;
+const float		FILE_WRITE						= 2;
+
+// Button values used by input_buttons
+const float BUTTON_ATTACK = 1;
+const float BUTTON_JUMP = 2;
+const float BUTTON_3 = 4;
+const float BUTTON_4 = 8;
+const float BUTTON_5 = 16;
+const float BUTTON_6 = 32;
+const float BUTTON7 = 64;
+const float BUTTON8 = 128;
+const float BUTTON_USE = 256;
+const float BUTTON_CHAT = 512;
+const float BUTTON_PRYDONCURSOR = 1024;
+const float BUTTON_9 = 2048;
+const float BUTTON_10 = 4096;
+const float BUTTON_11 = 8192;
+const float BUTTON_12 = 16384;
+const float BUTTON_13 = 32768;
+const float BUTTON_14 = 65536;
+const float BUTTON_15 = 131072;
+const float BUTTON_16 = 262144;
+
+
+const float DRAWFLAG_NORMAL = 0;
+const float DRAWFLAG_ADDITIVE = 1;
+const float DRAWFLAG_MODULATE = 2;
+const float DRAWFLAG_2XMODULATE = 3;
+const float DRAWFLAG_SCREEN = 4;
+const float DRAWFLAG_MIPMAP = 0x100; // only for R_BeginPolygon
+
+#define        SOLID_NOT                               0               // no interaction with other objects
+#define        SOLID_TRIGGER                   1               // touch on edge, but not blocking
+#define        SOLID_BBOX                              2               // touch on edge, block
+#define        SOLID_SLIDEBOX                  3               // touch on edge, but not an onground
+#define        SOLID_BSP                               4               // bsp clip, touch on edge, block
+#define        SOLID_CORPSE                    5               // same as SOLID_BBOX, except it behaves as SOLID_NOT against SOLID_SLIDEBOX objects (players/monsters)
+
+float MOVE_NORMAL = 0; // same as FALSE
+float MOVE_NOMONSTERS = 1; // same as TRUE
+float MOVE_MISSILE = 2; // save as movement with .movetype == MOVETYPE_FLYMISSILE
+float MOVE_HITMODEL = 4;
+float MOVE_WORLDONLY = 3;
+
+float CAMERA_FREE = 1;
+float CAMERA_CHASE = 2;
+
+float EF_NOMODELFLAGS = 8388608;


Property changes on: trunk/data/qcsrc/client/csqc_constants.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/ctf.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/damage.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/client/effects.qc
===================================================================
--- trunk/data/qcsrc/client/effects.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/client/effects.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,100 +1,100 @@
-/*
-.vector fx_start;
-.vector fx_end;
-.float  fx_with;
-.string fx_texture;
-.float  fx_lifetime;
-
-void SUB_Remove()
-{ remove(self); }
-
-void b_draw()
-{
-    //Draw_CylindricLine(self.fx_start, self.fx_end, self.fx_with, self.fx_texture, 0, time * 3, '1 1 1', 0.7, DRAWFLAG_ADDITIVE);
-    Draw_CylindricLine(self.fx_start, self.fx_end, self.fx_with, self.fx_texture, (self.fx_with/256), 0, '1 1 1', 1, DRAWFLAG_ADDITIVE);
-
-}
-void b_make(vector s,vector e, string t,float l,float z)
-{
-    entity b;
-    b = spawn();
-    b.fx_texture = t;
-    b.fx_start = s;
-    b.fx_end = e;
-    b.fx_with = z;
-    b.think = SUB_Remove;
-    b.nextthink = time + l;
-	b.draw = b_draw;
-
-	//b.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
-}
-*/
-
-void cl_effetcs_lightningarc(vector from, vector to,float seglength,float drifts,float drifte,float branchfactor,float branchfactor_add)
-{
-    vector direction,dirnew, pos, pos_l;
-    float length, steps, steplength, i,drift;
-
-    length     = vlen(from - to);
-    if(length < 1)
-        return;
-
-    steps      = floor(length / seglength);
-    if(steps < 1)
-    {
-        te_lightning1(world,from,to);
-        return;
-    }
-
-    steplength = length / steps;
-    direction  = normalize(to - from);
-    pos_l = from;
-    if(length > seglength)
-    {
-        for(i = 1; i < steps; i += 1)
-        {
-            drift = drifts * (1 - (i / steps)) + drifte * (i / steps);
-            dirnew = normalize(direction * (1 - drift) + randomvec() * drift);
-            pos = pos_l +  dirnew * steplength;
-            te_lightning1(world,pos_l,pos);
-            //b_make(pos_l, pos,"particles/lightning2",0.25,64);
-            if(random() < branchfactor)
-                cl_effetcs_lightningarc(pos, pos + (dirnew * length * 0.25),seglength,drifts,drifte,min(branchfactor + branchfactor_add,1),branchfactor_add);
-
-            pos_l = pos;
-        }
-        te_lightning1(world,pos_l,to);
-        //b_make(pos_l, to,"particles/lightning2",0.25,64);
-
-    }
-    else
-        te_lightning1(world,from,to);
-        //b_make(from, to,"particles/lightning2",0.25,64);
-
-}
-
-void Net_ReadLightningarc()
-{
-	vector from, to;
-
-    from_x = ReadCoord(); from_y = ReadCoord(); from_z = ReadCoord();
-    to_x   = ReadCoord(); to_y   = ReadCoord(); to_z   = ReadCoord();
-
-    if(cvar("cl_effects_lightningarc_simple"))
-    {
-        te_lightning1(world,from,to);
-    }
-    else
-    {
-        float seglength, drifts, drifte, branchfactor, branchfactor_add;
-
-        seglength    = cvar("cl_effects_lightningarc_segmentlength");
-        drifts       = cvar("cl_effects_lightningarc_drift_start");
-        drifte       = cvar("cl_effects_lightningarc_drift_end");
-        branchfactor = cvar("cl_effects_lightningarc_branchfactor_start");
-        branchfactor = cvar("cl_effects_lightningarc_branchfactor_add");
-
-        cl_effetcs_lightningarc(from,to,seglength,drifts,drifte,branchfactor,branchfactor_add);
-    }
-
-}
+/*
+.vector fx_start;
+.vector fx_end;
+.float  fx_with;
+.string fx_texture;
+.float  fx_lifetime;
+
+void SUB_Remove()
+{ remove(self); }
+
+void b_draw()
+{
+    //Draw_CylindricLine(self.fx_start, self.fx_end, self.fx_with, self.fx_texture, 0, time * 3, '1 1 1', 0.7, DRAWFLAG_ADDITIVE);
+    Draw_CylindricLine(self.fx_start, self.fx_end, self.fx_with, self.fx_texture, (self.fx_with/256), 0, '1 1 1', 1, DRAWFLAG_ADDITIVE);
+
+}
+void b_make(vector s,vector e, string t,float l,float z)
+{
+    entity b;
+    b = spawn();
+    b.fx_texture = t;
+    b.fx_start = s;
+    b.fx_end = e;
+    b.fx_with = z;
+    b.think = SUB_Remove;
+    b.nextthink = time + l;
+	b.draw = b_draw;
+
+	//b.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
+}
+*/
+
+void cl_effetcs_lightningarc(vector from, vector to,float seglength,float drifts,float drifte,float branchfactor,float branchfactor_add)
+{
+    vector direction,dirnew, pos, pos_l;
+    float length, steps, steplength, i,drift;
+
+    length     = vlen(from - to);
+    if(length < 1)
+        return;
+
+    steps      = floor(length / seglength);
+    if(steps < 1)
+    {
+        te_lightning1(world,from,to);
+        return;
+    }
+
+    steplength = length / steps;
+    direction  = normalize(to - from);
+    pos_l = from;
+    if(length > seglength)
+    {
+        for(i = 1; i < steps; i += 1)
+        {
+            drift = drifts * (1 - (i / steps)) + drifte * (i / steps);
+            dirnew = normalize(direction * (1 - drift) + randomvec() * drift);
+            pos = pos_l +  dirnew * steplength;
+            te_lightning1(world,pos_l,pos);
+            //b_make(pos_l, pos,"particles/lightning2",0.25,64);
+            if(random() < branchfactor)
+                cl_effetcs_lightningarc(pos, pos + (dirnew * length * 0.25),seglength,drifts,drifte,min(branchfactor + branchfactor_add,1),branchfactor_add);
+
+            pos_l = pos;
+        }
+        te_lightning1(world,pos_l,to);
+        //b_make(pos_l, to,"particles/lightning2",0.25,64);
+
+    }
+    else
+        te_lightning1(world,from,to);
+        //b_make(from, to,"particles/lightning2",0.25,64);
+
+}
+
+void Net_ReadLightningarc()
+{
+	vector from, to;
+
+    from_x = ReadCoord(); from_y = ReadCoord(); from_z = ReadCoord();
+    to_x   = ReadCoord(); to_y   = ReadCoord(); to_z   = ReadCoord();
+
+    if(cvar("cl_effects_lightningarc_simple"))
+    {
+        te_lightning1(world,from,to);
+    }
+    else
+    {
+        float seglength, drifts, drifte, branchfactor, branchfactor_add;
+
+        seglength    = cvar("cl_effects_lightningarc_segmentlength");
+        drifts       = cvar("cl_effects_lightningarc_drift_start");
+        drifte       = cvar("cl_effects_lightningarc_drift_end");
+        branchfactor = cvar("cl_effects_lightningarc_branchfactor_start");
+        branchfactor = cvar("cl_effects_lightningarc_branchfactor_add");
+
+        cl_effetcs_lightningarc(from,to,seglength,drifts,drifte,branchfactor,branchfactor_add);
+    }
+
+}


Property changes on: trunk/data/qcsrc/client/effects.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/gibs.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/hook.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/interpolate.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/interpolate.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/laser.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/main.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/mapvoting.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/movetypes.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/movetypes.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/particles.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/prandom.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/prandom.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/pre.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/projectile.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/client/rubble.qc
===================================================================
--- trunk/data/qcsrc/client/rubble.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/client/rubble.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,34 +1,34 @@
-.float creationtime;
-
-void RubbleDrop(entity list, void() deleteproc)
-{
-    float t,tt;
-    entity rub,old_rub;
-
-    rub = findchainentity(owner,list);
-    while(rub)
-    {
-        if(rub.creationtime > t)
-        {
-            old_rub = rub;
-            tt = t;
-        }
-        rub = rub.chain;
-    }
-
-    rub = self;
-    self = old_rub;
-    deleteproc();
-    self = rub;
-}
-
-entity RubbleNew(entity list)
-{
-    entity rub;
-
-    rub = spawn();
-    rub.creationtime = time;
-    rub.owner = list;
-
-    return rub;
-}
+.float creationtime;
+
+void RubbleDrop(entity list, void() deleteproc)
+{
+    float t,tt;
+    entity rub,old_rub;
+
+    rub = findchainentity(owner,list);
+    while(rub)
+    {
+        if(rub.creationtime > t)
+        {
+            old_rub = rub;
+            tt = t;
+        }
+        rub = rub.chain;
+    }
+
+    rub = self;
+    self = old_rub;
+    deleteproc();
+    self = rub;
+}
+
+entity RubbleNew(entity list)
+{
+    entity rub;
+
+    rub = spawn();
+    rub.creationtime = time;
+    rub.owner = list;
+
+    return rub;
+}


Property changes on: trunk/data/qcsrc/client/rubble.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/sortlist.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/teamplay.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/teamradar.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/teamradar.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/wall.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/waypointsprites.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/client/waypointsprites.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/common/items.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/common/items.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/common/util-pre.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/bigbutton.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/bigcommandbutton.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/colorpicker.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/cvarlist.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/demolist.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/dialog_multiplayer_create_advanced.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/dialog_multiplayer_demo.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/dialog_multiplayer_join_serverinfo.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup_radar.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/dialog_multiplayer_playersetup_weapons.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/dialog_settings_audio.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/dialog_settings_misc_cvars.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/dialog_settings_network.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/modbutton.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/playerlist.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/skinlist.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/menu/nexuiz/weaponslist.c
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/bots_scripting.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/csqceffects.qc
===================================================================
--- trunk/data/qcsrc/server/csqceffects.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/csqceffects.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,13 +1,13 @@
-void te_csqc_lightningarc(vector from,vector to)
-{
-	WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
-	WriteByte(MSG_BROADCAST, TE_CSQC_LIGHTNINGARC);
-
-	WriteCoord(MSG_BROADCAST, from_x);
-	WriteCoord(MSG_BROADCAST, from_y);
-	WriteCoord(MSG_BROADCAST, from_z);
-	WriteCoord(MSG_BROADCAST, to_x);
-	WriteCoord(MSG_BROADCAST, to_y);
-	WriteCoord(MSG_BROADCAST, to_z);
-}
-
+void te_csqc_lightningarc(vector from,vector to)
+{
+	WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
+	WriteByte(MSG_BROADCAST, TE_CSQC_LIGHTNINGARC);
+
+	WriteCoord(MSG_BROADCAST, from_x);
+	WriteCoord(MSG_BROADCAST, from_y);
+	WriteCoord(MSG_BROADCAST, from_z);
+	WriteCoord(MSG_BROADCAST, to_x);
+	WriteCoord(MSG_BROADCAST, to_y);
+	WriteCoord(MSG_BROADCAST, to_z);
+}
+


Property changes on: trunk/data/qcsrc/server/csqceffects.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/csqcprojectile.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/csqcprojectile.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/ent_cs.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/func_breakable.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/g_hook.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/g_models.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/havocbot_ons.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/monsters/ai.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/monsters/defs.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/monsters/fight.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/monsters/m_monsters.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/monsters/mode_management.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/movelib.qc
===================================================================
--- trunk/data/qcsrc/server/movelib.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/movelib.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,234 +1,234 @@
-.vector moveto;
-
-/**
-    Simulate drag
-    self.velocity = movelib_vdrag(self.velocity,0.02,0.5);
-**/
-vector movelib_dragvec(float drag, float exp)
-{
-    float lspeed,ldrag;
-
-    lspeed = vlen(self.velocity);
-    ldrag = lspeed * drag;
-    ldrag = ldrag * (drag * exp);
-    ldrag = 1 - (ldrag / lspeed);
-
-    return self.velocity * ldrag;
-}
-
-/**
-    Simulate drag
-    self.velocity = movelib_vdrag(somespeed,0.01,0.7);
-**/
-float movelib_dragflt(float fspeed,float drag,float exp)
-{
-    float ldrag;
-
-    ldrag = fspeed * drag;
-    ldrag = ldrag * ldrag * exp;
-    ldrag = 1 - (ldrag / fspeed);
-
-    return ldrag;
-}
-
-/**
-    Do a inertia simulation based on velocity.
-    Basicaly, this allows you to simulate loss of steering with higher speed.
-    self.velocity = movelib_inertia_fromspeed(self.velocity,newvel,1000,0.1,0.9);
-**/
-vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax)
-{
-    float influense;
-
-    influense = vlen(self.velocity) * (1 / vel_max);
-
-    influense = bound(newmin,influense,oldmax);
-
-    return (vel_new * (1 - influense)) + (self.velocity * influense);
-}
-
-vector movelib_inertmove(vector new_vel,float new_bias)
-{
-    return new_vel * new_bias + self.velocity * (1-new_bias);
-}
-
-.float  movelib_lastupdate;
-void movelib_move(vector force,float max_velocity,float drag,float mass,float breakforce)
-{
-    float deltatime;
-    float acceleration;
-    float mspeed;
-    vector breakvec;
-
-    deltatime = time - self.movelib_lastupdate;
-    if (deltatime > 0.15) deltatime = 0;
-    self.movelib_lastupdate = time;
-    if (!deltatime) return;
-
-    mspeed = vlen(self.velocity);
-
-    if (mass)
-        acceleration = vlen(force) / mass;
-    else
-        acceleration = vlen(force);
-
-    if (self.flags & FL_ONGROUND)
-    {
-        if (breakforce)
-        {
-            breakvec = (normalize(self.velocity) * (breakforce / mass) * deltatime);
-            self.velocity = self.velocity - breakvec;
-        }
-
-        self.velocity = self.velocity + force * (acceleration * deltatime);
-    }
-
-    if (drag)
-        self.velocity = movelib_dragvec(drag, 1);
-
-    if (self.waterlevel > 1)
-    {
-        self.velocity = self.velocity + force * (acceleration * deltatime);
-        self.velocity = self.velocity + '0 0 0.05' * sv_gravity * deltatime;
-    }
-    else
-        self.velocity = self.velocity + '0 0 -1' * sv_gravity * deltatime;
-
-    mspeed = vlen(self.velocity);
-
-    if (max_velocity)
-        if (mspeed > max_velocity)
-            self.velocity = normalize(self.velocity) * (mspeed - 50);//* max_velocity;
-}
-
-/*
-.float mass;
-.float side_friction;
-.float ground_friction;
-.float air_friction;
-.float water_friction;
-.float buoyancy;
-float movelib_deltatime;
-
-void movelib_startupdate()
-{
-    movelib_deltatime = time - self.movelib_lastupdate;
-
-    if (movelib_deltatime > 0.5)
-        movelib_deltatime = 0;
-
-    self.movelib_lastupdate = time;
-}
-
-void movelib_update(vector dir,float force)
-{
-    vector acceleration;
-    float old_speed;
-    float ffriction,v_z;
-
-    vector breakvec;
-    vector old_dir;
-    vector ggravity;
-    vector old;
-
-    if(!movelib_deltatime)
-        return;
-    v_z = self.velocity_z;
-    old_speed    = vlen(self.velocity);
-    old_dir      = normalize(self.velocity);
-
-    //ggravity      =  (sv_gravity / self.mass) * '0 0 100';
-    acceleration =  (force / self.mass) * dir;
-    //acceleration -= old_dir * (old_speed / self.mass);
-    acceleration -= ggravity;
-
-    if(self.waterlevel > 1)
-    {
-        ffriction = self.water_friction;
-        acceleration += self.buoyancy * '0 0 1';
-    }
-    else
-        if(self.flags & FL_ONGROUND)
-            ffriction = self.ground_friction;
-        else
-            ffriction = self.air_friction;
-
-    acceleration *= ffriction;
-    //self.velocity = self.velocity * (ffriction * movelib_deltatime);
-    self.velocity += acceleration * movelib_deltatime;
-    self.velocity_z = v_z;
-
-}
-*/
-
-void movelib_move_simple(vector newdir,float velo,float blendrate)
-{
-    self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
-}
-void movelib_beak_simple(float force)
-{
-    float mspeed;
-    vector mdir;
-    float vz;
-
-    mspeed = max(0,vlen(self.velocity) - force);
-    mdir   = normalize(self.velocity);
-    vz = self.velocity_z;
-    self.velocity = mdir * mspeed;
-    self.velocity_z = vz;
-}
-
-
-void movelib_groundalign4point(float spring_length,float spring_up,float blendrate)
-{
-    vector a,b,c,d,e,r,push_angle, ahead,side;
-
-    push_angle_y = 0;
-    r = (self.absmax + self.absmin) * 0.5 + (v_up * spring_up);
-    e = v_up * spring_length;
-
-    // Put springs slightly inside bbox
-    ahead = v_forward * (self.maxs_x * 0.85);
-    side  = v_right   * (self.maxs_y * 0.85);
-
-    a = r + ahead + side;
-    b = r + ahead - side;
-    c = r - ahead + side;
-    d = r - ahead - side;
-
-    traceline(a, a - e,MOVE_NORMAL,self);
-    a_z =  (1 - trace_fraction);
-    r = trace_endpos;
-
-    traceline(b, b - e,MOVE_NORMAL,self);
-    b_z =  (1 - trace_fraction);
-    r += trace_endpos;
-
-    traceline(c, c - e,MOVE_NORMAL,self);
-    c_z =  (1 - trace_fraction);
-    r += trace_endpos;
-
-    traceline(d, d - e,MOVE_NORMAL,self);
-    d_z =  (1 - trace_fraction);
-    r += trace_endpos;
-
-    a_x = r_z;
-    r = self.origin;
-    r_z = r_z;
-
-    push_angle_x = (a_z - c_z) * 45;
-    push_angle_x += (b_z - d_z) * 45;
-
-    push_angle_z = (b_z - a_z) * 45;
-    push_angle_z += (d_z - c_z) * 45;
-
-    //self.angles_x += push_angle_x * 0.95;
-    //self.angles_z += push_angle_z * 0.95;
-
-    self.angles_x = ((1-blendrate) *  self.angles_x)  + (push_angle_x * blendrate);
-    self.angles_z = ((1-blendrate) *  self.angles_z)  + (push_angle_z * blendrate);
-
-    //a = self.origin;
-    setorigin(self,r);
-}
-
+.vector moveto;
+
+/**
+    Simulate drag
+    self.velocity = movelib_vdrag(self.velocity,0.02,0.5);
+**/
+vector movelib_dragvec(float drag, float exp)
+{
+    float lspeed,ldrag;
+
+    lspeed = vlen(self.velocity);
+    ldrag = lspeed * drag;
+    ldrag = ldrag * (drag * exp);
+    ldrag = 1 - (ldrag / lspeed);
+
+    return self.velocity * ldrag;
+}
+
+/**
+    Simulate drag
+    self.velocity = movelib_vdrag(somespeed,0.01,0.7);
+**/
+float movelib_dragflt(float fspeed,float drag,float exp)
+{
+    float ldrag;
+
+    ldrag = fspeed * drag;
+    ldrag = ldrag * ldrag * exp;
+    ldrag = 1 - (ldrag / fspeed);
+
+    return ldrag;
+}
+
+/**
+    Do a inertia simulation based on velocity.
+    Basicaly, this allows you to simulate loss of steering with higher speed.
+    self.velocity = movelib_inertia_fromspeed(self.velocity,newvel,1000,0.1,0.9);
+**/
+vector movelib_inertmove_byspeed(vector vel_new, float vel_max,float newmin,float oldmax)
+{
+    float influense;
+
+    influense = vlen(self.velocity) * (1 / vel_max);
+
+    influense = bound(newmin,influense,oldmax);
+
+    return (vel_new * (1 - influense)) + (self.velocity * influense);
+}
+
+vector movelib_inertmove(vector new_vel,float new_bias)
+{
+    return new_vel * new_bias + self.velocity * (1-new_bias);
+}
+
+.float  movelib_lastupdate;
+void movelib_move(vector force,float max_velocity,float drag,float mass,float breakforce)
+{
+    float deltatime;
+    float acceleration;
+    float mspeed;
+    vector breakvec;
+
+    deltatime = time - self.movelib_lastupdate;
+    if (deltatime > 0.15) deltatime = 0;
+    self.movelib_lastupdate = time;
+    if (!deltatime) return;
+
+    mspeed = vlen(self.velocity);
+
+    if (mass)
+        acceleration = vlen(force) / mass;
+    else
+        acceleration = vlen(force);
+
+    if (self.flags & FL_ONGROUND)
+    {
+        if (breakforce)
+        {
+            breakvec = (normalize(self.velocity) * (breakforce / mass) * deltatime);
+            self.velocity = self.velocity - breakvec;
+        }
+
+        self.velocity = self.velocity + force * (acceleration * deltatime);
+    }
+
+    if (drag)
+        self.velocity = movelib_dragvec(drag, 1);
+
+    if (self.waterlevel > 1)
+    {
+        self.velocity = self.velocity + force * (acceleration * deltatime);
+        self.velocity = self.velocity + '0 0 0.05' * sv_gravity * deltatime;
+    }
+    else
+        self.velocity = self.velocity + '0 0 -1' * sv_gravity * deltatime;
+
+    mspeed = vlen(self.velocity);
+
+    if (max_velocity)
+        if (mspeed > max_velocity)
+            self.velocity = normalize(self.velocity) * (mspeed - 50);//* max_velocity;
+}
+
+/*
+.float mass;
+.float side_friction;
+.float ground_friction;
+.float air_friction;
+.float water_friction;
+.float buoyancy;
+float movelib_deltatime;
+
+void movelib_startupdate()
+{
+    movelib_deltatime = time - self.movelib_lastupdate;
+
+    if (movelib_deltatime > 0.5)
+        movelib_deltatime = 0;
+
+    self.movelib_lastupdate = time;
+}
+
+void movelib_update(vector dir,float force)
+{
+    vector acceleration;
+    float old_speed;
+    float ffriction,v_z;
+
+    vector breakvec;
+    vector old_dir;
+    vector ggravity;
+    vector old;
+
+    if(!movelib_deltatime)
+        return;
+    v_z = self.velocity_z;
+    old_speed    = vlen(self.velocity);
+    old_dir      = normalize(self.velocity);
+
+    //ggravity      =  (sv_gravity / self.mass) * '0 0 100';
+    acceleration =  (force / self.mass) * dir;
+    //acceleration -= old_dir * (old_speed / self.mass);
+    acceleration -= ggravity;
+
+    if(self.waterlevel > 1)
+    {
+        ffriction = self.water_friction;
+        acceleration += self.buoyancy * '0 0 1';
+    }
+    else
+        if(self.flags & FL_ONGROUND)
+            ffriction = self.ground_friction;
+        else
+            ffriction = self.air_friction;
+
+    acceleration *= ffriction;
+    //self.velocity = self.velocity * (ffriction * movelib_deltatime);
+    self.velocity += acceleration * movelib_deltatime;
+    self.velocity_z = v_z;
+
+}
+*/
+
+void movelib_move_simple(vector newdir,float velo,float blendrate)
+{
+    self.velocity = self.velocity * (1 - blendrate) + (newdir * blendrate) * velo;
+}
+void movelib_beak_simple(float force)
+{
+    float mspeed;
+    vector mdir;
+    float vz;
+
+    mspeed = max(0,vlen(self.velocity) - force);
+    mdir   = normalize(self.velocity);
+    vz = self.velocity_z;
+    self.velocity = mdir * mspeed;
+    self.velocity_z = vz;
+}
+
+
+void movelib_groundalign4point(float spring_length,float spring_up,float blendrate)
+{
+    vector a,b,c,d,e,r,push_angle, ahead,side;
+
+    push_angle_y = 0;
+    r = (self.absmax + self.absmin) * 0.5 + (v_up * spring_up);
+    e = v_up * spring_length;
+
+    // Put springs slightly inside bbox
+    ahead = v_forward * (self.maxs_x * 0.85);
+    side  = v_right   * (self.maxs_y * 0.85);
+
+    a = r + ahead + side;
+    b = r + ahead - side;
+    c = r - ahead + side;
+    d = r - ahead - side;
+
+    traceline(a, a - e,MOVE_NORMAL,self);
+    a_z =  (1 - trace_fraction);
+    r = trace_endpos;
+
+    traceline(b, b - e,MOVE_NORMAL,self);
+    b_z =  (1 - trace_fraction);
+    r += trace_endpos;
+
+    traceline(c, c - e,MOVE_NORMAL,self);
+    c_z =  (1 - trace_fraction);
+    r += trace_endpos;
+
+    traceline(d, d - e,MOVE_NORMAL,self);
+    d_z =  (1 - trace_fraction);
+    r += trace_endpos;
+
+    a_x = r_z;
+    r = self.origin;
+    r_z = r_z;
+
+    push_angle_x = (a_z - c_z) * 45;
+    push_angle_x += (b_z - d_z) * 45;
+
+    push_angle_z = (b_z - a_z) * 45;
+    push_angle_z += (d_z - c_z) * 45;
+
+    //self.angles_x += push_angle_x * 0.95;
+    //self.angles_z += push_angle_z * 0.95;
+
+    self.angles_x = ((1-blendrate) *  self.angles_x)  + (push_angle_x * blendrate);
+    self.angles_z = ((1-blendrate) *  self.angles_z)  + (push_angle_z * blendrate);
+
+    //a = self.origin;
+    setorigin(self,r);
+}
+


Property changes on: trunk/data/qcsrc/server/movelib.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/nexball.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/pathlib/costs.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib/costs.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/pathlib/costs.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,144 +1,144 @@
-float pathlib_g_static(entity parent,vector to, float static_cost)
-{
-    return parent.pathlib_node_g + static_cost;
-}
-
-float pathlib_g_static_water(entity parent,vector to, float static_cost)
-{
-    if(inwater(to))
-        return parent.pathlib_node_g + static_cost * pathlib_movecost_waterfactor;
-    else
-        return parent.pathlib_node_g + static_cost;
-}
-
-float pathlib_g_euclidean(entity parent,vector to, float static_cost)
-{
-    return parent.pathlib_node_g + vlen(parent.origin - to);
-}
-
-float pathlib_g_euclidean_water(entity parent,vector to, float static_cost)
-{
-    if(inwater(to))
-        return parent.pathlib_node_g + vlen(parent.origin - to) * pathlib_movecost_waterfactor;
-    else
-        return parent.pathlib_node_g + vlen(parent.origin - to);
-}
-
-
-/**
-    Manhattan Menas we expect to move up,down left or right
-    No diagonal moves espected. (like moving bewteen city blocks)
-**/
-float pathlib_h_manhattan(vector a,vector b)
-{
-    //h(n) = D * (abs(n.x-goal.x) + abs(n.y-goal.y))
-
-    float h;
-    h  = fabs(a_x - b_x);
-    h += fabs(a_y - b_y);
-    h *= pathlib_gridsize;
-
-    return h;
-}
-
-/**
-    This heuristic consider both stright and disagonal moves
-    to have teh same cost.
-**/
-float pathlib_h_diagonal(vector a,vector b)
-{
-    //h(n) = D * max(abs(n.x-goal.x), abs(n.y-goal.y))
-    float h,x,y;
-
-    x = fabs(a_x - b_x);
-    y = fabs(a_y - b_y);
-    h = pathlib_movecost * max(x,y);
-
-    return h;
-}
-
-/**
-    This heuristic only considers the stright line distance.
-    Will usualy mean a lower H then G meaning A* Will speand more
-    and run slower.
-**/
-float pathlib_h_euclidean(vector a,vector b)
-{
-    return vlen(a - b);
-}
-
-/**
-    This heuristic consider both stright and disagonal moves,
-    But has a separate cost for diagonal moves.
-**/
-float pathlib_h_diagonal2(vector a,vector b)
-{
-    float h_diag,h_str,h,x,y;
-
-    /*
-    h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
-    h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
-    h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
-    */
-
-    x = fabs(a_x - b_x);
-    y = fabs(a_y - b_y);
-
-    h_diag = min(x,y);
-    h_str = x + y;
-
-    h =  pathlib_movecost_diag * h_diag;
-    h += pathlib_movecost * (h_str - 2 * h_diag);
-
-    return h;
-}
-
-/**
-    This heuristic consider both stright and disagonal moves,
-    But has a separate cost for diagonal moves.
-**/
-float pathlib_h_diagonal2sdp(vector preprev,vector prev,vector point,vector end)
-{
-    float h_diag,h_str,h,x,y,z;
-
-    //h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
-    //h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
-    //h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
-
-    x = fabs(point_x - end_x);
-    y = fabs(point_y - end_y);
-    z = fabs(point_z - end_z);
-
-    h_diag = min3(x,y,z);
-    h_str = x + y + z;
-
-    h =  pathlib_movecost_diag * h_diag;
-    h += pathlib_movecost * (h_str - 2 * h_diag);
-
-    float m;
-    vector d1,d2;
-
-    d1 = normalize(preprev - point);
-    d2 = normalize(prev    - point);
-    m = vlen(d1-d2);
-
-    return h * m;
-}
-
-
-float pathlib_h_diagonal3(vector a,vector b)
-{
-    float h_diag,h_str,h,x,y,z;
-
-    x = fabs(a_x - b_x);
-    y = fabs(a_y - b_y);
-    z = fabs(a_z - b_z);
-
-    h_diag = min3(x,y,z);
-    h_str = x + y + z;
-
-    h =  pathlib_movecost_diag * h_diag;
-    h += pathlib_movecost * (h_str - 2 * h_diag);
-
-    return h;
-}
+float pathlib_g_static(entity parent,vector to, float static_cost)
+{
+    return parent.pathlib_node_g + static_cost;
+}
+
+float pathlib_g_static_water(entity parent,vector to, float static_cost)
+{
+    if(inwater(to))
+        return parent.pathlib_node_g + static_cost * pathlib_movecost_waterfactor;
+    else
+        return parent.pathlib_node_g + static_cost;
+}
+
+float pathlib_g_euclidean(entity parent,vector to, float static_cost)
+{
+    return parent.pathlib_node_g + vlen(parent.origin - to);
+}
+
+float pathlib_g_euclidean_water(entity parent,vector to, float static_cost)
+{
+    if(inwater(to))
+        return parent.pathlib_node_g + vlen(parent.origin - to) * pathlib_movecost_waterfactor;
+    else
+        return parent.pathlib_node_g + vlen(parent.origin - to);
+}
+
+
+/**
+    Manhattan Menas we expect to move up,down left or right
+    No diagonal moves espected. (like moving bewteen city blocks)
+**/
+float pathlib_h_manhattan(vector a,vector b)
+{
+    //h(n) = D * (abs(n.x-goal.x) + abs(n.y-goal.y))
+
+    float h;
+    h  = fabs(a_x - b_x);
+    h += fabs(a_y - b_y);
+    h *= pathlib_gridsize;
+
+    return h;
+}
+
+/**
+    This heuristic consider both stright and disagonal moves
+    to have teh same cost.
+**/
+float pathlib_h_diagonal(vector a,vector b)
+{
+    //h(n) = D * max(abs(n.x-goal.x), abs(n.y-goal.y))
+    float h,x,y;
+
+    x = fabs(a_x - b_x);
+    y = fabs(a_y - b_y);
+    h = pathlib_movecost * max(x,y);
+
+    return h;
+}
+
+/**
+    This heuristic only considers the stright line distance.
+    Will usualy mean a lower H then G meaning A* Will speand more
+    and run slower.
+**/
+float pathlib_h_euclidean(vector a,vector b)
+{
+    return vlen(a - b);
+}
+
+/**
+    This heuristic consider both stright and disagonal moves,
+    But has a separate cost for diagonal moves.
+**/
+float pathlib_h_diagonal2(vector a,vector b)
+{
+    float h_diag,h_str,h,x,y;
+
+    /*
+    h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
+    h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
+    h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
+    */
+
+    x = fabs(a_x - b_x);
+    y = fabs(a_y - b_y);
+
+    h_diag = min(x,y);
+    h_str = x + y;
+
+    h =  pathlib_movecost_diag * h_diag;
+    h += pathlib_movecost * (h_str - 2 * h_diag);
+
+    return h;
+}
+
+/**
+    This heuristic consider both stright and disagonal moves,
+    But has a separate cost for diagonal moves.
+**/
+float pathlib_h_diagonal2sdp(vector preprev,vector prev,vector point,vector end)
+{
+    float h_diag,h_str,h,x,y,z;
+
+    //h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
+    //h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
+    //h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
+
+    x = fabs(point_x - end_x);
+    y = fabs(point_y - end_y);
+    z = fabs(point_z - end_z);
+
+    h_diag = min3(x,y,z);
+    h_str = x + y + z;
+
+    h =  pathlib_movecost_diag * h_diag;
+    h += pathlib_movecost * (h_str - 2 * h_diag);
+
+    float m;
+    vector d1,d2;
+
+    d1 = normalize(preprev - point);
+    d2 = normalize(prev    - point);
+    m = vlen(d1-d2);
+
+    return h * m;
+}
+
+
+float pathlib_h_diagonal3(vector a,vector b)
+{
+    float h_diag,h_str,h,x,y,z;
+
+    x = fabs(a_x - b_x);
+    y = fabs(a_y - b_y);
+    z = fabs(a_z - b_z);
+
+    h_diag = min3(x,y,z);
+    h_str = x + y + z;
+
+    h =  pathlib_movecost_diag * h_diag;
+    h += pathlib_movecost * (h_str - 2 * h_diag);
+
+    return h;
+}


Property changes on: trunk/data/qcsrc/server/pathlib/costs.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/pathlib/debug.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib/debug.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/pathlib/debug.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,117 +1,117 @@
-
-void mark_error(vector where,float lifetime);
-void mark_info(vector where,float lifetime);
-entity mark_misc(vector where,float lifetime);
-
-
-void pathlib_showpath(entity start)
-{
-    entity e;
-    e = start;
-    while(e.path_next)
-    {
-        te_lightning1(e,e.origin,e.path_next.origin);
-        e = e.path_next;
-    }
-}
-
-void path_dbg_think()
-{
-    pathlib_showpath(self);
-    self.nextthink = time + 1;
-}
-
-void __showpath2_think()
-{
-    mark_info(self.origin,1);
-    if(self.path_next)
-    {
-        self.path_next.think     = __showpath2_think;
-        self.path_next.nextthink = time + 0.15;
-    }
-    else
-    {
-        self.owner.think     = __showpath2_think;
-        self.owner.nextthink = time + 0.15;
-    }
-}
-
-void pathlib_showpath2(entity path)
-{
-    path.think     = __showpath2_think;
-    path.nextthink = time;
-}
-
-
-void pathlib_showsquare2(entity node ,vector ncolor,float align)
-{
-
-    node.alpha     = 0.25;
-    node.scale     = pathlib_gridsize / 512.001;
-    node.solid     = SOLID_NOT;
-
-    setmodel(node,"models/pathlib/square.md3");
-    setorigin(node,node.origin);
-    node.colormod = ncolor;
-
-    if(align)
-    {
-        traceline(node.origin + '0 0 32',node.origin - '0 0 128',MOVE_WORLDONLY,node);
-        node.angles = vectoangles(trace_plane_normal);
-        node.angles_x -= 90;
-    }
-}
-
-void pathlib_showsquare(vector where,float goodsquare,float lifetime)
-{
-    entity s;
-
-    if(!lifetime)
-        lifetime = time + 30;
-    else
-        lifetime += time;
-
-    s           = spawn();
-    s.alpha     = 0.25;
-    s.think     = SUB_Remove;
-    s.nextthink = lifetime;
-    s.scale     = pathlib_gridsize / 512.001;
-    s.solid     = SOLID_NOT;
-
-    if(goodsquare)
-        setmodel(s,"models/pathlib/goodsquare.md3");
-    else
-        setmodel(s,"models/pathlib/badsquare.md3");
-
-
-
-    traceline(where + '0 0 32',where - '0 0 128',MOVE_WORLDONLY,s);
-
-    s.angles = vectoangles(trace_plane_normal);
-    s.angles_x -= 90;
-    setorigin(s,where);
-}
-
-void pathlib_showedge(vector where,float lifetime,float rot)
-{
-    entity e;
-
-    if(!lifetime)
-        lifetime = time + 30;
-    else
-        lifetime += time;
-
-    e           = spawn();
-    e.alpha     = 0.25;
-    e.think     = SUB_Remove;
-    e.nextthink = lifetime;
-    e.scale     = pathlib_gridsize / 512;
-    e.solid     = SOLID_NOT;
-    setorigin(e,where);
-    setmodel(e,"models/pathlib/edge.md3");
-    //traceline(where + '0 0 32',where - '0 0 128',MOVE_WORLDONLY,e);
-    //e.angles = vectoangles(trace_plane_normal);
-    e.angles_y = rot;
-    //e.angles_x += 90;
-
-}
+
+void mark_error(vector where,float lifetime);
+void mark_info(vector where,float lifetime);
+entity mark_misc(vector where,float lifetime);
+
+
+void pathlib_showpath(entity start)
+{
+    entity e;
+    e = start;
+    while(e.path_next)
+    {
+        te_lightning1(e,e.origin,e.path_next.origin);
+        e = e.path_next;
+    }
+}
+
+void path_dbg_think()
+{
+    pathlib_showpath(self);
+    self.nextthink = time + 1;
+}
+
+void __showpath2_think()
+{
+    mark_info(self.origin,1);
+    if(self.path_next)
+    {
+        self.path_next.think     = __showpath2_think;
+        self.path_next.nextthink = time + 0.15;
+    }
+    else
+    {
+        self.owner.think     = __showpath2_think;
+        self.owner.nextthink = time + 0.15;
+    }
+}
+
+void pathlib_showpath2(entity path)
+{
+    path.think     = __showpath2_think;
+    path.nextthink = time;
+}
+
+
+void pathlib_showsquare2(entity node ,vector ncolor,float align)
+{
+
+    node.alpha     = 0.25;
+    node.scale     = pathlib_gridsize / 512.001;
+    node.solid     = SOLID_NOT;
+
+    setmodel(node,"models/pathlib/square.md3");
+    setorigin(node,node.origin);
+    node.colormod = ncolor;
+
+    if(align)
+    {
+        traceline(node.origin + '0 0 32',node.origin - '0 0 128',MOVE_WORLDONLY,node);
+        node.angles = vectoangles(trace_plane_normal);
+        node.angles_x -= 90;
+    }
+}
+
+void pathlib_showsquare(vector where,float goodsquare,float lifetime)
+{
+    entity s;
+
+    if(!lifetime)
+        lifetime = time + 30;
+    else
+        lifetime += time;
+
+    s           = spawn();
+    s.alpha     = 0.25;
+    s.think     = SUB_Remove;
+    s.nextthink = lifetime;
+    s.scale     = pathlib_gridsize / 512.001;
+    s.solid     = SOLID_NOT;
+
+    if(goodsquare)
+        setmodel(s,"models/pathlib/goodsquare.md3");
+    else
+        setmodel(s,"models/pathlib/badsquare.md3");
+
+
+
+    traceline(where + '0 0 32',where - '0 0 128',MOVE_WORLDONLY,s);
+
+    s.angles = vectoangles(trace_plane_normal);
+    s.angles_x -= 90;
+    setorigin(s,where);
+}
+
+void pathlib_showedge(vector where,float lifetime,float rot)
+{
+    entity e;
+
+    if(!lifetime)
+        lifetime = time + 30;
+    else
+        lifetime += time;
+
+    e           = spawn();
+    e.alpha     = 0.25;
+    e.think     = SUB_Remove;
+    e.nextthink = lifetime;
+    e.scale     = pathlib_gridsize / 512;
+    e.solid     = SOLID_NOT;
+    setorigin(e,where);
+    setmodel(e,"models/pathlib/edge.md3");
+    //traceline(where + '0 0 32',where - '0 0 128',MOVE_WORLDONLY,e);
+    //e.angles = vectoangles(trace_plane_normal);
+    e.angles_y = rot;
+    //e.angles_x += 90;
+
+}


Property changes on: trunk/data/qcsrc/server/pathlib/debug.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/pathlib/expandnode.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib/expandnode.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/pathlib/expandnode.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,196 +1,196 @@
-vector plib_points2[8];
-vector plib_points[8];
-float  plib_fvals[8];
-
-float pathlib_expandnode_starf(entity node, vector start, vector goal)
-{
-    vector where,f,r,t;
-    float i,fc,fc2,c;
-    entity nap;
-
-    where = node.origin;
-
-    f = PLIB_FORWARD * pathlib_gridsize;
-    r = PLIB_RIGHT   * pathlib_gridsize;
-
-    // Forward
-    plib_points[0] = where + f;
-
-    // Back
-    plib_points[1] = where - f;
-
-    // Right
-    plib_points[2] = where + r;
-
-    // Left
-    plib_points[3] = where - r;
-
-    // Forward-right
-    plib_points[4] = where + f + r;
-
-    // Forward-left
-    plib_points[5] = where + f - r;
-
-    // Back-right
-    plib_points[6] = where - f + r;
-
-    // Back-left
-    plib_points[7] = where - f - r;
-
-    for(i=0;i < 8; ++i)
-    {
-        t = plib_points[i];
-        fc  = pathlib_heuristic(t,goal) + pathlib_cost(node,t,pathlib_gridsize);
-        plib_fvals[i] = fc;
-
-    }
-
-    fc = plib_fvals[0];
-    plib_points2[0] = plib_points[0];
-    vector bp;
-    bp = plib_points[0];
-    for(i = 0; i < 8; ++i)
-    {
-        c = 0;
-        nap = pathlib_nodeatpoint(plib_points[i]);
-        if(nap)
-            if(nap.owner == openlist)
-                c = 1;
-        else
-            c = 1;
-
-        if(c)
-        if(plib_fvals[i] < fc)
-        {
-            bp = plib_points[i];
-            fc = plib_fvals[i];
-            plib_points2[fc2] = plib_points[i];
-            ++fc2;
-        }
-
-        /*
-        nap = pathlib_nodeatpoint(plib_points[i]);
-        if(nap)
-        if not nap.owner == closedlist)
-        {
-        }
-        */
-    }
-
-    pathlib_makenode(node,start,bp,goal,pathlib_gridsize);
-
-    for(i = 0; i < 3; ++i)
-    {
-        pathlib_makenode(node,start,plib_points2[i],goal,pathlib_gridsize);
-    }
-
-    return pathlib_open_cnt;
-}
-
-float pathlib_expandnode_star(entity node, vector start, vector goal)
-{
-    vector point,where,f,r;
-
-    where = node.origin;
-
-    f = PLIB_FORWARD * pathlib_gridsize;
-    r = PLIB_RIGHT   * pathlib_gridsize;
-
-    // Forward
-    point = where + f;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Back
-    point = where - f;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Right
-    point = where + r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Left
-    point = where - r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Forward-right
-    point = where + f + r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
-
-    // Forward-left
-    point = where + f - r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
-
-    // Back-right
-    point = where - f + r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
-
-    // Back-left
-    point = where - f - r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
-
-    return pathlib_open_cnt;
-}
-
-float pathlib_expandnode_octagon(entity node, vector start, vector goal)
-{
-    vector point,where,f,r;
-
-    where = node.origin;
-
-    f = PLIB_FORWARD * pathlib_gridsize;
-    r = PLIB_RIGHT   * pathlib_gridsize;
-
-    // Forward
-    point = where + f;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Back
-    point = where - f;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Right
-    point = where + r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Left
-    point = where - r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    f = PLIB_FORWARD * pathlib_gridsize * 0.5;
-    r = PLIB_RIGHT   * pathlib_gridsize * 0.5;
-
-    // Forward-right
-    point = where + f + r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-
-    // Forward-left
-    point = where + f - r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-
-    // Back-right
-    point = where - f + r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Back-left
-    point = where - f - r;
-    pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    return pathlib_open_cnt;
-}
-
-float pathlib_expandnode_box(entity node, vector start, vector goal)
-{
-    vector v;
-
-    for(v_z = node.origin_z - pathlib_gridsize; v_z <= node.origin_z + pathlib_gridsize; v_z += pathlib_gridsize)
-    for(v_y = node.origin_y - pathlib_gridsize; v_y <= node.origin_y + pathlib_gridsize; v_y += pathlib_gridsize)
-    for(v_x = node.origin_x - pathlib_gridsize; v_x <= node.origin_x + pathlib_gridsize; v_x += pathlib_gridsize)
-    {
-        //if(vlen(v - node.origin))
-            pathlib_makenode(node,start,v,goal,pathlib_movecost);
-    }
-
-    return pathlib_open_cnt;
-}
+vector plib_points2[8];
+vector plib_points[8];
+float  plib_fvals[8];
+
+float pathlib_expandnode_starf(entity node, vector start, vector goal)
+{
+    vector where,f,r,t;
+    float i,fc,fc2,c;
+    entity nap;
+
+    where = node.origin;
+
+    f = PLIB_FORWARD * pathlib_gridsize;
+    r = PLIB_RIGHT   * pathlib_gridsize;
+
+    // Forward
+    plib_points[0] = where + f;
+
+    // Back
+    plib_points[1] = where - f;
+
+    // Right
+    plib_points[2] = where + r;
+
+    // Left
+    plib_points[3] = where - r;
+
+    // Forward-right
+    plib_points[4] = where + f + r;
+
+    // Forward-left
+    plib_points[5] = where + f - r;
+
+    // Back-right
+    plib_points[6] = where - f + r;
+
+    // Back-left
+    plib_points[7] = where - f - r;
+
+    for(i=0;i < 8; ++i)
+    {
+        t = plib_points[i];
+        fc  = pathlib_heuristic(t,goal) + pathlib_cost(node,t,pathlib_gridsize);
+        plib_fvals[i] = fc;
+
+    }
+
+    fc = plib_fvals[0];
+    plib_points2[0] = plib_points[0];
+    vector bp;
+    bp = plib_points[0];
+    for(i = 0; i < 8; ++i)
+    {
+        c = 0;
+        nap = pathlib_nodeatpoint(plib_points[i]);
+        if(nap)
+            if(nap.owner == openlist)
+                c = 1;
+        else
+            c = 1;
+
+        if(c)
+        if(plib_fvals[i] < fc)
+        {
+            bp = plib_points[i];
+            fc = plib_fvals[i];
+            plib_points2[fc2] = plib_points[i];
+            ++fc2;
+        }
+
+        /*
+        nap = pathlib_nodeatpoint(plib_points[i]);
+        if(nap)
+        if not nap.owner == closedlist)
+        {
+        }
+        */
+    }
+
+    pathlib_makenode(node,start,bp,goal,pathlib_gridsize);
+
+    for(i = 0; i < 3; ++i)
+    {
+        pathlib_makenode(node,start,plib_points2[i],goal,pathlib_gridsize);
+    }
+
+    return pathlib_open_cnt;
+}
+
+float pathlib_expandnode_star(entity node, vector start, vector goal)
+{
+    vector point,where,f,r;
+
+    where = node.origin;
+
+    f = PLIB_FORWARD * pathlib_gridsize;
+    r = PLIB_RIGHT   * pathlib_gridsize;
+
+    // Forward
+    point = where + f;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Back
+    point = where - f;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Right
+    point = where + r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Left
+    point = where - r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Forward-right
+    point = where + f + r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+    // Forward-left
+    point = where + f - r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+    // Back-right
+    point = where - f + r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+    // Back-left
+    point = where - f - r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+    return pathlib_open_cnt;
+}
+
+float pathlib_expandnode_octagon(entity node, vector start, vector goal)
+{
+    vector point,where,f,r;
+
+    where = node.origin;
+
+    f = PLIB_FORWARD * pathlib_gridsize;
+    r = PLIB_RIGHT   * pathlib_gridsize;
+
+    // Forward
+    point = where + f;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Back
+    point = where - f;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Right
+    point = where + r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Left
+    point = where - r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    f = PLIB_FORWARD * pathlib_gridsize * 0.5;
+    r = PLIB_RIGHT   * pathlib_gridsize * 0.5;
+
+    // Forward-right
+    point = where + f + r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+
+    // Forward-left
+    point = where + f - r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+
+    // Back-right
+    point = where - f + r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Back-left
+    point = where - f - r;
+    pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    return pathlib_open_cnt;
+}
+
+float pathlib_expandnode_box(entity node, vector start, vector goal)
+{
+    vector v;
+
+    for(v_z = node.origin_z - pathlib_gridsize; v_z <= node.origin_z + pathlib_gridsize; v_z += pathlib_gridsize)
+    for(v_y = node.origin_y - pathlib_gridsize; v_y <= node.origin_y + pathlib_gridsize; v_y += pathlib_gridsize)
+    for(v_x = node.origin_x - pathlib_gridsize; v_x <= node.origin_x + pathlib_gridsize; v_x += pathlib_gridsize)
+    {
+        //if(vlen(v - node.origin))
+            pathlib_makenode(node,start,v,goal,pathlib_movecost);
+    }
+
+    return pathlib_open_cnt;
+}


Property changes on: trunk/data/qcsrc/server/pathlib/expandnode.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/pathlib/main.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib/main.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/pathlib/main.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,534 +1,534 @@
-void pathlib_deletepath(entity start)
-{
-    entity e;
-
-    e = findchainentity(owner, start);
-    while(e)
-    {
-        e.think = SUB_Remove;
-        e.nextthink = time;
-        e = e.chain;
-    }
-}
-
-//#define PATHLIB_NODEEXPIRE 0.05
-#define PATHLIB_NODEEXPIRE 20
-
-void dumpnode(entity n)
-{
-    n.is_path_node = FALSE;
-    n.think        = SUB_Remove;
-    n.nextthink    = time;
-}
-
-entity pathlib_mknode(vector where,entity parent)
-{
-    entity node;
-
-    node = pathlib_nodeatpoint(where);
-    if(node)
-    {
-        mark_error(where,60);
-        return node;
-    }
-
-    node = spawn();
-
-    node.think        = SUB_Remove;
-    node.nextthink    = time + PATHLIB_NODEEXPIRE;
-    node.is_path_node = TRUE;
-    node.owner        = openlist;
-    node.path_prev    = parent;
-
-    setmodel(node,"models/pathlib/square.md3");
-    setsize(node,'0 0 0','0 0 0');
-    node.colormod = randomvec() * 2;
-    node.alpha = 0.25;
-    node.scale     = pathlib_gridsize / 512.001;
-
-    //pathlib_showsquare2(node,'1 1 1',0);//(node.medium & CONTENT_EMPTY));
-    setorigin(node, where);
-    node.medium = pointcontents(where);
-
-    mark_info(where,60);
-    //pathlib_showsquare(where,1,30);
-
-
-    ++pathlib_made_cnt;
-    ++pathlib_open_cnt;
-
-    return node;
-}
-
-float pathlib_makenode_adaptive(entity parent,vector start, vector to, vector goal,float cost)
-{
-    entity node;
-    float h,g,f,doedge;
-    vector where;
-
-    ++pathlib_searched_cnt;
-
-    if(inwater(parent.origin))
-    {
-        pathlib_expandnode = pathlib_expandnode_box;
-        pathlib_movenode   = pathlib_swimnode;
-    }
-    else
-    {
-        if(inwater(to))
-        {
-            pathlib_expandnode = pathlib_expandnode_box;
-            pathlib_movenode   = pathlib_walknode;
-        }
-        else
-        {
-            //if(edge_check(parent.origin))
-            //    return 0;
-
-            pathlib_expandnode = pathlib_expandnode_star;
-            pathlib_movenode   = pathlib_walknode;
-            doedge = 1;
-        }
-    }
-
-    node = pathlib_nodeatpoint(to);
-    if(node)
-    {
-        ++pathlib_merge_cnt;
-
-        if(node.owner == openlist)
-        {
-            h = pathlib_heuristic(node.origin,goal);
-            g = pathlib_cost(parent,node.origin,cost);
-            f = g + h;
-
-            if(node.pathlib_node_g > g)
-            {
-                node.pathlib_node_h = h;
-                node.pathlib_node_g = g;
-                node.pathlib_node_f = f;
-
-                node.path_prev = parent;
-            }
-
-            if not (best_open_node)
-                best_open_node = node;
-            else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
-                best_open_node = node;
-        }
-
-        return 1;
-    }
-
-    where = pathlib_movenode(parent.origin,to,0);
-    if not(pathlib_movenode_goodnode)
-        return 0;
-
-    if(pathlib_nodeatpoint(where))
-    {
-        dprint("NAP WHERE :",vtos(where),"\n");
-        dprint("not NAP TO:",vtos(to),"\n");
-        dprint("NAP-NNAP:",ftos(vlen(to-where)),"\n\n");
-        return 0;
-    }
-
-    if(doedge)
-        if not (tile_check(where))
-            return 0;
-
-    h = pathlib_heuristic(where,goal);
-    g = pathlib_cost(parent,where,cost);
-    f = g + h;
-
-
-    /*
-    node = findradius(where,pathlib_gridsize * 0.5);
-    while(node)
-    {
-        if(node.is_path_node == TRUE)
-        {
-            ++pathlib_merge_cnt;
-            if(node.owner == openlist)
-            {
-                if(node.pathlib_node_g > g)
-                {
-                    //pathlib_movenode(where,node.origin,0);
-                    //if(pathlib_movenode_goodnode)
-                    //{
-                        //mark_error(node.origin + '0 0 128',30);
-                        node.pathlib_node_h = h;
-                        node.pathlib_node_g = g;
-                        node.pathlib_node_f = f;
-                        node.path_prev = parent;
-                    //}
-                }
-
-                if not (best_open_node)
-                    best_open_node = node;
-                else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
-                    best_open_node = node;
-            }
-
-            return 1;
-        }
-        node = node.chain;
-    }
-    */
-
-    node = pathlib_mknode(where,parent);
-    node.pathlib_node_h = h;
-    node.pathlib_node_g = g;
-    node.pathlib_node_f = f;
-
-    if not (best_open_node)
-        best_open_node = node;
-    else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
-        best_open_node = node;
-
-    return 1;
-}
-
-entity pathlib_getbestopen()
-{
-    entity node;
-    entity bestnode;
-
-    if(best_open_node)
-    {
-        ++pathlib_bestcash_hits;
-        pathlib_bestcash_saved += pathlib_open_cnt;
-
-        return best_open_node;
-    }
-
-    node = findchainentity(owner,openlist);
-    if(!node)
-        return world;
-
-    bestnode = node;
-    while(node)
-    {
-        ++pathlib_bestopen_seached;
-        if(node.pathlib_node_f < bestnode.pathlib_node_f)
-            bestnode = node;
-
-        node = node.chain;
-    }
-
-    return bestnode;
-}
-
-void pathlib_close_node(entity node,vector goal)
-{
-
-    if(node.owner == closedlist)
-    {
-        dprint("Pathlib: Tried to close a closed node!\n");
-        return;
-    }
-
-    if(node == best_open_node)
-        best_open_node = world;
-
-    ++pathlib_closed_cnt;
-    --pathlib_open_cnt;
-
-    node.owner = closedlist;
-
-    if(vlen(node.origin - goal) <= pathlib_gridsize)
-    {
-        vector goalmove;
-
-        goalmove = pathlib_walknode(node.origin,goal,1);
-        if(pathlib_movenode_goodnode)
-        {
-            goal_node         = node;
-            pathlib_foundgoal = TRUE;
-        }
-    }
-}
-
-void pathlib_cleanup()
-{
-    best_open_node = world;
-
-    //return;
-
-    entity node;
-
-    node = findfloat(world,is_path_node, TRUE);
-    while(node)
-    {
-        /*
-        node.owner = openlist;
-        node.pathlib_node_g = 0;
-        node.pathlib_node_h = 0;
-        node.pathlib_node_f = 0;
-        node.path_prev = world;
-        */
-
-        dumpnode(node);
-        node = findfloat(node,is_path_node, TRUE);
-    }
-
-    if(openlist)
-        remove(openlist);
-
-    if(closedlist)
-        remove(closedlist);
-
-    openlist       = world;
-    closedlist     = world;
-
-}
-
-float Cosine_Interpolate(float a, float b, float x)
-{
-    float ft,f;
-
-	ft = x * 3.1415927;
-	f = (1 - cos(ft)) * 0.5;
-
-	return  a*(1-f) + b*f;
-}
-
-float buildpath_nodefilter_directional(vector n,vector c,vector p)
-{
-    vector d1,d2;
-
-    d2 = normalize(p - c);
-    d1 = normalize(c - n);
-
-    if(vlen(d1-d2) < 0.25)
-    {
-        //mark_error(c,30);
-        return 1;
-    }
-    //mark_info(c,30);
-    return 0;
-}
-
-float buildpath_nodefilter_moveskip(vector n,vector c,vector p)
-{
-    pathlib_walknode(p,n,1);
-    if(pathlib_movenode_goodnode)
-        return 1;
-
-    return 0;
-}
-
-entity path_build(entity next, vector where, entity prev, entity start)
-{
-    entity path;
-
-    if(prev && next)
-        if(buildpath_nodefilter)
-            if(buildpath_nodefilter(next.origin,where,prev.origin))
-                return next;
-
-
-    path           = spawn();
-    path.owner     = start;
-    path.path_next = next;
-
-    setorigin(path,where);
-
-    if(!next)
-        path.classname = "path_end";
-    else
-    {
-        if(!prev)
-            path.classname = "path_start";
-        else
-            path.classname = "path_node";
-    }
-
-    return path;
-}
-
-entity pathlib_astar(vector from,vector to)
-{
-    entity path, start, end, open, n, ln;
-    float ptime, ftime, ctime;
-
-    ptime = gettime(GETTIME_REALTIME);
-    pathlib_starttime = ptime;
-
-    pathlib_cleanup();
-
-    // Select water<->land capable node make/link
-    pathlib_makenode     = pathlib_makenode_adaptive;
-    // Select XYZ cost estimate
-    //pathlib_heuristic    = pathlib_h_diagonal3;
-    pathlib_heuristic    = pathlib_h_diagonal;
-    // Select distance + waterfactor cost
-    pathlib_cost         = pathlib_g_euclidean_water;
-    // Select star expander
-    pathlib_expandnode   = pathlib_expandnode_star;
-    // Select walk simulation movement test
-    pathlib_movenode     = pathlib_walknode;
-    // Filter final nodes by direction
-    buildpath_nodefilter = buildpath_nodefilter_directional;
-    // Filter tiles with cross pattern
-    tile_check = tile_check_cross;
-
-    // If the start is in water we need diffrent settings
-    if(inwater(from))
-    {
-        // Select volumetric node expaner
-        pathlib_expandnode = pathlib_expandnode_box;
-
-        // Water movement test
-        pathlib_movenode   = pathlib_swimnode;
-    }
-
-    if not(openlist)
-        openlist       = spawn();
-
-    if not(closedlist)
-        closedlist     = spawn();
-
-    pathlib_closed_cnt       = 0;
-    pathlib_open_cnt         = 0;
-    pathlib_made_cnt         = 0;
-    pathlib_merge_cnt        = 0;
-    pathlib_searched_cnt     = 0;
-    pathlib_bestopen_seached = 0;
-    pathlib_bestcash_hits    = 0;
-    pathlib_bestcash_saved   = 0;
-
-    pathlib_gridsize       = 128;
-    pathlib_movecost       = pathlib_gridsize;
-    pathlib_movecost_diag  = vlen(('1 1 0' * pathlib_gridsize));
-    pathlib_movecost_waterfactor = 1;
-    pathlib_foundgoal      = 0;
-
-    movenode_boxmax   = self.maxs * 1.25;
-    movenode_boxmin   = self.mins * 1.25;
-
-    movenode_stepsize = 32;
-
-    tile_check_size = 65;
-    tile_check_up   = '0 0 128';
-    tile_check_down = '0 0 128';
-
-    movenode_stepup   = '0 0 36';
-    movenode_maxdrop  = '0 0 128';
-    movenode_boxup    = '0 0 72';
-
-    from_x = fsnap(from_x,pathlib_gridsize);
-    from_y = fsnap(from_y,pathlib_gridsize);
-
-    to_x = fsnap(to_x,pathlib_gridsize);
-    to_y = fsnap(to_y,pathlib_gridsize);
-
-    dprint("AStar init\n");
-    path = pathlib_mknode(from,world);
-    pathlib_close_node(path,to);
-    if(pathlib_foundgoal)
-    {
-        dprint("AStar: Goal found on first node!\n");
-
-        open           = spawn();
-        open.owner     = open;
-        open.classname = "path_end";
-        setorigin(open,path.origin);
-
-        pathlib_cleanup();
-
-        return open;
-    }
-
-    if(pathlib_expandnode(path,from,to) <= 0)
-    {
-        dprint("AStar path fail.\n");
-        pathlib_cleanup();
-
-        return world;
-    }
-
-    best_open_node = pathlib_getbestopen();
-    n = best_open_node;
-    pathlib_close_node(best_open_node,to);
-    if(inwater(n.origin))
-        pathlib_expandnode_box(n,from,to);
-    else
-        pathlib_expandnode_star(n,from,to);
-
-    while(pathlib_open_cnt)
-    {
-        if((gettime(GETTIME_REALTIME) - pathlib_starttime) > pathlib_maxtime)
-        {
-            dprint("Path took to long to compute!\n");
-            dprint("Nodes - created: ", ftos(pathlib_made_cnt),"\n");
-            dprint("Nodes -    open: ", ftos(pathlib_open_cnt),"\n");
-            dprint("Nodes -  merged: ", ftos(pathlib_merge_cnt),"\n");
-            dprint("Nodes -  closed: ", ftos(pathlib_closed_cnt),"\n");
-
-            pathlib_cleanup();
-            return world;
-        }
-
-        best_open_node = pathlib_getbestopen();
-        n = best_open_node;
-        pathlib_close_node(best_open_node,to);
-
-        if(inwater(n.origin))
-            pathlib_expandnode_box(n,from,to);
-        else
-            pathlib_expandnode(n,from,to);
-
-        if(pathlib_foundgoal)
-        {
-            dprint("Target found. Rebuilding and filtering path...\n");
-            ftime = gettime(GETTIME_REALTIME);
-            ptime = ftime - ptime;
-
-            start = path_build(world,path.origin,world,world);
-            end   = path_build(world,goal_node.origin,world,start);
-            ln    = end;
-
-            open = goal_node;
-            for(open = goal_node; open.path_prev != path; open = open.path_prev)
-            {
-                n    = path_build(ln,open.origin,open.path_prev,start);
-                ln.path_prev = n;
-                ln = n;
-            }
-            start.path_next = n;
-            n.path_prev = start;
-            ftime = gettime(GETTIME_REALTIME) - ftime;
-
-            ctime = gettime(GETTIME_REALTIME);
-            pathlib_cleanup();
-            ctime = gettime(GETTIME_REALTIME) - ctime;
-
-
-#ifdef DEBUGPATHING
-            pathlib_showpath2(start);
-
-            dprint("Time used -      pathfinding: ", ftos(ptime),"\n");
-            dprint("Time used - rebuild & filter: ", ftos(ftime),"\n");
-            dprint("Time used -          cleanup: ", ftos(ctime),"\n");
-            dprint("Time used -            total: ", ftos(ptime + ftime + ctime),"\n");
-            dprint("Time used -         # frames: ", ftos(ceil((ptime + ftime + ctime) / sys_ticrate)),"\n\n");
-            dprint("Nodes -         created: ", ftos(pathlib_made_cnt),"\n");
-            dprint("Nodes -            open: ", ftos(pathlib_open_cnt),"\n");
-            dprint("Nodes -          merged: ", ftos(pathlib_merge_cnt),"\n");
-            dprint("Nodes -          closed: ", ftos(pathlib_closed_cnt),"\n");
-            dprint("Nodes -        searched: ", ftos(pathlib_searched_cnt),"\n");
-            dprint("Nodes bestopen searched: ", ftos(pathlib_bestopen_seached),"\n");
-            dprint("Nodes bestcash -   hits: ", ftos(pathlib_bestcash_hits),"\n");
-            dprint("Nodes bestcash -   save: ", ftos(pathlib_bestcash_saved),"\n");
-            dprint("AStar done.\n");
-#endif
-            return start;
-        }
-    }
-
-    dprint("A* Faild to find a path! Try a smaller gridsize.\n");
-
-    pathlib_cleanup();
-
-    return world;
-}
+void pathlib_deletepath(entity start)
+{
+    entity e;
+
+    e = findchainentity(owner, start);
+    while(e)
+    {
+        e.think = SUB_Remove;
+        e.nextthink = time;
+        e = e.chain;
+    }
+}
+
+//#define PATHLIB_NODEEXPIRE 0.05
+#define PATHLIB_NODEEXPIRE 20
+
+void dumpnode(entity n)
+{
+    n.is_path_node = FALSE;
+    n.think        = SUB_Remove;
+    n.nextthink    = time;
+}
+
+entity pathlib_mknode(vector where,entity parent)
+{
+    entity node;
+
+    node = pathlib_nodeatpoint(where);
+    if(node)
+    {
+        mark_error(where,60);
+        return node;
+    }
+
+    node = spawn();
+
+    node.think        = SUB_Remove;
+    node.nextthink    = time + PATHLIB_NODEEXPIRE;
+    node.is_path_node = TRUE;
+    node.owner        = openlist;
+    node.path_prev    = parent;
+
+    setmodel(node,"models/pathlib/square.md3");
+    setsize(node,'0 0 0','0 0 0');
+    node.colormod = randomvec() * 2;
+    node.alpha = 0.25;
+    node.scale     = pathlib_gridsize / 512.001;
+
+    //pathlib_showsquare2(node,'1 1 1',0);//(node.medium & CONTENT_EMPTY));
+    setorigin(node, where);
+    node.medium = pointcontents(where);
+
+    mark_info(where,60);
+    //pathlib_showsquare(where,1,30);
+
+
+    ++pathlib_made_cnt;
+    ++pathlib_open_cnt;
+
+    return node;
+}
+
+float pathlib_makenode_adaptive(entity parent,vector start, vector to, vector goal,float cost)
+{
+    entity node;
+    float h,g,f,doedge;
+    vector where;
+
+    ++pathlib_searched_cnt;
+
+    if(inwater(parent.origin))
+    {
+        pathlib_expandnode = pathlib_expandnode_box;
+        pathlib_movenode   = pathlib_swimnode;
+    }
+    else
+    {
+        if(inwater(to))
+        {
+            pathlib_expandnode = pathlib_expandnode_box;
+            pathlib_movenode   = pathlib_walknode;
+        }
+        else
+        {
+            //if(edge_check(parent.origin))
+            //    return 0;
+
+            pathlib_expandnode = pathlib_expandnode_star;
+            pathlib_movenode   = pathlib_walknode;
+            doedge = 1;
+        }
+    }
+
+    node = pathlib_nodeatpoint(to);
+    if(node)
+    {
+        ++pathlib_merge_cnt;
+
+        if(node.owner == openlist)
+        {
+            h = pathlib_heuristic(node.origin,goal);
+            g = pathlib_cost(parent,node.origin,cost);
+            f = g + h;
+
+            if(node.pathlib_node_g > g)
+            {
+                node.pathlib_node_h = h;
+                node.pathlib_node_g = g;
+                node.pathlib_node_f = f;
+
+                node.path_prev = parent;
+            }
+
+            if not (best_open_node)
+                best_open_node = node;
+            else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
+                best_open_node = node;
+        }
+
+        return 1;
+    }
+
+    where = pathlib_movenode(parent.origin,to,0);
+    if not(pathlib_movenode_goodnode)
+        return 0;
+
+    if(pathlib_nodeatpoint(where))
+    {
+        dprint("NAP WHERE :",vtos(where),"\n");
+        dprint("not NAP TO:",vtos(to),"\n");
+        dprint("NAP-NNAP:",ftos(vlen(to-where)),"\n\n");
+        return 0;
+    }
+
+    if(doedge)
+        if not (tile_check(where))
+            return 0;
+
+    h = pathlib_heuristic(where,goal);
+    g = pathlib_cost(parent,where,cost);
+    f = g + h;
+
+
+    /*
+    node = findradius(where,pathlib_gridsize * 0.5);
+    while(node)
+    {
+        if(node.is_path_node == TRUE)
+        {
+            ++pathlib_merge_cnt;
+            if(node.owner == openlist)
+            {
+                if(node.pathlib_node_g > g)
+                {
+                    //pathlib_movenode(where,node.origin,0);
+                    //if(pathlib_movenode_goodnode)
+                    //{
+                        //mark_error(node.origin + '0 0 128',30);
+                        node.pathlib_node_h = h;
+                        node.pathlib_node_g = g;
+                        node.pathlib_node_f = f;
+                        node.path_prev = parent;
+                    //}
+                }
+
+                if not (best_open_node)
+                    best_open_node = node;
+                else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
+                    best_open_node = node;
+            }
+
+            return 1;
+        }
+        node = node.chain;
+    }
+    */
+
+    node = pathlib_mknode(where,parent);
+    node.pathlib_node_h = h;
+    node.pathlib_node_g = g;
+    node.pathlib_node_f = f;
+
+    if not (best_open_node)
+        best_open_node = node;
+    else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
+        best_open_node = node;
+
+    return 1;
+}
+
+entity pathlib_getbestopen()
+{
+    entity node;
+    entity bestnode;
+
+    if(best_open_node)
+    {
+        ++pathlib_bestcash_hits;
+        pathlib_bestcash_saved += pathlib_open_cnt;
+
+        return best_open_node;
+    }
+
+    node = findchainentity(owner,openlist);
+    if(!node)
+        return world;
+
+    bestnode = node;
+    while(node)
+    {
+        ++pathlib_bestopen_seached;
+        if(node.pathlib_node_f < bestnode.pathlib_node_f)
+            bestnode = node;
+
+        node = node.chain;
+    }
+
+    return bestnode;
+}
+
+void pathlib_close_node(entity node,vector goal)
+{
+
+    if(node.owner == closedlist)
+    {
+        dprint("Pathlib: Tried to close a closed node!\n");
+        return;
+    }
+
+    if(node == best_open_node)
+        best_open_node = world;
+
+    ++pathlib_closed_cnt;
+    --pathlib_open_cnt;
+
+    node.owner = closedlist;
+
+    if(vlen(node.origin - goal) <= pathlib_gridsize)
+    {
+        vector goalmove;
+
+        goalmove = pathlib_walknode(node.origin,goal,1);
+        if(pathlib_movenode_goodnode)
+        {
+            goal_node         = node;
+            pathlib_foundgoal = TRUE;
+        }
+    }
+}
+
+void pathlib_cleanup()
+{
+    best_open_node = world;
+
+    //return;
+
+    entity node;
+
+    node = findfloat(world,is_path_node, TRUE);
+    while(node)
+    {
+        /*
+        node.owner = openlist;
+        node.pathlib_node_g = 0;
+        node.pathlib_node_h = 0;
+        node.pathlib_node_f = 0;
+        node.path_prev = world;
+        */
+
+        dumpnode(node);
+        node = findfloat(node,is_path_node, TRUE);
+    }
+
+    if(openlist)
+        remove(openlist);
+
+    if(closedlist)
+        remove(closedlist);
+
+    openlist       = world;
+    closedlist     = world;
+
+}
+
+float Cosine_Interpolate(float a, float b, float x)
+{
+    float ft,f;
+
+	ft = x * 3.1415927;
+	f = (1 - cos(ft)) * 0.5;
+
+	return  a*(1-f) + b*f;
+}
+
+float buildpath_nodefilter_directional(vector n,vector c,vector p)
+{
+    vector d1,d2;
+
+    d2 = normalize(p - c);
+    d1 = normalize(c - n);
+
+    if(vlen(d1-d2) < 0.25)
+    {
+        //mark_error(c,30);
+        return 1;
+    }
+    //mark_info(c,30);
+    return 0;
+}
+
+float buildpath_nodefilter_moveskip(vector n,vector c,vector p)
+{
+    pathlib_walknode(p,n,1);
+    if(pathlib_movenode_goodnode)
+        return 1;
+
+    return 0;
+}
+
+entity path_build(entity next, vector where, entity prev, entity start)
+{
+    entity path;
+
+    if(prev && next)
+        if(buildpath_nodefilter)
+            if(buildpath_nodefilter(next.origin,where,prev.origin))
+                return next;
+
+
+    path           = spawn();
+    path.owner     = start;
+    path.path_next = next;
+
+    setorigin(path,where);
+
+    if(!next)
+        path.classname = "path_end";
+    else
+    {
+        if(!prev)
+            path.classname = "path_start";
+        else
+            path.classname = "path_node";
+    }
+
+    return path;
+}
+
+entity pathlib_astar(vector from,vector to)
+{
+    entity path, start, end, open, n, ln;
+    float ptime, ftime, ctime;
+
+    ptime = gettime(GETTIME_REALTIME);
+    pathlib_starttime = ptime;
+
+    pathlib_cleanup();
+
+    // Select water<->land capable node make/link
+    pathlib_makenode     = pathlib_makenode_adaptive;
+    // Select XYZ cost estimate
+    //pathlib_heuristic    = pathlib_h_diagonal3;
+    pathlib_heuristic    = pathlib_h_diagonal;
+    // Select distance + waterfactor cost
+    pathlib_cost         = pathlib_g_euclidean_water;
+    // Select star expander
+    pathlib_expandnode   = pathlib_expandnode_star;
+    // Select walk simulation movement test
+    pathlib_movenode     = pathlib_walknode;
+    // Filter final nodes by direction
+    buildpath_nodefilter = buildpath_nodefilter_directional;
+    // Filter tiles with cross pattern
+    tile_check = tile_check_cross;
+
+    // If the start is in water we need diffrent settings
+    if(inwater(from))
+    {
+        // Select volumetric node expaner
+        pathlib_expandnode = pathlib_expandnode_box;
+
+        // Water movement test
+        pathlib_movenode   = pathlib_swimnode;
+    }
+
+    if not(openlist)
+        openlist       = spawn();
+
+    if not(closedlist)
+        closedlist     = spawn();
+
+    pathlib_closed_cnt       = 0;
+    pathlib_open_cnt         = 0;
+    pathlib_made_cnt         = 0;
+    pathlib_merge_cnt        = 0;
+    pathlib_searched_cnt     = 0;
+    pathlib_bestopen_seached = 0;
+    pathlib_bestcash_hits    = 0;
+    pathlib_bestcash_saved   = 0;
+
+    pathlib_gridsize       = 128;
+    pathlib_movecost       = pathlib_gridsize;
+    pathlib_movecost_diag  = vlen(('1 1 0' * pathlib_gridsize));
+    pathlib_movecost_waterfactor = 1;
+    pathlib_foundgoal      = 0;
+
+    movenode_boxmax   = self.maxs * 1.25;
+    movenode_boxmin   = self.mins * 1.25;
+
+    movenode_stepsize = 32;
+
+    tile_check_size = 65;
+    tile_check_up   = '0 0 128';
+    tile_check_down = '0 0 128';
+
+    movenode_stepup   = '0 0 36';
+    movenode_maxdrop  = '0 0 128';
+    movenode_boxup    = '0 0 72';
+
+    from_x = fsnap(from_x,pathlib_gridsize);
+    from_y = fsnap(from_y,pathlib_gridsize);
+
+    to_x = fsnap(to_x,pathlib_gridsize);
+    to_y = fsnap(to_y,pathlib_gridsize);
+
+    dprint("AStar init\n");
+    path = pathlib_mknode(from,world);
+    pathlib_close_node(path,to);
+    if(pathlib_foundgoal)
+    {
+        dprint("AStar: Goal found on first node!\n");
+
+        open           = spawn();
+        open.owner     = open;
+        open.classname = "path_end";
+        setorigin(open,path.origin);
+
+        pathlib_cleanup();
+
+        return open;
+    }
+
+    if(pathlib_expandnode(path,from,to) <= 0)
+    {
+        dprint("AStar path fail.\n");
+        pathlib_cleanup();
+
+        return world;
+    }
+
+    best_open_node = pathlib_getbestopen();
+    n = best_open_node;
+    pathlib_close_node(best_open_node,to);
+    if(inwater(n.origin))
+        pathlib_expandnode_box(n,from,to);
+    else
+        pathlib_expandnode_star(n,from,to);
+
+    while(pathlib_open_cnt)
+    {
+        if((gettime(GETTIME_REALTIME) - pathlib_starttime) > pathlib_maxtime)
+        {
+            dprint("Path took to long to compute!\n");
+            dprint("Nodes - created: ", ftos(pathlib_made_cnt),"\n");
+            dprint("Nodes -    open: ", ftos(pathlib_open_cnt),"\n");
+            dprint("Nodes -  merged: ", ftos(pathlib_merge_cnt),"\n");
+            dprint("Nodes -  closed: ", ftos(pathlib_closed_cnt),"\n");
+
+            pathlib_cleanup();
+            return world;
+        }
+
+        best_open_node = pathlib_getbestopen();
+        n = best_open_node;
+        pathlib_close_node(best_open_node,to);
+
+        if(inwater(n.origin))
+            pathlib_expandnode_box(n,from,to);
+        else
+            pathlib_expandnode(n,from,to);
+
+        if(pathlib_foundgoal)
+        {
+            dprint("Target found. Rebuilding and filtering path...\n");
+            ftime = gettime(GETTIME_REALTIME);
+            ptime = ftime - ptime;
+
+            start = path_build(world,path.origin,world,world);
+            end   = path_build(world,goal_node.origin,world,start);
+            ln    = end;
+
+            open = goal_node;
+            for(open = goal_node; open.path_prev != path; open = open.path_prev)
+            {
+                n    = path_build(ln,open.origin,open.path_prev,start);
+                ln.path_prev = n;
+                ln = n;
+            }
+            start.path_next = n;
+            n.path_prev = start;
+            ftime = gettime(GETTIME_REALTIME) - ftime;
+
+            ctime = gettime(GETTIME_REALTIME);
+            pathlib_cleanup();
+            ctime = gettime(GETTIME_REALTIME) - ctime;
+
+
+#ifdef DEBUGPATHING
+            pathlib_showpath2(start);
+
+            dprint("Time used -      pathfinding: ", ftos(ptime),"\n");
+            dprint("Time used - rebuild & filter: ", ftos(ftime),"\n");
+            dprint("Time used -          cleanup: ", ftos(ctime),"\n");
+            dprint("Time used -            total: ", ftos(ptime + ftime + ctime),"\n");
+            dprint("Time used -         # frames: ", ftos(ceil((ptime + ftime + ctime) / sys_ticrate)),"\n\n");
+            dprint("Nodes -         created: ", ftos(pathlib_made_cnt),"\n");
+            dprint("Nodes -            open: ", ftos(pathlib_open_cnt),"\n");
+            dprint("Nodes -          merged: ", ftos(pathlib_merge_cnt),"\n");
+            dprint("Nodes -          closed: ", ftos(pathlib_closed_cnt),"\n");
+            dprint("Nodes -        searched: ", ftos(pathlib_searched_cnt),"\n");
+            dprint("Nodes bestopen searched: ", ftos(pathlib_bestopen_seached),"\n");
+            dprint("Nodes bestcash -   hits: ", ftos(pathlib_bestcash_hits),"\n");
+            dprint("Nodes bestcash -   save: ", ftos(pathlib_bestcash_saved),"\n");
+            dprint("AStar done.\n");
+#endif
+            return start;
+        }
+    }
+
+    dprint("A* Faild to find a path! Try a smaller gridsize.\n");
+
+    pathlib_cleanup();
+
+    return world;
+}


Property changes on: trunk/data/qcsrc/server/pathlib/main.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/pathlib/movenode.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib/movenode.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/pathlib/movenode.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,126 +1,126 @@
-vector pathlib_wateroutnode(vector start,vector end)
-{
-    vector surface;
-
-    pathlib_movenode_goodnode = 0;
-
-    end_x = fsnap(end_x, pathlib_gridsize);
-    end_y = fsnap(end_y, pathlib_gridsize);
-
-    traceline(end + ('0 0 0.25' * pathlib_gridsize),end - ('0 0 1' * pathlib_gridsize),MOVE_WORLDONLY,self);
-    end = trace_endpos;
-
-    if not(pointcontents(end - '0 0 1') == CONTENT_SOLID)
-        return end;
-
-    for(surface = start ; surface_z < (end_z + 32); ++surface_z)
-    {
-        if(pointcontents(surface) == CONTENT_EMPTY)
-            break;
-    }
-
-    if(pointcontents(surface + '0 0 1') != CONTENT_EMPTY)
-        return end;
-
-    tracebox(start + '0 0 64', movenode_boxmin,movenode_boxmax, end + '0 0 64', MOVE_WORLDONLY, self);
-    if(trace_fraction == 1)
-        pathlib_movenode_goodnode = 1;
-
-    if(fabs(surface_z - end_z) > 32)
-        pathlib_movenode_goodnode = 0;
-
-    return end;
-}
-
-vector pathlib_swimnode(vector start,vector end)
-{
-    pathlib_movenode_goodnode = 0;
-
-    if(pointcontents(start) != CONTENT_WATER)
-        return end;
-
-    end_x = fsnap(end_x, pathlib_gridsize);
-    end_y = fsnap(end_y, pathlib_gridsize);
-
-    if(pointcontents(end) == CONTENT_EMPTY)
-        return pathlib_wateroutnode( start, end);
-
-    tracebox(start, movenode_boxmin,movenode_boxmax, end, MOVE_WORLDONLY, self);
-    if(trace_fraction == 1)
-        pathlib_movenode_goodnode = 1;
-
-    return end;
-}
-
-vector pathlib_flynode(vector start,vector end)
-{
-    pathlib_movenode_goodnode = 0;
-
-    end_x = fsnap(end_x, pathlib_gridsize);
-    end_y = fsnap(end_y, pathlib_gridsize);
-
-    tracebox(start, movenode_boxmin,movenode_boxmax, end, MOVE_WORLDONLY, self);
-    if(trace_fraction == 1)
-        pathlib_movenode_goodnode = 1;
-
-    return end;
-}
-
-vector pathlib_walknode(vector start,vector end,float doedge)
-{
-    vector direction,point,last_point,s,e;
-    float steps, distance, i;
-
-    pathlib_movenode_goodnode = 0;
-
-    end_x = fsnap(end_x,pathlib_gridsize);
-    end_y = fsnap(end_y,pathlib_gridsize);
-    start_x = fsnap(start_x,pathlib_gridsize);
-    start_y = fsnap(start_y,pathlib_gridsize);
-
-    // Find the floor
-    traceline(start + movenode_stepup, start - movenode_maxdrop,MOVE_WORLDONLY,self);
-    if(trace_fraction == 1.0)
-        return trace_endpos;
-
-    start = trace_endpos;
-
-    // Find the direcion, without Z
-    s   = start; e   = end;
-    //e_z = 0; s_z = 0;
-    direction = normalize(e - s);
-
-    distance  = vlen(start - end);
-    steps     = rint(distance / movenode_stepsize);
-
-    last_point = start;
-    for(i = 1; i < steps; ++i)
-    {
-        point = last_point + (direction * movenode_stepsize);
-        traceline(point + movenode_stepup,point - movenode_maxdrop,MOVE_WORLDONLY,self);
-        if(trace_fraction == 1.0)
-            return trace_endpos;
-
-        last_point = trace_endpos;
-    }
-
-    point = last_point + (direction * movenode_stepsize);
-    point_x = fsnap(point_x,pathlib_gridsize);
-    point_y = fsnap(point_y,pathlib_gridsize);
-
-    //dprint("end_x:  ",ftos(end_x),  "  end_y:  ",ftos(end_y),"\n");
-    //dprint("point_x:",ftos(point_x),"  point_y:",ftos(point_y),"\n\n");
-
-    traceline(point + movenode_stepup, point - movenode_maxdrop,MOVE_WORLDONLY,self);
-    if(trace_fraction == 1.0)
-        return trace_endpos;
-
-    last_point = trace_endpos;
-
-    tracebox(start + movenode_boxup, movenode_boxmin,movenode_boxmax, last_point + movenode_boxup, MOVE_WORLDONLY, self);
-    if(trace_fraction != 1.0)
-        return trace_endpos;
-
-    pathlib_movenode_goodnode = 1;
-    return last_point;
-}
+vector pathlib_wateroutnode(vector start,vector end)
+{
+    vector surface;
+
+    pathlib_movenode_goodnode = 0;
+
+    end_x = fsnap(end_x, pathlib_gridsize);
+    end_y = fsnap(end_y, pathlib_gridsize);
+
+    traceline(end + ('0 0 0.25' * pathlib_gridsize),end - ('0 0 1' * pathlib_gridsize),MOVE_WORLDONLY,self);
+    end = trace_endpos;
+
+    if not(pointcontents(end - '0 0 1') == CONTENT_SOLID)
+        return end;
+
+    for(surface = start ; surface_z < (end_z + 32); ++surface_z)
+    {
+        if(pointcontents(surface) == CONTENT_EMPTY)
+            break;
+    }
+
+    if(pointcontents(surface + '0 0 1') != CONTENT_EMPTY)
+        return end;
+
+    tracebox(start + '0 0 64', movenode_boxmin,movenode_boxmax, end + '0 0 64', MOVE_WORLDONLY, self);
+    if(trace_fraction == 1)
+        pathlib_movenode_goodnode = 1;
+
+    if(fabs(surface_z - end_z) > 32)
+        pathlib_movenode_goodnode = 0;
+
+    return end;
+}
+
+vector pathlib_swimnode(vector start,vector end)
+{
+    pathlib_movenode_goodnode = 0;
+
+    if(pointcontents(start) != CONTENT_WATER)
+        return end;
+
+    end_x = fsnap(end_x, pathlib_gridsize);
+    end_y = fsnap(end_y, pathlib_gridsize);
+
+    if(pointcontents(end) == CONTENT_EMPTY)
+        return pathlib_wateroutnode( start, end);
+
+    tracebox(start, movenode_boxmin,movenode_boxmax, end, MOVE_WORLDONLY, self);
+    if(trace_fraction == 1)
+        pathlib_movenode_goodnode = 1;
+
+    return end;
+}
+
+vector pathlib_flynode(vector start,vector end)
+{
+    pathlib_movenode_goodnode = 0;
+
+    end_x = fsnap(end_x, pathlib_gridsize);
+    end_y = fsnap(end_y, pathlib_gridsize);
+
+    tracebox(start, movenode_boxmin,movenode_boxmax, end, MOVE_WORLDONLY, self);
+    if(trace_fraction == 1)
+        pathlib_movenode_goodnode = 1;
+
+    return end;
+}
+
+vector pathlib_walknode(vector start,vector end,float doedge)
+{
+    vector direction,point,last_point,s,e;
+    float steps, distance, i;
+
+    pathlib_movenode_goodnode = 0;
+
+    end_x = fsnap(end_x,pathlib_gridsize);
+    end_y = fsnap(end_y,pathlib_gridsize);
+    start_x = fsnap(start_x,pathlib_gridsize);
+    start_y = fsnap(start_y,pathlib_gridsize);
+
+    // Find the floor
+    traceline(start + movenode_stepup, start - movenode_maxdrop,MOVE_WORLDONLY,self);
+    if(trace_fraction == 1.0)
+        return trace_endpos;
+
+    start = trace_endpos;
+
+    // Find the direcion, without Z
+    s   = start; e   = end;
+    //e_z = 0; s_z = 0;
+    direction = normalize(e - s);
+
+    distance  = vlen(start - end);
+    steps     = rint(distance / movenode_stepsize);
+
+    last_point = start;
+    for(i = 1; i < steps; ++i)
+    {
+        point = last_point + (direction * movenode_stepsize);
+        traceline(point + movenode_stepup,point - movenode_maxdrop,MOVE_WORLDONLY,self);
+        if(trace_fraction == 1.0)
+            return trace_endpos;
+
+        last_point = trace_endpos;
+    }
+
+    point = last_point + (direction * movenode_stepsize);
+    point_x = fsnap(point_x,pathlib_gridsize);
+    point_y = fsnap(point_y,pathlib_gridsize);
+
+    //dprint("end_x:  ",ftos(end_x),  "  end_y:  ",ftos(end_y),"\n");
+    //dprint("point_x:",ftos(point_x),"  point_y:",ftos(point_y),"\n\n");
+
+    traceline(point + movenode_stepup, point - movenode_maxdrop,MOVE_WORLDONLY,self);
+    if(trace_fraction == 1.0)
+        return trace_endpos;
+
+    last_point = trace_endpos;
+
+    tracebox(start + movenode_boxup, movenode_boxmin,movenode_boxmax, last_point + movenode_boxup, MOVE_WORLDONLY, self);
+    if(trace_fraction != 1.0)
+        return trace_endpos;
+
+    pathlib_movenode_goodnode = 1;
+    return last_point;
+}


Property changes on: trunk/data/qcsrc/server/pathlib/movenode.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/pathlib/pathlib.qh
===================================================================
--- trunk/data/qcsrc/server/pathlib/pathlib.qh	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/pathlib/pathlib.qh	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,99 +1,99 @@
-.entity path_next;
-.entity path_prev;
-
-#define inwater(point) (pointcontents(point) == CONTENT_WATER)
-#define medium spawnshieldtime
-
-#define PLIB_FORWARD '0 1 0'
-//#define PLIB_BACK    '0 -1 0'
-#define PLIB_RIGHT   '1 0 0'
-//#define PLIB_LEFT    '-1 0 0'
-
-#define DEBUGPATHING
-#ifdef DEBUGPATHING
-void pathlib_showpath(entity start);
-void pathlib_showpath2(entity path);
-#endif
-
-entity openlist;
-entity closedlist;
-entity goal_node;
-
-.float is_path_node;
-.float pathlib_node_g;
-.float pathlib_node_h;
-.float pathlib_node_f;
-
-float pathlib_open_cnt;
-float pathlib_closed_cnt;
-float pathlib_made_cnt;
-float pathlib_merge_cnt;
-float pathlib_searched_cnt;
-float pathlib_bestopen_seached;
-float pathlib_bestcash_hits;
-float pathlib_bestcash_saved;
-float pathlib_gridsize;
-float pathlib_movecost;
-float pathlib_movecost_diag;
-float pathlib_movecost_waterfactor;
-float pathlib_foundgoal;
-
-float pathlib_starttime;
-#define pathlib_maxtime 5
-
-entity best_open_node;
-
-vector tile_check_up;
-vector tile_check_down;
-float  tile_check_size;
-float      tile_check_cross(vector where);
-float      tile_check_plus(vector where);
-float      tile_check_star(vector where);
-var float  tile_check(vector where);
-
-float  movenode_stepsize;
-vector movenode_stepup;
-vector movenode_maxdrop;
-vector movenode_boxup;
-vector movenode_boxmax;
-vector movenode_boxmin;
-float  pathlib_movenode_goodnode;
-
-vector     pathlib_wateroutnode(vector start, vector end);
-vector     pathlib_swimnode(vector start, vector end);
-vector     pathlib_flynode(vector start, vector end);
-vector     pathlib_walknode(vector start, vector end, float doedge);
-var vector pathlib_movenode(vector start, vector end, float doedge);
-
-float      pathlib_expandnode_star(entity node, vector start, vector goal);
-float      pathlib_expandnode_box(entity node, vector start, vector goal);
-float      pathlib_expandnode_octagon(entity node, vector start, vector goal);
-var float  pathlib_expandnode(entity node, vector start, vector goal);
-
-float      pathlib_g_static(entity parent, vector to, float static_cost);
-float      pathlib_g_static_water(entity parent, vector to, float static_cost);
-float      pathlib_g_euclidean(entity parent, vector to, float static_cost);
-float      pathlib_g_euclidean_water(entity parent, vector to, float static_cost);
-var float  pathlib_cost(entity parent, vector to, float static_cost);
-
-float      pathlib_h_manhattan(vector a, vector b);
-float      pathlib_h_diagonal(vector a, vector b);
-float      pathlib_h_euclidean(vector a,vector b);
-float      pathlib_h_diagonal2(vector a, vector b);
-float      pathlib_h_diagonal3(vector a, vector b);
-float      pathlib_h_diagonal2sdp(vector preprev, vector prev, vector point, vector end);
-var float  pathlib_heuristic(vector from, vector to);
-
-var float  pathlib_makenode(entity parent,vector start, vector to, vector goal,float cost);
-var float  buildpath_nodefilter(vector n,vector c,vector p);
-
-
-#ifdef DEBUGPATHING
-#include "debug.qc"
-#endif
-
-#include "utility.qc"
-#include "movenode.qc"
-#include "costs.qc"
-#include "expandnode.qc"
-#include "main.qc"
+.entity path_next;
+.entity path_prev;
+
+#define inwater(point) (pointcontents(point) == CONTENT_WATER)
+#define medium spawnshieldtime
+
+#define PLIB_FORWARD '0 1 0'
+//#define PLIB_BACK    '0 -1 0'
+#define PLIB_RIGHT   '1 0 0'
+//#define PLIB_LEFT    '-1 0 0'
+
+#define DEBUGPATHING
+#ifdef DEBUGPATHING
+void pathlib_showpath(entity start);
+void pathlib_showpath2(entity path);
+#endif
+
+entity openlist;
+entity closedlist;
+entity goal_node;
+
+.float is_path_node;
+.float pathlib_node_g;
+.float pathlib_node_h;
+.float pathlib_node_f;
+
+float pathlib_open_cnt;
+float pathlib_closed_cnt;
+float pathlib_made_cnt;
+float pathlib_merge_cnt;
+float pathlib_searched_cnt;
+float pathlib_bestopen_seached;
+float pathlib_bestcash_hits;
+float pathlib_bestcash_saved;
+float pathlib_gridsize;
+float pathlib_movecost;
+float pathlib_movecost_diag;
+float pathlib_movecost_waterfactor;
+float pathlib_foundgoal;
+
+float pathlib_starttime;
+#define pathlib_maxtime 5
+
+entity best_open_node;
+
+vector tile_check_up;
+vector tile_check_down;
+float  tile_check_size;
+float      tile_check_cross(vector where);
+float      tile_check_plus(vector where);
+float      tile_check_star(vector where);
+var float  tile_check(vector where);
+
+float  movenode_stepsize;
+vector movenode_stepup;
+vector movenode_maxdrop;
+vector movenode_boxup;
+vector movenode_boxmax;
+vector movenode_boxmin;
+float  pathlib_movenode_goodnode;
+
+vector     pathlib_wateroutnode(vector start, vector end);
+vector     pathlib_swimnode(vector start, vector end);
+vector     pathlib_flynode(vector start, vector end);
+vector     pathlib_walknode(vector start, vector end, float doedge);
+var vector pathlib_movenode(vector start, vector end, float doedge);
+
+float      pathlib_expandnode_star(entity node, vector start, vector goal);
+float      pathlib_expandnode_box(entity node, vector start, vector goal);
+float      pathlib_expandnode_octagon(entity node, vector start, vector goal);
+var float  pathlib_expandnode(entity node, vector start, vector goal);
+
+float      pathlib_g_static(entity parent, vector to, float static_cost);
+float      pathlib_g_static_water(entity parent, vector to, float static_cost);
+float      pathlib_g_euclidean(entity parent, vector to, float static_cost);
+float      pathlib_g_euclidean_water(entity parent, vector to, float static_cost);
+var float  pathlib_cost(entity parent, vector to, float static_cost);
+
+float      pathlib_h_manhattan(vector a, vector b);
+float      pathlib_h_diagonal(vector a, vector b);
+float      pathlib_h_euclidean(vector a,vector b);
+float      pathlib_h_diagonal2(vector a, vector b);
+float      pathlib_h_diagonal3(vector a, vector b);
+float      pathlib_h_diagonal2sdp(vector preprev, vector prev, vector point, vector end);
+var float  pathlib_heuristic(vector from, vector to);
+
+var float  pathlib_makenode(entity parent,vector start, vector to, vector goal,float cost);
+var float  buildpath_nodefilter(vector n,vector c,vector p);
+
+
+#ifdef DEBUGPATHING
+#include "debug.qc"
+#endif
+
+#include "utility.qc"
+#include "movenode.qc"
+#include "costs.qc"
+#include "expandnode.qc"
+#include "main.qc"


Property changes on: trunk/data/qcsrc/server/pathlib/pathlib.qh
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/pathlib/utility.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib/utility.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/pathlib/utility.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,162 +1,162 @@
-float fsnap(float val,float fsize)
-{
-    return rint(val / fsize) * fsize;
-}
-
-vector vsnap(vector point,float fsize)
-{
-    vector vret;
-
-    vret_x = rint(point_x / fsize) * fsize;
-    vret_y = rint(point_y / fsize) * fsize;
-    vret_z = ceil(point_z / fsize) * fsize;
-
-    return vret;
-}
-
-float location_isok(vector point, float water_isok, float air_isok)
-{
-    float pc,pc2;
-
-    if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
-        return 0;
-
-    pc  = pointcontents(point);
-    pc2 = pointcontents(point - '0 0 1');
-
-    switch(pc)
-    {
-        case CONTENT_SOLID:
-            break;
-
-        case CONTENT_SLIME:
-            break;
-
-        case CONTENT_LAVA:
-            break;
-
-        case CONTENT_SKY:
-            break;
-
-        case CONTENT_EMPTY:
-            if (pc2 == CONTENT_SOLID)
-                return 1;
-
-            if (pc2 == CONTENT_EMPTY)
-                if(air_isok)
-                    return 1;
-
-            if (pc2 == CONTENT_WATER)
-                if(water_isok)
-                    return 1;
-
-            break;
-
-        case CONTENT_WATER:
-            if (water_isok)
-                return 1;
-
-            break;
-    }
-
-    return 0;
-}
-
-entity pathlib_nodeatpoint(vector where)
-{
-    entity node;
-
-    ++pathlib_searched_cnt;
-
-    where_x = fsnap(where_x,pathlib_gridsize);
-    where_y = fsnap(where_y,pathlib_gridsize);
-
-    node = findradius(where,pathlib_gridsize * 0.5);
-    while(node)
-    {
-        if(node.is_path_node == TRUE)
-            return node;
-
-        node = node.chain;
-    }
-
-    return world;
-}
-
-float tile_check_cross(vector where)
-{
-    vector p,f,r;
-
-    f = PLIB_FORWARD * tile_check_size;
-    r = PLIB_RIGHT   * tile_check_size;
-
-    // forward-right
-    p = where + f + r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-    // Forward-left
-    p = where + f - r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-    // Back-right
-    p = where - f + r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-    //Back-left
-    p = where - f - r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-    return 1;
-}
-
-float tile_check_plus(vector where)
-{
-    vector p,f,r;
-
-    f = PLIB_FORWARD * tile_check_size;
-    r = PLIB_RIGHT   * tile_check_size;
-
-    // forward
-    p = where + f;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-    //left
-    p = where - r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-
-    // Right
-    p = where + r;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-    //Back
-    p = where - f;
-    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
-    if not (location_isok(trace_endpos,1,0))
-        return 0;
-
-    return 1;
-}
-
-float tile_check_star(vector where)
-{
-    if(tile_check_plus(where))
-        return tile_check_cross(where);
-
-    return 0;
-}
-
+float fsnap(float val,float fsize)
+{
+    return rint(val / fsize) * fsize;
+}
+
+vector vsnap(vector point,float fsize)
+{
+    vector vret;
+
+    vret_x = rint(point_x / fsize) * fsize;
+    vret_y = rint(point_y / fsize) * fsize;
+    vret_z = ceil(point_z / fsize) * fsize;
+
+    return vret;
+}
+
+float location_isok(vector point, float water_isok, float air_isok)
+{
+    float pc,pc2;
+
+    if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+        return 0;
+
+    pc  = pointcontents(point);
+    pc2 = pointcontents(point - '0 0 1');
+
+    switch(pc)
+    {
+        case CONTENT_SOLID:
+            break;
+
+        case CONTENT_SLIME:
+            break;
+
+        case CONTENT_LAVA:
+            break;
+
+        case CONTENT_SKY:
+            break;
+
+        case CONTENT_EMPTY:
+            if (pc2 == CONTENT_SOLID)
+                return 1;
+
+            if (pc2 == CONTENT_EMPTY)
+                if(air_isok)
+                    return 1;
+
+            if (pc2 == CONTENT_WATER)
+                if(water_isok)
+                    return 1;
+
+            break;
+
+        case CONTENT_WATER:
+            if (water_isok)
+                return 1;
+
+            break;
+    }
+
+    return 0;
+}
+
+entity pathlib_nodeatpoint(vector where)
+{
+    entity node;
+
+    ++pathlib_searched_cnt;
+
+    where_x = fsnap(where_x,pathlib_gridsize);
+    where_y = fsnap(where_y,pathlib_gridsize);
+
+    node = findradius(where,pathlib_gridsize * 0.5);
+    while(node)
+    {
+        if(node.is_path_node == TRUE)
+            return node;
+
+        node = node.chain;
+    }
+
+    return world;
+}
+
+float tile_check_cross(vector where)
+{
+    vector p,f,r;
+
+    f = PLIB_FORWARD * tile_check_size;
+    r = PLIB_RIGHT   * tile_check_size;
+
+    // forward-right
+    p = where + f + r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if not (location_isok(trace_endpos,1,0))
+        return 0;
+
+    // Forward-left
+    p = where + f - r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if not (location_isok(trace_endpos,1,0))
+        return 0;
+
+    // Back-right
+    p = where - f + r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if not (location_isok(trace_endpos,1,0))
+        return 0;
+
+    //Back-left
+    p = where - f - r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if not (location_isok(trace_endpos,1,0))
+        return 0;
+
+    return 1;
+}
+
+float tile_check_plus(vector where)
+{
+    vector p,f,r;
+
+    f = PLIB_FORWARD * tile_check_size;
+    r = PLIB_RIGHT   * tile_check_size;
+
+    // forward
+    p = where + f;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if not (location_isok(trace_endpos,1,0))
+        return 0;
+
+    //left
+    p = where - r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if not (location_isok(trace_endpos,1,0))
+        return 0;
+
+
+    // Right
+    p = where + r;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if not (location_isok(trace_endpos,1,0))
+        return 0;
+
+    //Back
+    p = where - f;
+    traceline(p+tile_check_up,p-tile_check_down,MOVE_WORLDONLY,self);
+    if not (location_isok(trace_endpos,1,0))
+        return 0;
+
+    return 1;
+}
+
+float tile_check_star(vector where)
+{
+    if(tile_check_plus(where))
+        return tile_check_cross(where);
+
+    return 0;
+}
+


Property changes on: trunk/data/qcsrc/server/pathlib/utility.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/pathlib.qc
===================================================================
--- trunk/data/qcsrc/server/pathlib.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/pathlib.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,1047 +1,1047 @@
-//#define PATHLIB_RDFIELDS
-#ifdef PATHLIB_RDFIELDS
-    #define path_next swampslug
-    #define path_prev lasertarget
-#else
-    .entity path_next;
-    .entity path_prev;
-#endif
-
-#define medium spawnshieldtime
-
-//#define DEBUGPATHING
-
-entity openlist;
-entity closedlist;
-entity scraplist;
-
-.float pathlib_node_g;
-.float pathlib_node_h;
-.float pathlib_node_f;
-
-float pathlib_open_cnt;
-float pathlib_closed_cnt;
-float pathlib_made_cnt;
-float pathlib_merge_cnt;
-float pathlib_recycle_cnt;
-float pathlib_searched_cnt;
-
-#ifdef DEBUGPATHING
-
-#endif
-
-float pathlib_bestopen_seached;
-float pathlib_bestcash_hits;
-float pathlib_bestcash_saved;
-
-float pathlib_gridsize;
-
-float pathlib_movecost;
-float pathlib_movecost_diag;
-float pathlib_movecost_waterfactor;
-
-float pathlib_edge_check_size;
-
-float pathlib_foundgoal;
-entity goal_node;
-
-entity best_open_node;
-.float is_path_node;
-
-
-#ifdef DEBUGPATHING
-float edge_show(vector point,float fsize);
-void mark_error(vector where,float lifetime);
-void mark_info(vector where,float lifetime);
-entity mark_misc(vector where,float lifetime);
-
-void pathlib_showpath(entity start)
-{
-    entity e;
-    e = start;
-    while(e.path_next)
-    {
-        te_lightning1(e,e.origin,e.path_next.origin);
-        e = e.path_next;
-    }
-}
-
-void path_dbg_think()
-{
-    pathlib_showpath(self);
-    self.nextthink = time + 1;
-}
-
-void __showpath2_think()
-{
-    mark_info(self.origin,1);
-    if(self.path_next)
-    {
-        self.path_next.think     = __showpath2_think;
-        self.path_next.nextthink = time + 0.15;
-    }
-    else
-    {
-        self.owner.think     = __showpath2_think;
-        self.owner.nextthink = time + 0.15;
-    }
-}
-
-void pathlib_showpath2(entity path)
-{
-    path.think     = __showpath2_think;
-    path.nextthink = time;
-}
-
-#endif
-
-void pathlib_deletepath(entity start)
-{
-    entity e;
-
-    e = findchainentity(owner, start);
-    while(e)
-    {
-        e.think = SUB_Remove;
-        e.nextthink = time;
-        e = e.chain;
-    }
-}
-
-float fsnap(float val,float fsize)
-{
-    return rint(val / fsize) * fsize;
-}
-
-vector vsnap(vector point,float fsize)
-{
-    vector vret;
-
-    vret_x = rint(point_x / fsize) * fsize;
-    vret_y = rint(point_y / fsize) * fsize;
-    vret_z = ceil(point_z / fsize) * fsize;
-
-    return vret;
-}
-
-float  walknode_stepsize;
-vector walknode_stepup;
-vector walknode_maxdrop;
-vector walknode_boxup;
-vector walknode_boxmax;
-vector walknode_boxmin;
-float  pathlib_movenode_goodnode;
-
-float floor_ok(vector point)
-{
-    float pc;
-
-    if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
-        return 0;
-
-    pc = pointcontents(point);
-
-    switch(pc)
-    {
-        case CONTENT_SOLID:
-        case CONTENT_SLIME:
-        case CONTENT_LAVA:
-        case CONTENT_SKY:
-            return 0;
-        case CONTENT_EMPTY:
-            if not (pointcontents(point - '0 0 1') == CONTENT_SOLID)
-                return 0;
-            break;
-        case CONTENT_WATER:
-            return 1;
-    }
-    if(pointcontents(point - '0 0 1') == CONTENT_SOLID)
-        return 1;
-
-    return 0;
-}
-
-#define inwater(point) (pointcontents(point) == CONTENT_WATER)
-/*
-float inwater(vector point)
-{
-    if(pointcontents(point) == CONTENT_WATER)
-        return 1;
-    return 0;
-}
-*/
-
-#define _pcheck(p) traceline(p+z_up,p-z_down,MOVE_WORLDONLY,self); if not(floor_ok(trace_endpos)) return 1
-float edge_check(vector point,float fsize)
-{
-    vector z_up,z_down;
-
-    z_up   = '0 0 1' * fsize;
-    z_down = '0 0 1' * fsize;
-
-    _pcheck(point + ('1 1 0'  * fsize));
-    _pcheck(point + ('1 -1 0'  * fsize));
-    _pcheck(point + ('1 0 0' * fsize));
-
-    _pcheck(point + ('0 1 0'  * fsize));
-    _pcheck(point + ('0 -1 0' * fsize));
-
-    _pcheck(point + ('-1 0 0'  * fsize));
-    _pcheck(point + ('-1 1 0'  * fsize));
-    _pcheck(point + ('-1 -1 0' * fsize));
-
-    return 0;
-}
-
-#ifdef DEBUGPATHING
-#define _pshow(p) mark_error(p,10)
-float edge_show(vector point,float fsize)
-{
-
-    _pshow(point + ('1 1 0'  * fsize));
-    _pshow(point + ('1 -1 0' * fsize));
-    _pshow(point + ('1 0 0'  * fsize));
-
-    _pshow(point + ('0 1 0'  * fsize));
-    _pshow(point + ('0 -1 0' * fsize));
-
-    _pshow(point + ('-1 0 0'  * fsize));
-    _pshow(point + ('-1 1 0'  * fsize));
-    _pshow(point + ('-1 -1 0' * fsize));
-
-    return 0;
-}
-#endif
-
-var vector pathlib_movenode(vector start,vector end,float doedge);
-vector pathlib_wateroutnode(vector start,vector end)
-{
-    vector surface;
-
-    pathlib_movenode_goodnode = 0;
-
-    end_x = fsnap(end_x, pathlib_gridsize);
-    end_y = fsnap(end_y, pathlib_gridsize);
-
-    traceline(end + ('0 0 0.25' * pathlib_gridsize),end - ('0 0 1' * pathlib_gridsize),MOVE_WORLDONLY,self);
-    end = trace_endpos;
-
-    if not(pointcontents(end - '0 0 1') == CONTENT_SOLID)
-        return end;
-
-    for(surface = start ; surface_z < (end_z + 32); ++surface_z)
-    {
-        if(pointcontents(surface) == CONTENT_EMPTY)
-            break;
-    }
-
-    if(pointcontents(surface + '0 0 1') != CONTENT_EMPTY)
-        return end;
-
-    tracebox(start + '0 0 64', walknode_boxmin,walknode_boxmax, end + '0 0 64', MOVE_WORLDONLY, self);
-    if(trace_fraction == 1)
-        pathlib_movenode_goodnode = 1;
-
-    if(fabs(surface_z - end_z) > 32)
-        pathlib_movenode_goodnode = 0;
-
-    return end;
-}
-
-vector pathlib_swimnode(vector start,vector end)
-{
-    pathlib_movenode_goodnode = 0;
-
-    if(pointcontents(start) != CONTENT_WATER)
-        return end;
-
-    end_x = fsnap(end_x, pathlib_gridsize);
-    end_y = fsnap(end_y, pathlib_gridsize);
-
-    if(pointcontents(end) == CONTENT_EMPTY)
-        return pathlib_wateroutnode( start, end);
-
-    tracebox(start, walknode_boxmin,walknode_boxmax, end, MOVE_WORLDONLY, self);
-    if(trace_fraction == 1)
-        pathlib_movenode_goodnode = 1;
-
-    return end;
-}
-
-vector pathlib_flynode(vector start,vector end)
-{
-    pathlib_movenode_goodnode = 0;
-
-    end_x = fsnap(end_x, pathlib_gridsize);
-    end_y = fsnap(end_y, pathlib_gridsize);
-
-    tracebox(start, walknode_boxmin,walknode_boxmax, end, MOVE_WORLDONLY, self);
-    if(trace_fraction == 1)
-        pathlib_movenode_goodnode = 1;
-
-    return end;
-}
-
-vector pathlib_walknode(vector start,vector end,float doedge)
-{
-    vector direction,point,last_point,s,e;
-    float steps, distance, i,laststep;
-
-    pathlib_movenode_goodnode = 0;
-
-    s   = start;
-    e   = end;
-    e_z = 0;
-    s_z = 0;
-    direction  = normalize(s - e);
-
-    distance    = vlen(start - end);
-    laststep    = distance / walknode_stepsize;
-    steps       = floor(laststep);
-    laststep    = laststep - steps;
-
-    point = start;
-    s     = point + walknode_stepup;
-    e     = point - walknode_maxdrop;
-
-    traceline(s, e,MOVE_WORLDONLY,self);
-    if(trace_fraction == 1.0)
-        return trace_endpos;
-
-    if (floor_ok(trace_endpos) == 0)
-        return trace_endpos;
-
-    last_point = trace_endpos;
-
-    for(i = 0; i < steps; ++i)
-    {
-        point = last_point + direction * walknode_stepsize;
-
-        s = point + walknode_stepup;
-        e = point - walknode_maxdrop;
-        traceline(s, e,MOVE_WORLDONLY,self);
-        if(trace_fraction == 1.0)
-            return trace_endpos;
-
-        point = trace_endpos;
-        if not(floor_ok(trace_endpos))
-            return trace_endpos;
-
-        tracebox(last_point + walknode_boxup, walknode_boxmin,walknode_boxmax, point + walknode_boxup, MOVE_WORLDONLY, self);
-        if(trace_fraction != 1.0)
-            return trace_endpos;
-
-        if(doedge)
-        if(edge_check(point,pathlib_edge_check_size))
-            return trace_endpos;
-
-        last_point = point;
-    }
-
-    point = last_point + direction * walknode_stepsize * laststep;
-
-    point_x = fsnap(point_x, pathlib_gridsize);
-    point_y = fsnap(point_y, pathlib_gridsize);
-
-    s = point + walknode_stepup;
-    e = point - walknode_maxdrop;
-    traceline(s, e,MOVE_WORLDONLY,self);
-
-    if(trace_fraction == 1.0)
-        return trace_endpos;
-
-    point = trace_endpos;
-
-    if not(floor_ok(trace_endpos))
-        return trace_endpos;
-
-    tracebox(last_point + walknode_boxup, walknode_boxmin,walknode_boxmax, point + walknode_boxup, MOVE_WORLDONLY, self);
-    if(trace_fraction != 1.0)
-        return trace_endpos;
-
-    pathlib_movenode_goodnode = 1;
-    return point;
-}
-
-var float pathlib_cost(entity parent,vector to, float static_cost);
-float pathlib_g_static(entity parent,vector to, float static_cost)
-{
-    if(inwater(to))
-        return parent.pathlib_node_g + static_cost * pathlib_movecost_waterfactor;
-    else
-        return parent.pathlib_node_g + static_cost;
-}
-
-float pathlib_g_static_water(entity parent,vector to, float static_cost)
-{
-    if(inwater(to))
-        return parent.pathlib_node_g + static_cost * pathlib_movecost_waterfactor;
-    else
-        return parent.pathlib_node_g + static_cost;
-}
-
-float pathlib_g_euclidean(entity parent,vector to, float static_cost)
-{
-    return parent.pathlib_node_g + vlen(parent.origin - to);
-}
-float pathlib_g_euclidean_water(entity parent,vector to, float static_cost)
-{
-    if(inwater(to))
-        return parent.pathlib_node_g + vlen(parent.origin - to) * pathlib_movecost_waterfactor;
-    else
-        return parent.pathlib_node_g + vlen(parent.origin - to);
-}
-
-var float(vector from,vector to) pathlib_heuristic;
-
-/**
-    Manhattan Menas we expect to move up,down left or right
-    No diagonal moves espected. (like moving bewteen city blocks)
-**/
-float pathlib_h_manhattan(vector a,vector b)
-{
-    //h(n) = D * (abs(n.x-goal.x) + abs(n.y-goal.y))
-
-    float h;
-    h  = fabs(a_x - b_x);
-    h += fabs(a_y - b_y);
-    h *= pathlib_gridsize;
-
-    return h;
-}
-
-/**
-    This heuristic consider both stright and disagonal moves
-    to have teh same cost.
-**/
-float pathlib_h_diagonal(vector a,vector b)
-{
-    //h(n) = D * max(abs(n.x-goal.x), abs(n.y-goal.y))
-    float h,x,y;
-
-    x = fabs(a_x - b_x);
-    y = fabs(a_y - b_y);
-    h = pathlib_movecost * max(x,y);
-
-    return h;
-}
-
-/**
-    This heuristic only considers the stright line distance.
-    Will usualy mean a lower H then G meaning A* Will speand more
-    and run slower.
-**/
-float pathlib_h_euclidean(vector a,vector b)
-{
-    return vlen(a - b);
-}
-
-/**
-    This heuristic consider both stright and disagonal moves,
-    But has a separate cost for diagonal moves.
-**/
-float pathlib_h_diagonal2(vector a,vector b)
-{
-    float h_diag,h_str,h,x,y;
-
-    /*
-    h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
-    h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
-    h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
-    */
-
-    x = fabs(a_x - b_x);
-    y = fabs(a_y - b_y);
-
-    h_diag = min(x,y);
-    h_str = x + y;
-
-    h =  pathlib_movecost_diag * h_diag;
-    h += pathlib_movecost * (h_str - 2 * h_diag);
-
-    return h;
-}
-
-/**
-    This heuristic consider both stright and disagonal moves,
-    But has a separate cost for diagonal moves.
-
-
-**/
-float pathlib_h_diagonal2sdp(vector preprev,vector prev,vector point,vector end)
-{
-    float h_diag,h_str,h,x,y,z;
-
-    //h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
-    //h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
-    //h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
-
-    x = fabs(point_x - end_x);
-    y = fabs(point_y - end_y);
-    z = fabs(point_z - end_z);
-
-    h_diag = min3(x,y,z);
-    h_str = x + y + z;
-
-    h =  pathlib_movecost_diag * h_diag;
-    h += pathlib_movecost * (h_str - 2 * h_diag);
-
-    float m;
-    vector d1,d2;
-
-    d1 = normalize(preprev - point);
-    d2 = normalize(prev    - point);
-    m = vlen(d1-d2);
-    //bprint("pathlib_h_diagonal2sdp-M = ",ftos(m),"\n");
-
-    return h * m;
-}
-
-
-float pathlib_h_diagonal3(vector a,vector b)
-{
-    float h_diag,h_str,h,x,y,z;
-
-    //h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
-    //h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
-    //h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
-
-    x = fabs(a_x - b_x);
-    y = fabs(a_y - b_y);
-    z = fabs(a_z - b_z);
-
-    h_diag = min3(x,y,z);
-    h_str = x + y + z;
-
-    h =  pathlib_movecost_diag * h_diag;
-    h += pathlib_movecost * (h_str - 2 * h_diag);
-
-    return h;
-}
-
-//#define PATHLIB_USE_NODESCRAP
-#define PATHLIB_NODEEXPIRE 0.05
-float pathlib_scraplist_cnt;
-entity newnode()
-{
-    entity n;
-#ifdef PATHLIB_USE_NODESCRAP
-    if(pathlib_scraplist_cnt)
-    {
-        n = findentity(world,owner,scraplist);
-        if(n)
-        {
-            --pathlib_scraplist_cnt;
-            ++pathlib_recycle_cnt;
-            return n;
-        }
-        else
-            pathlib_scraplist_cnt = 0;
-    }
-#endif
-    ++pathlib_made_cnt;
-    n = spawn();
-#ifdef PATHLIB_NODEEXPIRE
-    n.think      = SUB_Remove;
-    n.nextthink  = time + PATHLIB_NODEEXPIRE;
-    return n;
-}
-
-void dumpnode(entity n)
-{
-#ifdef PATHLIB_USE_NODESCRAP
-    ++pathlib_scraplist_cnt;
-
-    n.path_next    = world;
-    n.path_prev    = world;
-    n.is_path_node = FALSE;
-    n.owner        = scraplist;
-#else
-    //n.is_path_node = FALSE;
-    n.think        = SUB_Remove;
-    n.nextthink    = time;
-#endif
-}
-
-entity pathlib_mknode(vector where,entity parent)
-{
-    entity node;
-
-    node              = newnode();
-    node.is_path_node = TRUE;
-    node.owner        = openlist;
-    node.path_prev    = parent;
-
-    setorigin(node, where);
-
-    ++pathlib_open_cnt;
-
-    node.medium = pointcontents(where);
-
-    return node;
-}
-
-var float pathlib_expandnode(entity node, vector start, vector goal);
-float pathlib_expandnode_star(entity node, vector start, vector goal);
-float pathlib_expandnode_box(entity node, vector start, vector goal);
-
-var float pathlib_makenode(entity parent,vector start, vector to, vector goal,float cost);
-float pathlib_makenode_adaptive(entity parent,vector start, vector to, vector goal,float cost)
-{
-    entity node;
-    float h,g,f,doedge;
-    vector where;
-
-    ++pathlib_searched_cnt;
-
-    if(inwater(parent.origin))
-    {
-        pathlib_expandnode = pathlib_expandnode_box;
-        pathlib_movenode   = pathlib_swimnode;
-    }
-    else
-    {
-        if(inwater(to))
-        {
-            pathlib_expandnode = pathlib_expandnode_box;
-            pathlib_movenode   = pathlib_swimnode;
-        }
-        else
-        {
-
-            pathlib_expandnode = pathlib_expandnode_star;
-            pathlib_movenode   = pathlib_walknode;
-            doedge = 1;
-        }
-    }
-
-    where = pathlib_movenode(parent.origin,to,0);
-    if not(pathlib_movenode_goodnode)
-        return 0;
-
-    if(doedge)
-    if(edge_check(where,pathlib_edge_check_size))
-        return 0;
-
-    if(parent.path_prev)
-        pathlib_h_diagonal2sdp(parent.path_prev.origin,parent.origin,where,goal);
-
-    h = pathlib_heuristic(where,goal);
-    g = pathlib_cost(parent,where,cost);
-    f = g + h;
-
-    node = findradius(where,pathlib_gridsize * 0.75);
-    while(node)
-    {
-        if(node.is_path_node == TRUE)
-        {
-            ++pathlib_merge_cnt;
-            if(node.owner == openlist)
-            {
-                if(node.pathlib_node_g > g)
-                {
-                    node.pathlib_node_h = h;
-                    node.pathlib_node_g = g;
-                    node.pathlib_node_f = f;
-                    node.path_prev = parent;
-                }
-
-                if not (best_open_node)
-                    best_open_node = node;
-                else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
-                    best_open_node = node;
-            }
-
-            return 1;
-        }
-        node = node.chain;
-    }
-
-    node = pathlib_mknode(where,parent);
-    node.pathlib_node_h = h;
-    node.pathlib_node_g = g;
-    node.pathlib_node_f = f;
-
-    if not (best_open_node)
-        best_open_node = node;
-    else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
-        best_open_node = node;
-
-    return 1;
-}
-
-entity pathlib_getbestopen()
-{
-    entity node;
-    entity bestnode;
-
-    if(best_open_node)
-    {
-        ++pathlib_bestcash_hits;
-        pathlib_bestcash_saved += pathlib_open_cnt;
-
-        return best_open_node;
-    }
-
-    node = findchainentity(owner,openlist);
-    if(!node)
-        return world;
-
-    bestnode = node;
-    while(node)
-    {
-        ++pathlib_bestopen_seached;
-        if(node.pathlib_node_f < bestnode.pathlib_node_f)
-            bestnode = node;
-
-        node = node.chain;
-    }
-
-    return bestnode;
-}
-
-void pathlib_close_node(entity node,vector goal)
-{
-
-    if(node.owner == closedlist)
-    {
-        dprint("Pathlib: Tried to close a closed node!\n");
-        return;
-    }
-
-    if(node == best_open_node)
-        best_open_node = world;
-
-    ++pathlib_closed_cnt;
-    --pathlib_open_cnt;
-
-    node.owner = closedlist;
-
-    if(vlen(node.origin - goal) <= pathlib_gridsize)
-    {
-        vector goalmove;
-
-        goalmove = pathlib_walknode(node.origin,goal,1);
-        if(pathlib_movenode_goodnode)
-        {
-            goal_node         = node;
-            pathlib_foundgoal = TRUE;
-        }
-    }
-}
-
-float pathlib_expandnode_star(entity node, vector start, vector goal)
-{
-    vector point;
-    vector where;
-    float nodecnt;
-
-    where = node.origin;
-
-    v_forward = '1 0 0';
-    v_right   = '0 1 0';
-
-    // Forward
-    point = where + v_forward * pathlib_gridsize;
-    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Back
-    point = where - v_forward * pathlib_gridsize;
-    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Right
-    point = where + v_right * pathlib_gridsize;
-    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Left
-    point = where - v_right * pathlib_gridsize;
-    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
-
-    // Forward-right
-    point = where + v_forward * pathlib_gridsize + v_right * pathlib_gridsize;
-    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
-
-    // Forward-left
-    point = where + v_forward * pathlib_gridsize - v_right * pathlib_gridsize;
-    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
-
-    // Back-right
-    point = where - v_forward * pathlib_gridsize + v_right * pathlib_gridsize;
-    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
-
-    // Back-left
-    point = where - v_forward * pathlib_gridsize - v_right * pathlib_gridsize;
-    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
-
-    return pathlib_open_cnt;
-}
-
-float pathlib_expandnode_box(entity node, vector start, vector goal)
-{
-    vector v;
-
-    for(v_z = node.origin_z - pathlib_gridsize; v_z <= node.origin_z + pathlib_gridsize; v_z += pathlib_gridsize)
-    for(v_y = node.origin_y - pathlib_gridsize; v_y <= node.origin_y + pathlib_gridsize; v_y += pathlib_gridsize)
-    for(v_x = node.origin_x - pathlib_gridsize; v_x <= node.origin_x + pathlib_gridsize; v_x += pathlib_gridsize)
-    {
-        if(vlen(v - node.origin))
-            pathlib_makenode(node,start,v,goal,pathlib_movecost);
-    }
-
-    return pathlib_open_cnt;
-}
-
-void pathlib_cleanup()
-{
-    entity node;
-
-    node = findfloat(world,is_path_node, TRUE);
-    while(node)
-    {
-        dumpnode(node);
-        node = findfloat(node,is_path_node, TRUE);
-    }
-
-    if(openlist)
-        remove(openlist);
-
-    if(closedlist)
-        remove(closedlist);
-
-    best_open_node = world;
-    openlist       = world;
-    closedlist     = world;
-}
-
-var float buildpath_nodefilter(vector n,vector c,vector p);
-float buildpath_nodefilter_directional(vector n,vector c,vector p)
-{
-    vector d1,d2;
-
-    d2 = normalize(p - c);
-    d1 = normalize(c - n);
-
-    if(vlen(d1-d2) < 0.25)
-        return 1;
-
-    return 0;
-}
-
-float buildpath_nodefilter_moveskip(vector n,vector c,vector p)
-{
-    pathlib_walknode(p,n,1);
-    if(pathlib_movenode_goodnode)
-        return 1;
-
-    return 0;
-}
-
-entity path_build(entity next, vector where, entity prev, entity start)
-{
-    entity path;
-
-    if(prev && next)
-        if(buildpath_nodefilter)
-            if(buildpath_nodefilter(next.origin,where,prev.origin))
-                return next;
-
-
-    path           = spawn();
-    path.owner     = start;
-    path.path_next = next;
-
-    setorigin(path,where);
-
-    if(!next)
-        path.classname = "path_end";
-    else
-    {
-        if(!prev)
-            path.classname = "path_start";
-        else
-            path.classname = "path_node";
-    }
-
-    return path;
-}
-
-entity pathlib_astar(vector from,vector to)
-{
-    entity path, start, end, open, n, ln;
-    float ptime, ftime, ctime;
-
-    ptime = gettime(GETTIME_REALTIME);
-
-    pathlib_cleanup();
-
-    // Select water<->land capable node make/link
-    pathlib_makenode     = pathlib_makenode_adaptive;
-    // Select XYZ cost estimate
-    pathlib_heuristic    = pathlib_h_diagonal3;
-    // Select distance + waterfactor cost
-    pathlib_cost         = pathlib_g_euclidean_water;
-    // Select star expander
-    pathlib_expandnode   = pathlib_expandnode_star;
-    // Select walk simulation movement test
-    pathlib_movenode     = pathlib_walknode;
-    // Filter final nodes by direction
-    buildpath_nodefilter = buildpath_nodefilter_directional;
-
-    // If the start is in water we need diffrent settings
-    if(inwater(from))
-    {
-        // Select volumetric node expaner
-        pathlib_expandnode = pathlib_expandnode_box;
-
-        // Water movement test
-        pathlib_movenode   = pathlib_swimnode;
-    }
-
-    if not(openlist)
-        openlist       = spawn();
-
-    if not(closedlist)
-        closedlist     = spawn();
-
-    if not(scraplist)
-        scraplist      = spawn();
-
-    pathlib_closed_cnt       = 0;
-    pathlib_open_cnt         = 0;
-    pathlib_made_cnt         = 0;
-    pathlib_merge_cnt        = 0;
-    pathlib_searched_cnt     = 0;
-    pathlib_bestopen_seached = 0;
-    pathlib_bestcash_hits    = 0;
-    pathlib_bestcash_saved   = 0;
-    pathlib_recycle_cnt      = 0;
-
-    pathlib_gridsize       = 128;
-    pathlib_movecost       = pathlib_gridsize;
-    pathlib_movecost_diag  = vlen(('1 1 0' * pathlib_gridsize));
-    pathlib_movecost_waterfactor = 1.1;
-    pathlib_foundgoal      = 0;
-
-    walknode_boxmax   = self.maxs * 1.5;
-    walknode_boxmin   = self.mins * 1.5;
-
-    pathlib_edge_check_size = (vlen(walknode_boxmin - walknode_boxmax) * 0.5);
-
-    walknode_boxup    = '0 0 2' * self.maxs_z;
-    walknode_stepsize = 32;
-    walknode_stepup   = '0 0 1' * walknode_stepsize;
-    walknode_maxdrop  = '0 0 3' * walknode_stepsize;
-
-    from_x = fsnap(from_x,pathlib_gridsize);
-    from_y = fsnap(from_y,pathlib_gridsize);
-
-    to_x = fsnap(to_x,pathlib_gridsize);
-    to_y = fsnap(to_y,pathlib_gridsize);
-
-    dprint("AStar init. ", ftos(pathlib_scraplist_cnt), " nodes on scrap\n");
-    path = pathlib_mknode(from,world);
-    pathlib_close_node(path,to);
-    if(pathlib_foundgoal)
-    {
-        dprint("AStar: Goal found on first node!\n");
-
-        open           = spawn();
-        open.owner     = open;
-        open.classname = "path_end";
-        setorigin(open,path.origin);
-
-        pathlib_cleanup();
-
-        return open;
-    }
-
-    if(pathlib_expandnode(path,from,to) <= 0)
-    {
-        dprint("AStar path fail.\n");
-        pathlib_cleanup();
-
-        return world;
-    }
-
-    best_open_node = pathlib_getbestopen();
-    n = best_open_node;
-    pathlib_close_node(best_open_node,to);
-    if(inwater(n.origin))
-        pathlib_expandnode_box(n,from,to);
-    else
-        pathlib_expandnode_star(n,from,to);
-
-    while(pathlib_open_cnt)
-    {
-        best_open_node = pathlib_getbestopen();
-        n = best_open_node;
-        pathlib_close_node(best_open_node,to);
-
-        if(inwater(n.origin))
-            pathlib_expandnode_box(n,from,to);
-        else
-            pathlib_expandnode(n,from,to);
-
-        if(pathlib_foundgoal)
-        {
-            dprint("Target found. Rebuilding and filtering path...\n");
-            ftime = gettime(GETTIME_REALTIME);
-            ptime = ftime - ptime;
-
-            start = path_build(world,path.origin,world,world);
-            end   = path_build(world,goal_node.origin,world,start);
-            ln    = end;
-
-            open = goal_node;
-            for(open = goal_node; open.path_prev != path; open = open.path_prev)
-            {
-                n    = path_build(ln,open.origin,open.path_prev,start);
-                ln.path_prev = n;
-                ln = n;
-            }
-            start.path_next = n;
-            n.path_prev = start;
-            ftime = gettime(GETTIME_REALTIME) - ftime;
-
-            ctime = gettime(GETTIME_REALTIME);
-            pathlib_cleanup();
-            ctime = gettime(GETTIME_REALTIME) - ctime;
-
-
-#ifdef DEBUGPATHING
-            pathlib_showpath2(start);
-
-            dprint("Time used -      pathfinding: ", ftos(ptime),"\n");
-            dprint("Time used - rebuild & filter: ", ftos(ftime),"\n");
-            dprint("Time used -          cleanup: ", ftos(ctime),"\n");
-            dprint("Time used -            total: ", ftos(ptime + ftime + ctime),"\n");
-            dprint("Time used -         # frames: ", ftos(ceil((ptime + ftime + ctime) / sys_ticrate)),"\n\n");
-            dprint("Nodes -         created: ", ftos(pathlib_made_cnt),"\n");
-            dprint("Nodes -            open: ", ftos(pathlib_open_cnt),"\n");
-            dprint("Nodes -          merged: ", ftos(pathlib_merge_cnt),"\n");
-            dprint("Nodes -          closed: ", ftos(pathlib_closed_cnt),"\n");
-            dprint("Nodes -        searched: ", ftos(pathlib_searched_cnt),"\n");
-
-        if(pathlib_recycle_cnt)
-            dprint("Nodes -      make/reuse: ", ftos(pathlib_made_cnt / pathlib_recycle_cnt),"\n");
-        if(pathlib_recycle_cnt)
-            dprint("Nodes -          reused: ", ftos(pathlib_recycle_cnt),"\n");
-
-            dprint("Nodes bestopen searched: ", ftos(pathlib_bestopen_seached),"\n");
-            dprint("Nodes bestcash -   hits: ", ftos(pathlib_bestcash_hits),"\n");
-            dprint("Nodes bestcash -   save: ", ftos(pathlib_bestcash_saved),"\n");
-            dprint("AStar done. ", ftos(pathlib_scraplist_cnt), " nodes on scrap\n\n");
-#endif
-            return start;
-        }
-    }
-
-    dprint("A* Faild to find a path! Try a smaller gridsize.\n");
-
-    pathlib_cleanup();
-
-    return world;
-}
-
-
-
+//#define PATHLIB_RDFIELDS
+#ifdef PATHLIB_RDFIELDS
+    #define path_next swampslug
+    #define path_prev lasertarget
+#else
+    .entity path_next;
+    .entity path_prev;
+#endif
+
+#define medium spawnshieldtime
+
+//#define DEBUGPATHING
+
+entity openlist;
+entity closedlist;
+entity scraplist;
+
+.float pathlib_node_g;
+.float pathlib_node_h;
+.float pathlib_node_f;
+
+float pathlib_open_cnt;
+float pathlib_closed_cnt;
+float pathlib_made_cnt;
+float pathlib_merge_cnt;
+float pathlib_recycle_cnt;
+float pathlib_searched_cnt;
+
+#ifdef DEBUGPATHING
+
+#endif
+
+float pathlib_bestopen_seached;
+float pathlib_bestcash_hits;
+float pathlib_bestcash_saved;
+
+float pathlib_gridsize;
+
+float pathlib_movecost;
+float pathlib_movecost_diag;
+float pathlib_movecost_waterfactor;
+
+float pathlib_edge_check_size;
+
+float pathlib_foundgoal;
+entity goal_node;
+
+entity best_open_node;
+.float is_path_node;
+
+
+#ifdef DEBUGPATHING
+float edge_show(vector point,float fsize);
+void mark_error(vector where,float lifetime);
+void mark_info(vector where,float lifetime);
+entity mark_misc(vector where,float lifetime);
+
+void pathlib_showpath(entity start)
+{
+    entity e;
+    e = start;
+    while(e.path_next)
+    {
+        te_lightning1(e,e.origin,e.path_next.origin);
+        e = e.path_next;
+    }
+}
+
+void path_dbg_think()
+{
+    pathlib_showpath(self);
+    self.nextthink = time + 1;
+}
+
+void __showpath2_think()
+{
+    mark_info(self.origin,1);
+    if(self.path_next)
+    {
+        self.path_next.think     = __showpath2_think;
+        self.path_next.nextthink = time + 0.15;
+    }
+    else
+    {
+        self.owner.think     = __showpath2_think;
+        self.owner.nextthink = time + 0.15;
+    }
+}
+
+void pathlib_showpath2(entity path)
+{
+    path.think     = __showpath2_think;
+    path.nextthink = time;
+}
+
+#endif
+
+void pathlib_deletepath(entity start)
+{
+    entity e;
+
+    e = findchainentity(owner, start);
+    while(e)
+    {
+        e.think = SUB_Remove;
+        e.nextthink = time;
+        e = e.chain;
+    }
+}
+
+float fsnap(float val,float fsize)
+{
+    return rint(val / fsize) * fsize;
+}
+
+vector vsnap(vector point,float fsize)
+{
+    vector vret;
+
+    vret_x = rint(point_x / fsize) * fsize;
+    vret_y = rint(point_y / fsize) * fsize;
+    vret_z = ceil(point_z / fsize) * fsize;
+
+    return vret;
+}
+
+float  walknode_stepsize;
+vector walknode_stepup;
+vector walknode_maxdrop;
+vector walknode_boxup;
+vector walknode_boxmax;
+vector walknode_boxmin;
+float  pathlib_movenode_goodnode;
+
+float floor_ok(vector point)
+{
+    float pc;
+
+    if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+        return 0;
+
+    pc = pointcontents(point);
+
+    switch(pc)
+    {
+        case CONTENT_SOLID:
+        case CONTENT_SLIME:
+        case CONTENT_LAVA:
+        case CONTENT_SKY:
+            return 0;
+        case CONTENT_EMPTY:
+            if not (pointcontents(point - '0 0 1') == CONTENT_SOLID)
+                return 0;
+            break;
+        case CONTENT_WATER:
+            return 1;
+    }
+    if(pointcontents(point - '0 0 1') == CONTENT_SOLID)
+        return 1;
+
+    return 0;
+}
+
+#define inwater(point) (pointcontents(point) == CONTENT_WATER)
+/*
+float inwater(vector point)
+{
+    if(pointcontents(point) == CONTENT_WATER)
+        return 1;
+    return 0;
+}
+*/
+
+#define _pcheck(p) traceline(p+z_up,p-z_down,MOVE_WORLDONLY,self); if not(floor_ok(trace_endpos)) return 1
+float edge_check(vector point,float fsize)
+{
+    vector z_up,z_down;
+
+    z_up   = '0 0 1' * fsize;
+    z_down = '0 0 1' * fsize;
+
+    _pcheck(point + ('1 1 0'  * fsize));
+    _pcheck(point + ('1 -1 0'  * fsize));
+    _pcheck(point + ('1 0 0' * fsize));
+
+    _pcheck(point + ('0 1 0'  * fsize));
+    _pcheck(point + ('0 -1 0' * fsize));
+
+    _pcheck(point + ('-1 0 0'  * fsize));
+    _pcheck(point + ('-1 1 0'  * fsize));
+    _pcheck(point + ('-1 -1 0' * fsize));
+
+    return 0;
+}
+
+#ifdef DEBUGPATHING
+#define _pshow(p) mark_error(p,10)
+float edge_show(vector point,float fsize)
+{
+
+    _pshow(point + ('1 1 0'  * fsize));
+    _pshow(point + ('1 -1 0' * fsize));
+    _pshow(point + ('1 0 0'  * fsize));
+
+    _pshow(point + ('0 1 0'  * fsize));
+    _pshow(point + ('0 -1 0' * fsize));
+
+    _pshow(point + ('-1 0 0'  * fsize));
+    _pshow(point + ('-1 1 0'  * fsize));
+    _pshow(point + ('-1 -1 0' * fsize));
+
+    return 0;
+}
+#endif
+
+var vector pathlib_movenode(vector start,vector end,float doedge);
+vector pathlib_wateroutnode(vector start,vector end)
+{
+    vector surface;
+
+    pathlib_movenode_goodnode = 0;
+
+    end_x = fsnap(end_x, pathlib_gridsize);
+    end_y = fsnap(end_y, pathlib_gridsize);
+
+    traceline(end + ('0 0 0.25' * pathlib_gridsize),end - ('0 0 1' * pathlib_gridsize),MOVE_WORLDONLY,self);
+    end = trace_endpos;
+
+    if not(pointcontents(end - '0 0 1') == CONTENT_SOLID)
+        return end;
+
+    for(surface = start ; surface_z < (end_z + 32); ++surface_z)
+    {
+        if(pointcontents(surface) == CONTENT_EMPTY)
+            break;
+    }
+
+    if(pointcontents(surface + '0 0 1') != CONTENT_EMPTY)
+        return end;
+
+    tracebox(start + '0 0 64', walknode_boxmin,walknode_boxmax, end + '0 0 64', MOVE_WORLDONLY, self);
+    if(trace_fraction == 1)
+        pathlib_movenode_goodnode = 1;
+
+    if(fabs(surface_z - end_z) > 32)
+        pathlib_movenode_goodnode = 0;
+
+    return end;
+}
+
+vector pathlib_swimnode(vector start,vector end)
+{
+    pathlib_movenode_goodnode = 0;
+
+    if(pointcontents(start) != CONTENT_WATER)
+        return end;
+
+    end_x = fsnap(end_x, pathlib_gridsize);
+    end_y = fsnap(end_y, pathlib_gridsize);
+
+    if(pointcontents(end) == CONTENT_EMPTY)
+        return pathlib_wateroutnode( start, end);
+
+    tracebox(start, walknode_boxmin,walknode_boxmax, end, MOVE_WORLDONLY, self);
+    if(trace_fraction == 1)
+        pathlib_movenode_goodnode = 1;
+
+    return end;
+}
+
+vector pathlib_flynode(vector start,vector end)
+{
+    pathlib_movenode_goodnode = 0;
+
+    end_x = fsnap(end_x, pathlib_gridsize);
+    end_y = fsnap(end_y, pathlib_gridsize);
+
+    tracebox(start, walknode_boxmin,walknode_boxmax, end, MOVE_WORLDONLY, self);
+    if(trace_fraction == 1)
+        pathlib_movenode_goodnode = 1;
+
+    return end;
+}
+
+vector pathlib_walknode(vector start,vector end,float doedge)
+{
+    vector direction,point,last_point,s,e;
+    float steps, distance, i,laststep;
+
+    pathlib_movenode_goodnode = 0;
+
+    s   = start;
+    e   = end;
+    e_z = 0;
+    s_z = 0;
+    direction  = normalize(s - e);
+
+    distance    = vlen(start - end);
+    laststep    = distance / walknode_stepsize;
+    steps       = floor(laststep);
+    laststep    = laststep - steps;
+
+    point = start;
+    s     = point + walknode_stepup;
+    e     = point - walknode_maxdrop;
+
+    traceline(s, e,MOVE_WORLDONLY,self);
+    if(trace_fraction == 1.0)
+        return trace_endpos;
+
+    if (floor_ok(trace_endpos) == 0)
+        return trace_endpos;
+
+    last_point = trace_endpos;
+
+    for(i = 0; i < steps; ++i)
+    {
+        point = last_point + direction * walknode_stepsize;
+
+        s = point + walknode_stepup;
+        e = point - walknode_maxdrop;
+        traceline(s, e,MOVE_WORLDONLY,self);
+        if(trace_fraction == 1.0)
+            return trace_endpos;
+
+        point = trace_endpos;
+        if not(floor_ok(trace_endpos))
+            return trace_endpos;
+
+        tracebox(last_point + walknode_boxup, walknode_boxmin,walknode_boxmax, point + walknode_boxup, MOVE_WORLDONLY, self);
+        if(trace_fraction != 1.0)
+            return trace_endpos;
+
+        if(doedge)
+        if(edge_check(point,pathlib_edge_check_size))
+            return trace_endpos;
+
+        last_point = point;
+    }
+
+    point = last_point + direction * walknode_stepsize * laststep;
+
+    point_x = fsnap(point_x, pathlib_gridsize);
+    point_y = fsnap(point_y, pathlib_gridsize);
+
+    s = point + walknode_stepup;
+    e = point - walknode_maxdrop;
+    traceline(s, e,MOVE_WORLDONLY,self);
+
+    if(trace_fraction == 1.0)
+        return trace_endpos;
+
+    point = trace_endpos;
+
+    if not(floor_ok(trace_endpos))
+        return trace_endpos;
+
+    tracebox(last_point + walknode_boxup, walknode_boxmin,walknode_boxmax, point + walknode_boxup, MOVE_WORLDONLY, self);
+    if(trace_fraction != 1.0)
+        return trace_endpos;
+
+    pathlib_movenode_goodnode = 1;
+    return point;
+}
+
+var float pathlib_cost(entity parent,vector to, float static_cost);
+float pathlib_g_static(entity parent,vector to, float static_cost)
+{
+    if(inwater(to))
+        return parent.pathlib_node_g + static_cost * pathlib_movecost_waterfactor;
+    else
+        return parent.pathlib_node_g + static_cost;
+}
+
+float pathlib_g_static_water(entity parent,vector to, float static_cost)
+{
+    if(inwater(to))
+        return parent.pathlib_node_g + static_cost * pathlib_movecost_waterfactor;
+    else
+        return parent.pathlib_node_g + static_cost;
+}
+
+float pathlib_g_euclidean(entity parent,vector to, float static_cost)
+{
+    return parent.pathlib_node_g + vlen(parent.origin - to);
+}
+float pathlib_g_euclidean_water(entity parent,vector to, float static_cost)
+{
+    if(inwater(to))
+        return parent.pathlib_node_g + vlen(parent.origin - to) * pathlib_movecost_waterfactor;
+    else
+        return parent.pathlib_node_g + vlen(parent.origin - to);
+}
+
+var float(vector from,vector to) pathlib_heuristic;
+
+/**
+    Manhattan Menas we expect to move up,down left or right
+    No diagonal moves espected. (like moving bewteen city blocks)
+**/
+float pathlib_h_manhattan(vector a,vector b)
+{
+    //h(n) = D * (abs(n.x-goal.x) + abs(n.y-goal.y))
+
+    float h;
+    h  = fabs(a_x - b_x);
+    h += fabs(a_y - b_y);
+    h *= pathlib_gridsize;
+
+    return h;
+}
+
+/**
+    This heuristic consider both stright and disagonal moves
+    to have teh same cost.
+**/
+float pathlib_h_diagonal(vector a,vector b)
+{
+    //h(n) = D * max(abs(n.x-goal.x), abs(n.y-goal.y))
+    float h,x,y;
+
+    x = fabs(a_x - b_x);
+    y = fabs(a_y - b_y);
+    h = pathlib_movecost * max(x,y);
+
+    return h;
+}
+
+/**
+    This heuristic only considers the stright line distance.
+    Will usualy mean a lower H then G meaning A* Will speand more
+    and run slower.
+**/
+float pathlib_h_euclidean(vector a,vector b)
+{
+    return vlen(a - b);
+}
+
+/**
+    This heuristic consider both stright and disagonal moves,
+    But has a separate cost for diagonal moves.
+**/
+float pathlib_h_diagonal2(vector a,vector b)
+{
+    float h_diag,h_str,h,x,y;
+
+    /*
+    h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
+    h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
+    h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
+    */
+
+    x = fabs(a_x - b_x);
+    y = fabs(a_y - b_y);
+
+    h_diag = min(x,y);
+    h_str = x + y;
+
+    h =  pathlib_movecost_diag * h_diag;
+    h += pathlib_movecost * (h_str - 2 * h_diag);
+
+    return h;
+}
+
+/**
+    This heuristic consider both stright and disagonal moves,
+    But has a separate cost for diagonal moves.
+
+
+**/
+float pathlib_h_diagonal2sdp(vector preprev,vector prev,vector point,vector end)
+{
+    float h_diag,h_str,h,x,y,z;
+
+    //h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
+    //h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
+    //h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
+
+    x = fabs(point_x - end_x);
+    y = fabs(point_y - end_y);
+    z = fabs(point_z - end_z);
+
+    h_diag = min3(x,y,z);
+    h_str = x + y + z;
+
+    h =  pathlib_movecost_diag * h_diag;
+    h += pathlib_movecost * (h_str - 2 * h_diag);
+
+    float m;
+    vector d1,d2;
+
+    d1 = normalize(preprev - point);
+    d2 = normalize(prev    - point);
+    m = vlen(d1-d2);
+    //bprint("pathlib_h_diagonal2sdp-M = ",ftos(m),"\n");
+
+    return h * m;
+}
+
+
+float pathlib_h_diagonal3(vector a,vector b)
+{
+    float h_diag,h_str,h,x,y,z;
+
+    //h_diagonal(n) = min(abs(n.x-goal.x), abs(n.y-goal.y))
+    //h_straight(n) = (abs(n.x-goal.x) + abs(n.y-goal.y))
+    //h(n) = D2 * h_diagonal(n) + D * (h_straight(n) - 2*h_diagonal(n)))
+
+    x = fabs(a_x - b_x);
+    y = fabs(a_y - b_y);
+    z = fabs(a_z - b_z);
+
+    h_diag = min3(x,y,z);
+    h_str = x + y + z;
+
+    h =  pathlib_movecost_diag * h_diag;
+    h += pathlib_movecost * (h_str - 2 * h_diag);
+
+    return h;
+}
+
+//#define PATHLIB_USE_NODESCRAP
+#define PATHLIB_NODEEXPIRE 0.05
+float pathlib_scraplist_cnt;
+entity newnode()
+{
+    entity n;
+#ifdef PATHLIB_USE_NODESCRAP
+    if(pathlib_scraplist_cnt)
+    {
+        n = findentity(world,owner,scraplist);
+        if(n)
+        {
+            --pathlib_scraplist_cnt;
+            ++pathlib_recycle_cnt;
+            return n;
+        }
+        else
+            pathlib_scraplist_cnt = 0;
+    }
+#endif
+    ++pathlib_made_cnt;
+    n = spawn();
+#ifdef PATHLIB_NODEEXPIRE
+    n.think      = SUB_Remove;
+    n.nextthink  = time + PATHLIB_NODEEXPIRE;
+    return n;
+}
+
+void dumpnode(entity n)
+{
+#ifdef PATHLIB_USE_NODESCRAP
+    ++pathlib_scraplist_cnt;
+
+    n.path_next    = world;
+    n.path_prev    = world;
+    n.is_path_node = FALSE;
+    n.owner        = scraplist;
+#else
+    //n.is_path_node = FALSE;
+    n.think        = SUB_Remove;
+    n.nextthink    = time;
+#endif
+}
+
+entity pathlib_mknode(vector where,entity parent)
+{
+    entity node;
+
+    node              = newnode();
+    node.is_path_node = TRUE;
+    node.owner        = openlist;
+    node.path_prev    = parent;
+
+    setorigin(node, where);
+
+    ++pathlib_open_cnt;
+
+    node.medium = pointcontents(where);
+
+    return node;
+}
+
+var float pathlib_expandnode(entity node, vector start, vector goal);
+float pathlib_expandnode_star(entity node, vector start, vector goal);
+float pathlib_expandnode_box(entity node, vector start, vector goal);
+
+var float pathlib_makenode(entity parent,vector start, vector to, vector goal,float cost);
+float pathlib_makenode_adaptive(entity parent,vector start, vector to, vector goal,float cost)
+{
+    entity node;
+    float h,g,f,doedge;
+    vector where;
+
+    ++pathlib_searched_cnt;
+
+    if(inwater(parent.origin))
+    {
+        pathlib_expandnode = pathlib_expandnode_box;
+        pathlib_movenode   = pathlib_swimnode;
+    }
+    else
+    {
+        if(inwater(to))
+        {
+            pathlib_expandnode = pathlib_expandnode_box;
+            pathlib_movenode   = pathlib_swimnode;
+        }
+        else
+        {
+
+            pathlib_expandnode = pathlib_expandnode_star;
+            pathlib_movenode   = pathlib_walknode;
+            doedge = 1;
+        }
+    }
+
+    where = pathlib_movenode(parent.origin,to,0);
+    if not(pathlib_movenode_goodnode)
+        return 0;
+
+    if(doedge)
+    if(edge_check(where,pathlib_edge_check_size))
+        return 0;
+
+    if(parent.path_prev)
+        pathlib_h_diagonal2sdp(parent.path_prev.origin,parent.origin,where,goal);
+
+    h = pathlib_heuristic(where,goal);
+    g = pathlib_cost(parent,where,cost);
+    f = g + h;
+
+    node = findradius(where,pathlib_gridsize * 0.75);
+    while(node)
+    {
+        if(node.is_path_node == TRUE)
+        {
+            ++pathlib_merge_cnt;
+            if(node.owner == openlist)
+            {
+                if(node.pathlib_node_g > g)
+                {
+                    node.pathlib_node_h = h;
+                    node.pathlib_node_g = g;
+                    node.pathlib_node_f = f;
+                    node.path_prev = parent;
+                }
+
+                if not (best_open_node)
+                    best_open_node = node;
+                else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
+                    best_open_node = node;
+            }
+
+            return 1;
+        }
+        node = node.chain;
+    }
+
+    node = pathlib_mknode(where,parent);
+    node.pathlib_node_h = h;
+    node.pathlib_node_g = g;
+    node.pathlib_node_f = f;
+
+    if not (best_open_node)
+        best_open_node = node;
+    else if(best_open_node.pathlib_node_f > node.pathlib_node_f)
+        best_open_node = node;
+
+    return 1;
+}
+
+entity pathlib_getbestopen()
+{
+    entity node;
+    entity bestnode;
+
+    if(best_open_node)
+    {
+        ++pathlib_bestcash_hits;
+        pathlib_bestcash_saved += pathlib_open_cnt;
+
+        return best_open_node;
+    }
+
+    node = findchainentity(owner,openlist);
+    if(!node)
+        return world;
+
+    bestnode = node;
+    while(node)
+    {
+        ++pathlib_bestopen_seached;
+        if(node.pathlib_node_f < bestnode.pathlib_node_f)
+            bestnode = node;
+
+        node = node.chain;
+    }
+
+    return bestnode;
+}
+
+void pathlib_close_node(entity node,vector goal)
+{
+
+    if(node.owner == closedlist)
+    {
+        dprint("Pathlib: Tried to close a closed node!\n");
+        return;
+    }
+
+    if(node == best_open_node)
+        best_open_node = world;
+
+    ++pathlib_closed_cnt;
+    --pathlib_open_cnt;
+
+    node.owner = closedlist;
+
+    if(vlen(node.origin - goal) <= pathlib_gridsize)
+    {
+        vector goalmove;
+
+        goalmove = pathlib_walknode(node.origin,goal,1);
+        if(pathlib_movenode_goodnode)
+        {
+            goal_node         = node;
+            pathlib_foundgoal = TRUE;
+        }
+    }
+}
+
+float pathlib_expandnode_star(entity node, vector start, vector goal)
+{
+    vector point;
+    vector where;
+    float nodecnt;
+
+    where = node.origin;
+
+    v_forward = '1 0 0';
+    v_right   = '0 1 0';
+
+    // Forward
+    point = where + v_forward * pathlib_gridsize;
+    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Back
+    point = where - v_forward * pathlib_gridsize;
+    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Right
+    point = where + v_right * pathlib_gridsize;
+    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Left
+    point = where - v_right * pathlib_gridsize;
+    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost);
+
+    // Forward-right
+    point = where + v_forward * pathlib_gridsize + v_right * pathlib_gridsize;
+    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+    // Forward-left
+    point = where + v_forward * pathlib_gridsize - v_right * pathlib_gridsize;
+    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+    // Back-right
+    point = where - v_forward * pathlib_gridsize + v_right * pathlib_gridsize;
+    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+    // Back-left
+    point = where - v_forward * pathlib_gridsize - v_right * pathlib_gridsize;
+    nodecnt += pathlib_makenode(node,start,point,goal,pathlib_movecost_diag);
+
+    return pathlib_open_cnt;
+}
+
+float pathlib_expandnode_box(entity node, vector start, vector goal)
+{
+    vector v;
+
+    for(v_z = node.origin_z - pathlib_gridsize; v_z <= node.origin_z + pathlib_gridsize; v_z += pathlib_gridsize)
+    for(v_y = node.origin_y - pathlib_gridsize; v_y <= node.origin_y + pathlib_gridsize; v_y += pathlib_gridsize)
+    for(v_x = node.origin_x - pathlib_gridsize; v_x <= node.origin_x + pathlib_gridsize; v_x += pathlib_gridsize)
+    {
+        if(vlen(v - node.origin))
+            pathlib_makenode(node,start,v,goal,pathlib_movecost);
+    }
+
+    return pathlib_open_cnt;
+}
+
+void pathlib_cleanup()
+{
+    entity node;
+
+    node = findfloat(world,is_path_node, TRUE);
+    while(node)
+    {
+        dumpnode(node);
+        node = findfloat(node,is_path_node, TRUE);
+    }
+
+    if(openlist)
+        remove(openlist);
+
+    if(closedlist)
+        remove(closedlist);
+
+    best_open_node = world;
+    openlist       = world;
+    closedlist     = world;
+}
+
+var float buildpath_nodefilter(vector n,vector c,vector p);
+float buildpath_nodefilter_directional(vector n,vector c,vector p)
+{
+    vector d1,d2;
+
+    d2 = normalize(p - c);
+    d1 = normalize(c - n);
+
+    if(vlen(d1-d2) < 0.25)
+        return 1;
+
+    return 0;
+}
+
+float buildpath_nodefilter_moveskip(vector n,vector c,vector p)
+{
+    pathlib_walknode(p,n,1);
+    if(pathlib_movenode_goodnode)
+        return 1;
+
+    return 0;
+}
+
+entity path_build(entity next, vector where, entity prev, entity start)
+{
+    entity path;
+
+    if(prev && next)
+        if(buildpath_nodefilter)
+            if(buildpath_nodefilter(next.origin,where,prev.origin))
+                return next;
+
+
+    path           = spawn();
+    path.owner     = start;
+    path.path_next = next;
+
+    setorigin(path,where);
+
+    if(!next)
+        path.classname = "path_end";
+    else
+    {
+        if(!prev)
+            path.classname = "path_start";
+        else
+            path.classname = "path_node";
+    }
+
+    return path;
+}
+
+entity pathlib_astar(vector from,vector to)
+{
+    entity path, start, end, open, n, ln;
+    float ptime, ftime, ctime;
+
+    ptime = gettime(GETTIME_REALTIME);
+
+    pathlib_cleanup();
+
+    // Select water<->land capable node make/link
+    pathlib_makenode     = pathlib_makenode_adaptive;
+    // Select XYZ cost estimate
+    pathlib_heuristic    = pathlib_h_diagonal3;
+    // Select distance + waterfactor cost
+    pathlib_cost         = pathlib_g_euclidean_water;
+    // Select star expander
+    pathlib_expandnode   = pathlib_expandnode_star;
+    // Select walk simulation movement test
+    pathlib_movenode     = pathlib_walknode;
+    // Filter final nodes by direction
+    buildpath_nodefilter = buildpath_nodefilter_directional;
+
+    // If the start is in water we need diffrent settings
+    if(inwater(from))
+    {
+        // Select volumetric node expaner
+        pathlib_expandnode = pathlib_expandnode_box;
+
+        // Water movement test
+        pathlib_movenode   = pathlib_swimnode;
+    }
+
+    if not(openlist)
+        openlist       = spawn();
+
+    if not(closedlist)
+        closedlist     = spawn();
+
+    if not(scraplist)
+        scraplist      = spawn();
+
+    pathlib_closed_cnt       = 0;
+    pathlib_open_cnt         = 0;
+    pathlib_made_cnt         = 0;
+    pathlib_merge_cnt        = 0;
+    pathlib_searched_cnt     = 0;
+    pathlib_bestopen_seached = 0;
+    pathlib_bestcash_hits    = 0;
+    pathlib_bestcash_saved   = 0;
+    pathlib_recycle_cnt      = 0;
+
+    pathlib_gridsize       = 128;
+    pathlib_movecost       = pathlib_gridsize;
+    pathlib_movecost_diag  = vlen(('1 1 0' * pathlib_gridsize));
+    pathlib_movecost_waterfactor = 1.1;
+    pathlib_foundgoal      = 0;
+
+    walknode_boxmax   = self.maxs * 1.5;
+    walknode_boxmin   = self.mins * 1.5;
+
+    pathlib_edge_check_size = (vlen(walknode_boxmin - walknode_boxmax) * 0.5);
+
+    walknode_boxup    = '0 0 2' * self.maxs_z;
+    walknode_stepsize = 32;
+    walknode_stepup   = '0 0 1' * walknode_stepsize;
+    walknode_maxdrop  = '0 0 3' * walknode_stepsize;
+
+    from_x = fsnap(from_x,pathlib_gridsize);
+    from_y = fsnap(from_y,pathlib_gridsize);
+
+    to_x = fsnap(to_x,pathlib_gridsize);
+    to_y = fsnap(to_y,pathlib_gridsize);
+
+    dprint("AStar init. ", ftos(pathlib_scraplist_cnt), " nodes on scrap\n");
+    path = pathlib_mknode(from,world);
+    pathlib_close_node(path,to);
+    if(pathlib_foundgoal)
+    {
+        dprint("AStar: Goal found on first node!\n");
+
+        open           = spawn();
+        open.owner     = open;
+        open.classname = "path_end";
+        setorigin(open,path.origin);
+
+        pathlib_cleanup();
+
+        return open;
+    }
+
+    if(pathlib_expandnode(path,from,to) <= 0)
+    {
+        dprint("AStar path fail.\n");
+        pathlib_cleanup();
+
+        return world;
+    }
+
+    best_open_node = pathlib_getbestopen();
+    n = best_open_node;
+    pathlib_close_node(best_open_node,to);
+    if(inwater(n.origin))
+        pathlib_expandnode_box(n,from,to);
+    else
+        pathlib_expandnode_star(n,from,to);
+
+    while(pathlib_open_cnt)
+    {
+        best_open_node = pathlib_getbestopen();
+        n = best_open_node;
+        pathlib_close_node(best_open_node,to);
+
+        if(inwater(n.origin))
+            pathlib_expandnode_box(n,from,to);
+        else
+            pathlib_expandnode(n,from,to);
+
+        if(pathlib_foundgoal)
+        {
+            dprint("Target found. Rebuilding and filtering path...\n");
+            ftime = gettime(GETTIME_REALTIME);
+            ptime = ftime - ptime;
+
+            start = path_build(world,path.origin,world,world);
+            end   = path_build(world,goal_node.origin,world,start);
+            ln    = end;
+
+            open = goal_node;
+            for(open = goal_node; open.path_prev != path; open = open.path_prev)
+            {
+                n    = path_build(ln,open.origin,open.path_prev,start);
+                ln.path_prev = n;
+                ln = n;
+            }
+            start.path_next = n;
+            n.path_prev = start;
+            ftime = gettime(GETTIME_REALTIME) - ftime;
+
+            ctime = gettime(GETTIME_REALTIME);
+            pathlib_cleanup();
+            ctime = gettime(GETTIME_REALTIME) - ctime;
+
+
+#ifdef DEBUGPATHING
+            pathlib_showpath2(start);
+
+            dprint("Time used -      pathfinding: ", ftos(ptime),"\n");
+            dprint("Time used - rebuild & filter: ", ftos(ftime),"\n");
+            dprint("Time used -          cleanup: ", ftos(ctime),"\n");
+            dprint("Time used -            total: ", ftos(ptime + ftime + ctime),"\n");
+            dprint("Time used -         # frames: ", ftos(ceil((ptime + ftime + ctime) / sys_ticrate)),"\n\n");
+            dprint("Nodes -         created: ", ftos(pathlib_made_cnt),"\n");
+            dprint("Nodes -            open: ", ftos(pathlib_open_cnt),"\n");
+            dprint("Nodes -          merged: ", ftos(pathlib_merge_cnt),"\n");
+            dprint("Nodes -          closed: ", ftos(pathlib_closed_cnt),"\n");
+            dprint("Nodes -        searched: ", ftos(pathlib_searched_cnt),"\n");
+
+        if(pathlib_recycle_cnt)
+            dprint("Nodes -      make/reuse: ", ftos(pathlib_made_cnt / pathlib_recycle_cnt),"\n");
+        if(pathlib_recycle_cnt)
+            dprint("Nodes -          reused: ", ftos(pathlib_recycle_cnt),"\n");
+
+            dprint("Nodes bestopen searched: ", ftos(pathlib_bestopen_seached),"\n");
+            dprint("Nodes bestcash -   hits: ", ftos(pathlib_bestcash_hits),"\n");
+            dprint("Nodes bestcash -   save: ", ftos(pathlib_bestcash_saved),"\n");
+            dprint("AStar done. ", ftos(pathlib_scraplist_cnt), " nodes on scrap\n\n");
+#endif
+            return start;
+        }
+    }
+
+    dprint("A* Faild to find a path! Try a smaller gridsize.\n");
+
+    pathlib_cleanup();
+
+    return world;
+}
+
+
+


Property changes on: trunk/data/qcsrc/server/pathlib.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/portals.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/portals.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/post-builtins.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/pre-builtins.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/race.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/race.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/scores.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/scores.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/scores_rules.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/steerlib.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/target_spawn.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/include/turrets.qh
===================================================================
--- trunk/data/qcsrc/server/tturrets/include/turrets.qh	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/include/turrets.qh	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,29 +1,29 @@
-#ifdef TTURRETS_ENABLED
-
-// Include section.
-#include "../system/system_misc.qc"       /// Assorted junk & jewls
-#include "../system/system_main.qc"       /// And routines
-#include "../system/system_aimprocs.qc"   /// Aiming realted stuff
-#include "../system/system_scoreprocs.qc" /// Target calssification
-#include "../system/system_damage.qc"     /// Outch, they are hurting me! what should i do?
-
-// Non combat units
-#include "../units/unit_fusionreactor.qc"  /// Supply unites that need it with power
-#include "../units/unit_targettrigger.qc"  /// Hit me!
-#include "../units/unit_checkpoint.qc"     /// Halfsmart pathing.
-
-// Combat units
-#include "../units/unit_plasma.qc"  /// Basic energy cannon
-#include "../units/unit_mlrs.qc"    /// Basic multibay RL
-#include "../units/unit_hellion.qc" /// Seeking missiles MLRS
-#include "../units/unit_flac.qc"    /// anti missile turret
-#include "../units/unit_phaser.qc"     /// ZzzapT
-#include "../units/unit_hk.qc"         /// Hunter killers
-#include "../units/unit_machinegun.qc" /// whacka
-#include "../units/unit_tessla.qc"     /// Chain lightning capabale turret
-#include "../units/unit_walker.qc"     /// Moving minigun-rocket-meele err thing
-#include "../units/unit_ewheel.qc"     /// A evil wheel. with guns on.
-//#include "../units/unit_repulsor.qc" /// Fires a wave that knocks foes back
-//#include "../units/unit_hive.qc"     /// Swarm AI
-
-#endif // TTURRETS_ENABLED
+#ifdef TTURRETS_ENABLED
+
+// Include section.
+#include "../system/system_misc.qc"       /// Assorted junk & jewls
+#include "../system/system_main.qc"       /// And routines
+#include "../system/system_aimprocs.qc"   /// Aiming realted stuff
+#include "../system/system_scoreprocs.qc" /// Target calssification
+#include "../system/system_damage.qc"     /// Outch, they are hurting me! what should i do?
+
+// Non combat units
+#include "../units/unit_fusionreactor.qc"  /// Supply unites that need it with power
+#include "../units/unit_targettrigger.qc"  /// Hit me!
+#include "../units/unit_checkpoint.qc"     /// Halfsmart pathing.
+
+// Combat units
+#include "../units/unit_plasma.qc"  /// Basic energy cannon
+#include "../units/unit_mlrs.qc"    /// Basic multibay RL
+#include "../units/unit_hellion.qc" /// Seeking missiles MLRS
+#include "../units/unit_flac.qc"    /// anti missile turret
+#include "../units/unit_phaser.qc"     /// ZzzapT
+#include "../units/unit_hk.qc"         /// Hunter killers
+#include "../units/unit_machinegun.qc" /// whacka
+#include "../units/unit_tessla.qc"     /// Chain lightning capabale turret
+#include "../units/unit_walker.qc"     /// Moving minigun-rocket-meele err thing
+#include "../units/unit_ewheel.qc"     /// A evil wheel. with guns on.
+//#include "../units/unit_repulsor.qc" /// Fires a wave that knocks foes back
+//#include "../units/unit_hive.qc"     /// Swarm AI
+
+#endif // TTURRETS_ENABLED


Property changes on: trunk/data/qcsrc/server/tturrets/include/turrets.qh
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/include/turrets_early.qh
===================================================================
--- trunk/data/qcsrc/server/tturrets/include/turrets_early.qh	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/include/turrets_early.qh	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,533 +1,533 @@
-// Comment out below to skip turrets
-#define TTURRETS_ENABLED
-
-#ifdef TTURRETS_ENABLED
-
-#message "with tZork turrets"
-
-vector real_origin(entity ent);
-
-/// Map time control over pain inflicted
-.float turret_scale_damage;
-/// Map time control targetting range
-.float turret_scale_range;
-/// Map time control refire
-.float turret_scale_refire;
-/// Map time control ammo held and recharged
-.float turret_scale_ammo;
-/// Map time control aim speed
-.float turret_scale_aim;
-/// Map time control health
-.float turret_scale_health;
-/// Map time control respawn time
-.float turret_scale_respawn;
-
-/// Used for cvar reloading
-.string cvar_basename;
-
-//.float spawnflags
-/// Spawn a pillar model under the turret to make it look ok on uneven ground surfaces
-#define TSF_TERRAINBASE   2
-/// Disable builtin ammo regeneration
-#define TSF_NO_AMMO_REGEN 4
-/// Dont break path to chase enemys. will still fire at them if possible.
-#define TSF_NO_PATHBREAK  8
-/// Dont respawn
-#define TSL_NO_RESPAWN    16
-
-/// target selection flags
-.float target_select_flags;
-/// target validatoin flags
-.float target_validate_flags;
-/// Dont select a target on its own.
-#define TFL_TARGETSELECT_NO            2
-/// Need line of sight
-#define TFL_TARGETSELECT_LOS           4
-/// Players are valid targets
-#define TFL_TARGETSELECT_PLAYERS       8
-/// Missiles are valid targets
-#define TFL_TARGETSELECT_MISSILES      16
-/// Responds to turret_trigger_target events
-#define TFL_TARGETSELECT_TRIGGERTARGET 32
-/// Angular limitations of turret head limits target selection
-#define TFL_TARGETSELECT_ANGLELIMITS   64
-/// Range limits apply in targetselection
-#define TFL_TARGETSELECT_RANGELIMTS    128
-/// DOnt select targets with a .team matching its own
-#define TFL_TARGETSELECT_TEAMCHECK     256
-/// Cant select targets on its own. needs to be triggerd or slaved.
-#define TFL_TARGETSELECT_NOBUILTIN     512
-/// TFL_TARGETSELECT_TEAMCHECK is inverted (selects only mebers of own .team)
-#define TFL_TARGETSELECT_OWNTEAM       1024
-/// Turrets aren't valid targets
-#define TFL_TARGETSELECT_NOTURRETS     2048
-/// Use feild of view
-#define TFL_TARGETSELECT_FOV           4096
-
-/// aim flags
-.float aim_flags;
-/// Dont aim.
-#define TFL_AIM_NO                  1
-/// Go for ground, not direct hit
-#define TFL_AIM_GROUND              2
-/// Go for ground, not direct hit, but only if target is on ground.
-#define TFL_AIM_GROUND2             4
-/// Use balistic aim. FIXME: not implemented
-#define TFL_AIM_BALISTIC            8
-/// Try to predict target movement (does not account for gravity)
-#define TFL_AIM_LEAD                16
-/// Compensate for shot traveltime when lead
-#define TFL_AIM_SHOTTIMECOMPENSATE  32
-/// Aim slightly in front of target
-#define TFL_AIM_INFRONT             64
-/// Aim slightly behind target
-#define TFL_AIM_BEHIND              128
-/// blend real and predicted z positions. (fake bounce prediction)
-#define TFL_AIM_ZEASE               256
-/// Try to do real prediction of targets z pos at impact.
-#define TFL_AIM_ZPREDICT            512
-/// Simply aim at target's current location
-#define TFL_AIM_SIMPLE              1024
-
-/// track (turn and pitch head) flags
-.float track_flags;
-/// Dont move head
-#define TFL_TRACK_NO    2
-/// Pitch the head
-#define TFL_TRACK_PITCH 4
-/// Rotate the head
-#define TFL_TRACK_ROT   8
-
-/// How tracking is preformed
-.float track_type;
-/// Hard angle increments. Ugly for fast turning, best accuracy.
-#define TFL_TRACKTYPE_STEPMOTOR    1
-/// Smoth absolute movement. Looks ok, fair accuracy.
-#define TFL_TRACKTYPE_FLUIDPRECISE 2
-/// Simulated inertia. "Wobbly mode" Looks kool, can mean really bad accuracy depending on how the feilds below are set
-#define TFL_TRACKTYPE_FLUIDINERTIA 3
-/// TFL_TRACKTYPE_FLUIDINERTIA: pitch multiplier
-.float track_accel_pitch;
-/// TFL_TRACKTYPE_FLUIDINERTIA: rotation multiplier
-.float  track_accel_rot;
-/// TFL_TRACKTYPE_FLUIDINERTIA: Blendrate with old rotation (inertia simulation) 1  = only old, 0 = only new
-.float  track_blendrate;
-
-/// How prefire check is preformed
-.float firecheck_flags;
-/// Dont kill the world
-#define TFL_FIRECHECK_WORLD       2
-/// Dont kill the dead
-#define TFL_FIRECHECK_DEAD        4
-/// Range limits apply
-#define TFL_FIRECHECK_DISTANCES   8
-/// Line Of Sight needs to be clear
-#define TFL_FIRECHECK_LOS         16
-/// Consider distance inpactpoint<->aimspot
-#define TFL_FIRECHECK_AIMDIST     32
-/// Consider enemy origin<->impactpoint
-#define TFL_FIRECHECK_REALDIST    64
-/// Consider angular diff head<->aimspot
-#define TFL_FIRECHECK_ANGLEDIST  128
-/// (re)consider target.team<->self.team
-#define TFL_FIRECHECK_TEAMCECK   256
-/// Try to avoid friendly fire
-#define TFL_FIRECHECK_AFF        512
-/// Own .ammo needs to be >= then own .shot_dmg
-#define TFL_FIRECHECK_OWM_AMMO   1024
-/// Others ammo need to be < others .ammo_max
-#define TFL_FIRECHECK_OTHER_AMMO 2048
-/// Check own .attack_finished_single vs time
-#define TFL_FIRECHECK_REFIRE     4096
-/// Move the acctual target to aimspot before tracing impact (and back after)
-#define TFL_FIRECHECK_VERIFIED   8192
-/// Dont do any chekcs
-#define TFL_FIRECHECK_NO         16384
-
-/// How shooting is done
-.float shoot_flags;
-/// Dont shoot
-#define  TFL_SHOOT_NO          64
-/// Fire in vollys (partial implementation through .shot_volly)
-#define  TFL_SHOOT_VOLLY       2
-/// Always do a full volly, even if target is lost or dead. (not implemented)
-#define  TFL_SHOOT_VOLLYALWAYS 4
-/// Loop though all valid tarters, and hit them.
-#define  TFL_SHOOT_HITALLVALID 8
-/// Fiering makes unit loose target (after volly is done, if in volly mode)
-#define  TFL_SHOOT_CLEARTARGET 16
-///Custom shooting;
-#define  TFL_SHOOT_CUSTOM 32
-
-/// Information aboute the units capabilities
-.float turrcaps_flags;
-/// No kown capabilities
-#define  TFL_TURRCAPS_NONE        0
-/// Capable of sniping
-#define  TFL_TURRCAPS_SNIPER      2
-/// Capable of splasdamage
-#define  TFL_TURRCAPS_RADIUSDMG   4
-/// Has one or more cannons with zero shot traveltime
-#define  TFL_TURRCAPS_HITSCAN     8
-/// More then one (type of) gun
-#define  TFL_TURRCAPS_MULTIGUN    16
-/// Carries at least one guided weapon
-#define  TFL_TURRCAPS_GUIDED      32
-/// At least one gun fiers slow projectiles
-#define  TFL_TURRCAPS_SLOWPROJ    64
-/// At least one gun fiers medium speed projectiles
-#define  TFL_TURRCAPS_MEDPROJ     128
-/// At least one gun fiers fast projectiles
-#define  TFL_TURRCAPS_FASTPROJ    256
-/// At least one gun capable of damaging players
-#define  TFL_TURRCAPS_PLAYERKILL  512
-/// At least one gun that can shoot town missiles
-#define  TFL_TURRCAPS_MISSILEKILL 1024
-/// Has support capabilities. powerplants and sutch.
-#define  TFL_TURRCAPS_SUPPORT     2048
-/// Proveides at least one type of ammmo
-#define  TFL_TURRCAPS_AMMOSOURCE  4096
-/// Can recive targets from external sources
-#define TFL_TURRCAPS_RECIVETARGETS 8192
-/// Capable of self-transport
-#define TFL_TURRCAPS_MOVE 16384
-/// Will roam arround even if not chasing anyting
-#define TFL_TURRCAPS_ROAM 32768
-#define TFL_TURRCAPS_HEADATTACHED 65536
-
-/// Ammo types needed and/or provided
-.float ammo_flags;
-/// Has and needs no ammo
-#define  TFL_AMMO_NONE     64
-/// Uses power
-#define  TFL_AMMO_ENERGY   2
-/// Uses bullets
-#define  TFL_AMMO_BULLETS  4
-/// Uses explosives
-#define  TFL_AMMO_ROCKETS  8
-/// Regenerates ammo on its own
-#define  TFL_AMMO_RECHARGE 16
-/// Can recive ammo from others
-#define  TFL_AMMO_RECIVE   32
-
-/// How incomming damage is handeld
-.float damage_flags;
-/// Cant be hurt
-#define  TFL_DMG_NO              256
-/// Can be damaged
-#define  TFL_DMG_YES             2
-/// Can be damaged  by teammates
-#define  TFL_DMG_TAKEFROMTEAM    4
-/// Traget attackers
-#define  TFL_DMG_RETALIATE       8
-/// Target attackers, even is on own team
-#define  TFL_DMG_RETALIATEONTEAM 16
-/// Loses target when damaged
-#define  TFL_DMG_TARGETLOSS      32
-/// Reciving damage trows off aim (pointless atm, aim gets recalculated to fast). not implemented.
-#define  TFL_DMG_AIMSHAKE        64
-/// Reciving damage slaps the head arround
-#define  TFL_DMG_HEADSHAKE       128
-/// Die and stay dead.
-#define  TFL_DMG_DEATH_NORESPAWN 256
-/// Supress std turret gibs on death
-#define  TFL_DMG_DEATH_NOGIBS    512
-
-// Spawnflags
-/// Spawn in teambased modes
-#define TFL_SPAWN_TEAM      2
-/// Spawn in FFA modes
-#define TFL_SPAWN_FFA       4
-
-
-/*
-* Fields used by turrets
-*/
-/// Turrets internal ai speed
-.float      ticrate;
-
-/// Where to point the when no target
-.vector     idle_aim;
-
-/// Top part of turret
-.entity     tur_head;
-
-/// Start/respawn health
-.float      tur_health;
-
-/// Defend this entity (or ratehr this entitys position)
-.entity     tur_defend;
-
-/// on/off toggle.
-.float      tur_active;
-
-// Aim from this point,
-//.vector     tur_aimorg;
-
-/// and shoot from here. (can be non constant, think MLRS)
-.vector     tur_shotorg;
-
-/// Aim at this spot
-.vector     tur_aimpos;
-
-/// Predicted time the round will impact
-.float      tur_impacttime;
-
-// Predicted place the round will impact
-//.vector     tur_impactpoint; // unused
-
-/// What entity the aimtrace hit, if any.
-.entity     tur_impactent;
-
-/// Distance to enemy
-.float      tur_dist_enemy;
-
-/// Distance to aimspot
-.float      tur_dist_aimpos;
-
-/// Distance impact<->aim
-.float      tur_dist_impact_to_aimpos;
-
-/// Decresment counter form .shot_volly to 0.
-.float      volly_counter;
-
-/*
-* Projectile/missile. its up to the individual turret implementation to
-** deal the damage, blow upp the missile or whatever.
-*/
-/// Track then refireing is possible
-//.float attack_finished; = attack_finished_single
-/// Shoot this often
-.float shot_refire;
-/// Shots travel this fast, when appliable
-.float shot_speed;
-/// Inaccuracy
-.float shot_spread;
-/// Estimated (core) damage of projectiles. also reduce on ammo with this amount when fiering
-.float shot_dmg;
-/// If radius dmg, this is how big that radius is.
-.float shot_radius;
-/// Max force exserted by round impact
-.float shot_force;
-/// < 1 = shoot # times at target (if possible)
-.float shot_volly;
-/// Refire after a compleated volly.
-.float shot_volly_refire;
-
-/// Consider targets within this range
-.float target_range;
-/// Dont consider targets closer then
-.float target_range_min;
-// Engage fire routine on targets within
-//.float target_range_fire; // no practical use aymore, work with target_range insted.
-/// Targets closer to this are prefered
-.float target_range_optimal;
-
-/*
-* The standard targetselection tries to select a target based on
-* range, angle offset, target type, "is old target"
-* Thise biases will allow score scaling to (dis)favor diffrent targets
-*/
-/// (dis)Favor best range this mutch
-.float target_select_rangebias;
-/// (dis)Favor targeting my old enemy this mutch
-.float target_select_samebias;
-/// (dis)Favor targeting the enemy closest to my guns current angle this mutch
-.float target_select_anglebias;
-/// (dis)Favor Missiles? (-1 to diable targeting compleatly)
-.float target_select_missilebias;
-/// (dis)Favot living players (-1 to diable targeting compleatly)
-.float target_select_playerbias;
-/// Field of view
-//.float target_select_fov;
-/// Last thimestamp this surret aquierd a valid target
-.float target_select_time;
-
-/*
-* Aim refers to real aiming, not gun pos (thats done by track)
-*/
-/// Maximum offset between impact and aim spot to fire
-.float aim_firetolerance_dist;
-// Maximum angular offset between head and aimspot to fire
-//.float aim_firetolerance_angle;
-/// How fast can i rotate/pitch (per second in stepmotor mode, base force in smooth modes)
-.float aim_speed;
-/// cant aim higher/lower then this
-.float aim_maxpitch;
-/// I cant rotate more then this
-.float aim_maxrot;
-
-// Ammo/power. keeping dmg and ammo on a one to one ratio is preferable (for rating)
-/// Staring & current ammo
-.float ammo;
-/// Regenerate this mutch ammo (per second)
-.float ammo_recharge;
-/// Max amount of ammo i can hold
-.float ammo_max;
-
-
-// Uncomment below to enable various debug output.
-//#define TURRET_DEBUG
-//#define TURRET_DEBUG_TARGETVALIDATE
-//#define TURRET_DEBUG_TARGETSELECT
-
-#ifdef TURRET_DEBUG
-.float tur_dbg_dmg_t_h; // Total dmg that hit something (can be more then tur_dbg_dmg_t_f since it should count radius dmg.
-.float tur_dbg_dmg_t_f; // Total damage spent
-.float tur_dbg_start;   // When did i go online?
-.float tur_dbg_tmr1;    // timer for random use
-.float tur_dbg_tmr2;    // timer for random use
-.float tur_dbg_tmr3;    // timer for random use
-.vector tur_dbg_rvec;   // Random vector, mainly for coloruing stuff'
-#endif
-
-// System main's
-/// Main AI loop
-void turret_think();
-/// Prefire checks and sutch
-void turret_fire();
-
-// Callbacks
-/// implements the actual fiering
-.void()  turret_firefunc;
-/// prefire checks go here. return 1 to go bang, 0 not to.
-.float() turret_firecheckfunc;
-// Execure BEFORE main ai loop. return 0 to cancel any following proccessing.
-//.float() turret_prethink;
-/// Execure AFTER main AI loop
-.void()  turret_postthink;
-
-/// Add a target
-.float(entity e_target,entity e_sender) turret_addtarget;
-
-//.float call_diehook;
-//.float call_respwnhook;
-.void() turret_diehook;
-.void() turret_respawnhook;
-
-/*
-#define TEH_THINK 2
-#define TEH_DAMAGE 4
-#define TEH_DIE 8
-#define TEH_RESPAWN 16
-#define TEH_TRACK 32
-#define TEH_AIM 64
-#define TEH_SELECT 128
-.float(float event_id) turret_eventhook;
-*/
-
-/*
-* Some turrets need other aimsystems then other.
-* This should return the place to aim at, not acctualy turn or
-* pitch anyting.
-*
-* use turret_stdproc_aim* or Make your own.
-* Make sure you update tur_enemy_dist and tur_enemy_adist
-* with the apropriate info, if you do.
-
-removed.
-*/
-// function used to aim, usualy turret_stdproc_aim_generic
-//.vector() turret_aim;
-
-/*
-* This is where the acctual turret turning should take place
-* Use turret_stdproc_track or make your own.
-wkacked to save mem.
-*/
-// Function used to turn and pitch the .tur_head usualy turret_stdproc_track
-//.void() turret_track;
-
-/*
-* Target selection, preferably but not nessesarely
-* return a normalized result.
-*/
-/// Function to use for target evaluation. usualy turret_stdproc_targetscore_generic
-.float(entity e_turret, entity e_target) turret_score_target;
-
-/*
-* Damage, death and respawn.
-*/
-//void turret_gibs_precash();
-// generalized so save mem (on fields)
-// Function to handle incomming damage. usualy turret_stdproc_damage
-//.void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce) turret_damagefunc;
-// Function to handle the event of death. usualy turret_stdproc_die
-//.void() turret_diefunc;
-// Function that handles rebirth. usualy turret_stdproc_respawn
-//.void() turret_spawnfunc;
-
-/*
-* Stuff to plug into requierd but unused callbacks.
-*/
-/// Always return 1
-//float turret_stdproc_true();
-/// Always return 0
-//float turret_stdproc_false();
-/// Always return nothing at all
-//void turret_stdproc_nothing();
-
-/*
-* Target selection
-*/
-// noting uses the following atm.
-// "closeer is beter" selection
-//float   turret_stdproc_targetscore_close(entity e_turret, entity e_target);
-// "further is beter" selection
-//float   turret_stdproc_targetscore_far(entity e_turret, entity e_target);
-// only target_range_optimal
-//float   turret_stdproc_targetscore_optimal(entity e_turret, entity e_target);
-// defendpos
-//float   turret_stdproc_targetscore_defend(entity e_turret, entity e_target);
-/// Generic fairly smart bias-aware target selection.
-float   turret_stdproc_targetscore_generic(entity e_turret, entity e_target);
-/// Experimental supportunits targetselector
-float   turret_stdproc_targetscore_support(entity e_turret,entity e_target);
-
-/*
-* Aim functions
-*/
-/// Generic aimer guided by self.aim_flags
-vector turret_stdproc_aim_generic()
-// Straight line, current location
-//vector  turret_stdproc_aim_simple()
-
-/*
-* Turret turning & pitch
-*/
-/// Tries to line up the turret head with the aimpos
-void turret_stdproc_track();
-
-/// Generic damage handeling. blows up the turret when health <= 0
-void turret_stdproc_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce);
-/// Spawns a explotion, does some damage & trows bits arround.
-void turret_stdproc_die();
-/// reassembles the turret.
-void turret_stdproc_respawn();
-
-/// Evaluate target validity
-float turret_validate_target(entity e_turret,entity e_target,float validate_flags);
-/// Turret Head Angle Diff Vector. updated by a sucsessfull call to turret_validate_target
-vector tvt_thadv;
-/// Turret Angle Diff Vector. updated by a sucsessfull call to turret_validate_target
-vector tvt_tadv;
-/// Turret Head Angle Diff Float. updated by a sucsessfull call to turret_validate_target
-float  tvt_thadf;
-/// Turret Angle Diff Float. updated by a sucsessfull call to turret_validate_target
-float  tvt_tadf;
-/// Distance. updated by a sucsessfull call to turret_validate_target
-float  tvt_dist;
-
-/// updates aim org, shot org, shot dir and enemy org for selected turret
-void turret_do_updates(entity e_turret);
-//.vector tur_aimorg_updated; // creates to much aim issues. using tur_shotorg_updated insted.
-//.vector tur_shotorg_updated; // DP8815 fixes gettaginfo, no longer needed.
-.vector tur_shotdir_updated;
-
-void turrets_precash();
-
-
-
-#endif // TTURRETS_ENABLED
-
-
+// Comment out below to skip turrets
+#define TTURRETS_ENABLED
+
+#ifdef TTURRETS_ENABLED
+
+#message "with tZork turrets"
+
+vector real_origin(entity ent);
+
+/// Map time control over pain inflicted
+.float turret_scale_damage;
+/// Map time control targetting range
+.float turret_scale_range;
+/// Map time control refire
+.float turret_scale_refire;
+/// Map time control ammo held and recharged
+.float turret_scale_ammo;
+/// Map time control aim speed
+.float turret_scale_aim;
+/// Map time control health
+.float turret_scale_health;
+/// Map time control respawn time
+.float turret_scale_respawn;
+
+/// Used for cvar reloading
+.string cvar_basename;
+
+//.float spawnflags
+/// Spawn a pillar model under the turret to make it look ok on uneven ground surfaces
+#define TSF_TERRAINBASE   2
+/// Disable builtin ammo regeneration
+#define TSF_NO_AMMO_REGEN 4
+/// Dont break path to chase enemys. will still fire at them if possible.
+#define TSF_NO_PATHBREAK  8
+/// Dont respawn
+#define TSL_NO_RESPAWN    16
+
+/// target selection flags
+.float target_select_flags;
+/// target validatoin flags
+.float target_validate_flags;
+/// Dont select a target on its own.
+#define TFL_TARGETSELECT_NO            2
+/// Need line of sight
+#define TFL_TARGETSELECT_LOS           4
+/// Players are valid targets
+#define TFL_TARGETSELECT_PLAYERS       8
+/// Missiles are valid targets
+#define TFL_TARGETSELECT_MISSILES      16
+/// Responds to turret_trigger_target events
+#define TFL_TARGETSELECT_TRIGGERTARGET 32
+/// Angular limitations of turret head limits target selection
+#define TFL_TARGETSELECT_ANGLELIMITS   64
+/// Range limits apply in targetselection
+#define TFL_TARGETSELECT_RANGELIMTS    128
+/// DOnt select targets with a .team matching its own
+#define TFL_TARGETSELECT_TEAMCHECK     256
+/// Cant select targets on its own. needs to be triggerd or slaved.
+#define TFL_TARGETSELECT_NOBUILTIN     512
+/// TFL_TARGETSELECT_TEAMCHECK is inverted (selects only mebers of own .team)
+#define TFL_TARGETSELECT_OWNTEAM       1024
+/// Turrets aren't valid targets
+#define TFL_TARGETSELECT_NOTURRETS     2048
+/// Use feild of view
+#define TFL_TARGETSELECT_FOV           4096
+
+/// aim flags
+.float aim_flags;
+/// Dont aim.
+#define TFL_AIM_NO                  1
+/// Go for ground, not direct hit
+#define TFL_AIM_GROUND              2
+/// Go for ground, not direct hit, but only if target is on ground.
+#define TFL_AIM_GROUND2             4
+/// Use balistic aim. FIXME: not implemented
+#define TFL_AIM_BALISTIC            8
+/// Try to predict target movement (does not account for gravity)
+#define TFL_AIM_LEAD                16
+/// Compensate for shot traveltime when lead
+#define TFL_AIM_SHOTTIMECOMPENSATE  32
+/// Aim slightly in front of target
+#define TFL_AIM_INFRONT             64
+/// Aim slightly behind target
+#define TFL_AIM_BEHIND              128
+/// blend real and predicted z positions. (fake bounce prediction)
+#define TFL_AIM_ZEASE               256
+/// Try to do real prediction of targets z pos at impact.
+#define TFL_AIM_ZPREDICT            512
+/// Simply aim at target's current location
+#define TFL_AIM_SIMPLE              1024
+
+/// track (turn and pitch head) flags
+.float track_flags;
+/// Dont move head
+#define TFL_TRACK_NO    2
+/// Pitch the head
+#define TFL_TRACK_PITCH 4
+/// Rotate the head
+#define TFL_TRACK_ROT   8
+
+/// How tracking is preformed
+.float track_type;
+/// Hard angle increments. Ugly for fast turning, best accuracy.
+#define TFL_TRACKTYPE_STEPMOTOR    1
+/// Smoth absolute movement. Looks ok, fair accuracy.
+#define TFL_TRACKTYPE_FLUIDPRECISE 2
+/// Simulated inertia. "Wobbly mode" Looks kool, can mean really bad accuracy depending on how the feilds below are set
+#define TFL_TRACKTYPE_FLUIDINERTIA 3
+/// TFL_TRACKTYPE_FLUIDINERTIA: pitch multiplier
+.float track_accel_pitch;
+/// TFL_TRACKTYPE_FLUIDINERTIA: rotation multiplier
+.float  track_accel_rot;
+/// TFL_TRACKTYPE_FLUIDINERTIA: Blendrate with old rotation (inertia simulation) 1  = only old, 0 = only new
+.float  track_blendrate;
+
+/// How prefire check is preformed
+.float firecheck_flags;
+/// Dont kill the world
+#define TFL_FIRECHECK_WORLD       2
+/// Dont kill the dead
+#define TFL_FIRECHECK_DEAD        4
+/// Range limits apply
+#define TFL_FIRECHECK_DISTANCES   8
+/// Line Of Sight needs to be clear
+#define TFL_FIRECHECK_LOS         16
+/// Consider distance inpactpoint<->aimspot
+#define TFL_FIRECHECK_AIMDIST     32
+/// Consider enemy origin<->impactpoint
+#define TFL_FIRECHECK_REALDIST    64
+/// Consider angular diff head<->aimspot
+#define TFL_FIRECHECK_ANGLEDIST  128
+/// (re)consider target.team<->self.team
+#define TFL_FIRECHECK_TEAMCECK   256
+/// Try to avoid friendly fire
+#define TFL_FIRECHECK_AFF        512
+/// Own .ammo needs to be >= then own .shot_dmg
+#define TFL_FIRECHECK_OWM_AMMO   1024
+/// Others ammo need to be < others .ammo_max
+#define TFL_FIRECHECK_OTHER_AMMO 2048
+/// Check own .attack_finished_single vs time
+#define TFL_FIRECHECK_REFIRE     4096
+/// Move the acctual target to aimspot before tracing impact (and back after)
+#define TFL_FIRECHECK_VERIFIED   8192
+/// Dont do any chekcs
+#define TFL_FIRECHECK_NO         16384
+
+/// How shooting is done
+.float shoot_flags;
+/// Dont shoot
+#define  TFL_SHOOT_NO          64
+/// Fire in vollys (partial implementation through .shot_volly)
+#define  TFL_SHOOT_VOLLY       2
+/// Always do a full volly, even if target is lost or dead. (not implemented)
+#define  TFL_SHOOT_VOLLYALWAYS 4
+/// Loop though all valid tarters, and hit them.
+#define  TFL_SHOOT_HITALLVALID 8
+/// Fiering makes unit loose target (after volly is done, if in volly mode)
+#define  TFL_SHOOT_CLEARTARGET 16
+///Custom shooting;
+#define  TFL_SHOOT_CUSTOM 32
+
+/// Information aboute the units capabilities
+.float turrcaps_flags;
+/// No kown capabilities
+#define  TFL_TURRCAPS_NONE        0
+/// Capable of sniping
+#define  TFL_TURRCAPS_SNIPER      2
+/// Capable of splasdamage
+#define  TFL_TURRCAPS_RADIUSDMG   4
+/// Has one or more cannons with zero shot traveltime
+#define  TFL_TURRCAPS_HITSCAN     8
+/// More then one (type of) gun
+#define  TFL_TURRCAPS_MULTIGUN    16
+/// Carries at least one guided weapon
+#define  TFL_TURRCAPS_GUIDED      32
+/// At least one gun fiers slow projectiles
+#define  TFL_TURRCAPS_SLOWPROJ    64
+/// At least one gun fiers medium speed projectiles
+#define  TFL_TURRCAPS_MEDPROJ     128
+/// At least one gun fiers fast projectiles
+#define  TFL_TURRCAPS_FASTPROJ    256
+/// At least one gun capable of damaging players
+#define  TFL_TURRCAPS_PLAYERKILL  512
+/// At least one gun that can shoot town missiles
+#define  TFL_TURRCAPS_MISSILEKILL 1024
+/// Has support capabilities. powerplants and sutch.
+#define  TFL_TURRCAPS_SUPPORT     2048
+/// Proveides at least one type of ammmo
+#define  TFL_TURRCAPS_AMMOSOURCE  4096
+/// Can recive targets from external sources
+#define TFL_TURRCAPS_RECIVETARGETS 8192
+/// Capable of self-transport
+#define TFL_TURRCAPS_MOVE 16384
+/// Will roam arround even if not chasing anyting
+#define TFL_TURRCAPS_ROAM 32768
+#define TFL_TURRCAPS_HEADATTACHED 65536
+
+/// Ammo types needed and/or provided
+.float ammo_flags;
+/// Has and needs no ammo
+#define  TFL_AMMO_NONE     64
+/// Uses power
+#define  TFL_AMMO_ENERGY   2
+/// Uses bullets
+#define  TFL_AMMO_BULLETS  4
+/// Uses explosives
+#define  TFL_AMMO_ROCKETS  8
+/// Regenerates ammo on its own
+#define  TFL_AMMO_RECHARGE 16
+/// Can recive ammo from others
+#define  TFL_AMMO_RECIVE   32
+
+/// How incomming damage is handeld
+.float damage_flags;
+/// Cant be hurt
+#define  TFL_DMG_NO              256
+/// Can be damaged
+#define  TFL_DMG_YES             2
+/// Can be damaged  by teammates
+#define  TFL_DMG_TAKEFROMTEAM    4
+/// Traget attackers
+#define  TFL_DMG_RETALIATE       8
+/// Target attackers, even is on own team
+#define  TFL_DMG_RETALIATEONTEAM 16
+/// Loses target when damaged
+#define  TFL_DMG_TARGETLOSS      32
+/// Reciving damage trows off aim (pointless atm, aim gets recalculated to fast). not implemented.
+#define  TFL_DMG_AIMSHAKE        64
+/// Reciving damage slaps the head arround
+#define  TFL_DMG_HEADSHAKE       128
+/// Die and stay dead.
+#define  TFL_DMG_DEATH_NORESPAWN 256
+/// Supress std turret gibs on death
+#define  TFL_DMG_DEATH_NOGIBS    512
+
+// Spawnflags
+/// Spawn in teambased modes
+#define TFL_SPAWN_TEAM      2
+/// Spawn in FFA modes
+#define TFL_SPAWN_FFA       4
+
+
+/*
+* Fields used by turrets
+*/
+/// Turrets internal ai speed
+.float      ticrate;
+
+/// Where to point the when no target
+.vector     idle_aim;
+
+/// Top part of turret
+.entity     tur_head;
+
+/// Start/respawn health
+.float      tur_health;
+
+/// Defend this entity (or ratehr this entitys position)
+.entity     tur_defend;
+
+/// on/off toggle.
+.float      tur_active;
+
+// Aim from this point,
+//.vector     tur_aimorg;
+
+/// and shoot from here. (can be non constant, think MLRS)
+.vector     tur_shotorg;
+
+/// Aim at this spot
+.vector     tur_aimpos;
+
+/// Predicted time the round will impact
+.float      tur_impacttime;
+
+// Predicted place the round will impact
+//.vector     tur_impactpoint; // unused
+
+/// What entity the aimtrace hit, if any.
+.entity     tur_impactent;
+
+/// Distance to enemy
+.float      tur_dist_enemy;
+
+/// Distance to aimspot
+.float      tur_dist_aimpos;
+
+/// Distance impact<->aim
+.float      tur_dist_impact_to_aimpos;
+
+/// Decresment counter form .shot_volly to 0.
+.float      volly_counter;
+
+/*
+* Projectile/missile. its up to the individual turret implementation to
+** deal the damage, blow upp the missile or whatever.
+*/
+/// Track then refireing is possible
+//.float attack_finished; = attack_finished_single
+/// Shoot this often
+.float shot_refire;
+/// Shots travel this fast, when appliable
+.float shot_speed;
+/// Inaccuracy
+.float shot_spread;
+/// Estimated (core) damage of projectiles. also reduce on ammo with this amount when fiering
+.float shot_dmg;
+/// If radius dmg, this is how big that radius is.
+.float shot_radius;
+/// Max force exserted by round impact
+.float shot_force;
+/// < 1 = shoot # times at target (if possible)
+.float shot_volly;
+/// Refire after a compleated volly.
+.float shot_volly_refire;
+
+/// Consider targets within this range
+.float target_range;
+/// Dont consider targets closer then
+.float target_range_min;
+// Engage fire routine on targets within
+//.float target_range_fire; // no practical use aymore, work with target_range insted.
+/// Targets closer to this are prefered
+.float target_range_optimal;
+
+/*
+* The standard targetselection tries to select a target based on
+* range, angle offset, target type, "is old target"
+* Thise biases will allow score scaling to (dis)favor diffrent targets
+*/
+/// (dis)Favor best range this mutch
+.float target_select_rangebias;
+/// (dis)Favor targeting my old enemy this mutch
+.float target_select_samebias;
+/// (dis)Favor targeting the enemy closest to my guns current angle this mutch
+.float target_select_anglebias;
+/// (dis)Favor Missiles? (-1 to diable targeting compleatly)
+.float target_select_missilebias;
+/// (dis)Favot living players (-1 to diable targeting compleatly)
+.float target_select_playerbias;
+/// Field of view
+//.float target_select_fov;
+/// Last thimestamp this surret aquierd a valid target
+.float target_select_time;
+
+/*
+* Aim refers to real aiming, not gun pos (thats done by track)
+*/
+/// Maximum offset between impact and aim spot to fire
+.float aim_firetolerance_dist;
+// Maximum angular offset between head and aimspot to fire
+//.float aim_firetolerance_angle;
+/// How fast can i rotate/pitch (per second in stepmotor mode, base force in smooth modes)
+.float aim_speed;
+/// cant aim higher/lower then this
+.float aim_maxpitch;
+/// I cant rotate more then this
+.float aim_maxrot;
+
+// Ammo/power. keeping dmg and ammo on a one to one ratio is preferable (for rating)
+/// Staring & current ammo
+.float ammo;
+/// Regenerate this mutch ammo (per second)
+.float ammo_recharge;
+/// Max amount of ammo i can hold
+.float ammo_max;
+
+
+// Uncomment below to enable various debug output.
+//#define TURRET_DEBUG
+//#define TURRET_DEBUG_TARGETVALIDATE
+//#define TURRET_DEBUG_TARGETSELECT
+
+#ifdef TURRET_DEBUG
+.float tur_dbg_dmg_t_h; // Total dmg that hit something (can be more then tur_dbg_dmg_t_f since it should count radius dmg.
+.float tur_dbg_dmg_t_f; // Total damage spent
+.float tur_dbg_start;   // When did i go online?
+.float tur_dbg_tmr1;    // timer for random use
+.float tur_dbg_tmr2;    // timer for random use
+.float tur_dbg_tmr3;    // timer for random use
+.vector tur_dbg_rvec;   // Random vector, mainly for coloruing stuff'
+#endif
+
+// System main's
+/// Main AI loop
+void turret_think();
+/// Prefire checks and sutch
+void turret_fire();
+
+// Callbacks
+/// implements the actual fiering
+.void()  turret_firefunc;
+/// prefire checks go here. return 1 to go bang, 0 not to.
+.float() turret_firecheckfunc;
+// Execure BEFORE main ai loop. return 0 to cancel any following proccessing.
+//.float() turret_prethink;
+/// Execure AFTER main AI loop
+.void()  turret_postthink;
+
+/// Add a target
+.float(entity e_target,entity e_sender) turret_addtarget;
+
+//.float call_diehook;
+//.float call_respwnhook;
+.void() turret_diehook;
+.void() turret_respawnhook;
+
+/*
+#define TEH_THINK 2
+#define TEH_DAMAGE 4
+#define TEH_DIE 8
+#define TEH_RESPAWN 16
+#define TEH_TRACK 32
+#define TEH_AIM 64
+#define TEH_SELECT 128
+.float(float event_id) turret_eventhook;
+*/
+
+/*
+* Some turrets need other aimsystems then other.
+* This should return the place to aim at, not acctualy turn or
+* pitch anyting.
+*
+* use turret_stdproc_aim* or Make your own.
+* Make sure you update tur_enemy_dist and tur_enemy_adist
+* with the apropriate info, if you do.
+
+removed.
+*/
+// function used to aim, usualy turret_stdproc_aim_generic
+//.vector() turret_aim;
+
+/*
+* This is where the acctual turret turning should take place
+* Use turret_stdproc_track or make your own.
+wkacked to save mem.
+*/
+// Function used to turn and pitch the .tur_head usualy turret_stdproc_track
+//.void() turret_track;
+
+/*
+* Target selection, preferably but not nessesarely
+* return a normalized result.
+*/
+/// Function to use for target evaluation. usualy turret_stdproc_targetscore_generic
+.float(entity e_turret, entity e_target) turret_score_target;
+
+/*
+* Damage, death and respawn.
+*/
+//void turret_gibs_precash();
+// generalized so save mem (on fields)
+// Function to handle incomming damage. usualy turret_stdproc_damage
+//.void(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce) turret_damagefunc;
+// Function to handle the event of death. usualy turret_stdproc_die
+//.void() turret_diefunc;
+// Function that handles rebirth. usualy turret_stdproc_respawn
+//.void() turret_spawnfunc;
+
+/*
+* Stuff to plug into requierd but unused callbacks.
+*/
+/// Always return 1
+//float turret_stdproc_true();
+/// Always return 0
+//float turret_stdproc_false();
+/// Always return nothing at all
+//void turret_stdproc_nothing();
+
+/*
+* Target selection
+*/
+// noting uses the following atm.
+// "closeer is beter" selection
+//float   turret_stdproc_targetscore_close(entity e_turret, entity e_target);
+// "further is beter" selection
+//float   turret_stdproc_targetscore_far(entity e_turret, entity e_target);
+// only target_range_optimal
+//float   turret_stdproc_targetscore_optimal(entity e_turret, entity e_target);
+// defendpos
+//float   turret_stdproc_targetscore_defend(entity e_turret, entity e_target);
+/// Generic fairly smart bias-aware target selection.
+float   turret_stdproc_targetscore_generic(entity e_turret, entity e_target);
+/// Experimental supportunits targetselector
+float   turret_stdproc_targetscore_support(entity e_turret,entity e_target);
+
+/*
+* Aim functions
+*/
+/// Generic aimer guided by self.aim_flags
+vector turret_stdproc_aim_generic()
+// Straight line, current location
+//vector  turret_stdproc_aim_simple()
+
+/*
+* Turret turning & pitch
+*/
+/// Tries to line up the turret head with the aimpos
+void turret_stdproc_track();
+
+/// Generic damage handeling. blows up the turret when health <= 0
+void turret_stdproc_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce);
+/// Spawns a explotion, does some damage & trows bits arround.
+void turret_stdproc_die();
+/// reassembles the turret.
+void turret_stdproc_respawn();
+
+/// Evaluate target validity
+float turret_validate_target(entity e_turret,entity e_target,float validate_flags);
+/// Turret Head Angle Diff Vector. updated by a sucsessfull call to turret_validate_target
+vector tvt_thadv;
+/// Turret Angle Diff Vector. updated by a sucsessfull call to turret_validate_target
+vector tvt_tadv;
+/// Turret Head Angle Diff Float. updated by a sucsessfull call to turret_validate_target
+float  tvt_thadf;
+/// Turret Angle Diff Float. updated by a sucsessfull call to turret_validate_target
+float  tvt_tadf;
+/// Distance. updated by a sucsessfull call to turret_validate_target
+float  tvt_dist;
+
+/// updates aim org, shot org, shot dir and enemy org for selected turret
+void turret_do_updates(entity e_turret);
+//.vector tur_aimorg_updated; // creates to much aim issues. using tur_shotorg_updated insted.
+//.vector tur_shotorg_updated; // DP8815 fixes gettaginfo, no longer needed.
+.vector tur_shotdir_updated;
+
+void turrets_precash();
+
+
+
+#endif // TTURRETS_ENABLED
+
+


Property changes on: trunk/data/qcsrc/server/tturrets/include/turrets_early.qh
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/system/system_aimprocs.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_aimprocs.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/system/system_aimprocs.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,122 +1,122 @@
-/*
-* Generic aim
-
-supports:
-TFL_AIM_NO
-TFL_AIM_GROUND
-TFL_AIM_LEAD
-TFL_AIM_SHOTTIMECOMPENSATE
-TFL_AIM_INFRONT
-TFL_AIM_BEHIND
-TFL_AIM_ZEASE
-
-not supported:
-TFL_AIM_BALISTIC
-*/
-vector turret_stdproc_aim_generic()
-{
-
-    vector pre_pos,prep;
-    float distance,impact_time,i,mintime;
-
-    turret_tag_fire_update();
-
-    if(self.aim_flags & TFL_AIM_SIMPLE)
-        return real_origin(self.enemy);
-
-    // Keep track of when we can shoot the next time and
-    // try to predict where the target will be then, so we can put our aimpoint there.
-    // + sys_ticrate for non hitscan, becouse spawned
-    // projectiles dont move during the first tic of their life.
-    if (self.turrcaps_flags & TFL_TURRCAPS_HITSCAN)
-        mintime = max(self.attack_finished_single - time,0);
-    else
-        mintime = max(self.attack_finished_single - time,0) + sys_ticrate;
-
-    // Baseline
-    pre_pos = real_origin(self.enemy);// + (self.enemy.velocity * mintime);
-
-    if (self.aim_flags & TFL_AIM_INFRONT)   // Aim a bit in front of the target
-        pre_pos = pre_pos + (normalize(self.enemy.velocity) * 64);
-
-    if (self.aim_flags & TFL_AIM_BEHIND)    // Aim a bit behind the target
-        pre_pos = pre_pos - (normalize(self.enemy.velocity) * 32);
-
-    // Lead?
-    if (self.aim_flags & TFL_AIM_LEAD)
-    if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE)       // Need to conpensate for shot traveltime
-    {
-        // FIXME: this cant be the best way to do this..
-
-
-        prep = pre_pos;
-        for(i = 0; i < 4; ++i)
-        {
-            distance = vlen(prep - self.tur_shotorg);
-            impact_time = distance / self.shot_speed;
-            prep = pre_pos + self.enemy.velocity * impact_time;
-        }
-
-
-        // tnx to Rudolf "div0" Polzer for this solution.
-        // hmm tobad it dont work.
-        /*
-        vector q;
-        q = solve_quadratic(self.enemy.velocity*self.enemy.velocity - self.shot_speed*self.shot_speed, 2*(pre_pos*self.enemy.velocity), pre_pos * pre_pos);
-        if(q_x > 0)
-            impact_time = q_x;
-        else
-            impact_time = q_y;
-        */
-
-        prep = pre_pos + (self.enemy.velocity * (impact_time + mintime));
-
-        if(self.aim_flags & TFL_AIM_ZPREDICT)
-        if not(self.enemy.flags & FL_ONGROUND)
-        if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE)
-        {
-            float vz;
-            prep_z = pre_pos_z;
-            vz = self.enemy.velocity_z;
-            for(i = 0; i < impact_time; i += sys_ticrate)
-            {
-                vz = vz - (sv_gravity * sys_ticrate);
-                prep_z = prep_z + vz * sys_ticrate;
-            }
-        }
-
-
-        pre_pos = prep;
-    }
-    else
-        pre_pos = pre_pos + self.enemy.velocity * mintime;
-
-    // Smooth out predict-Z?
-    /*
-    if (self.aim_flags & TFL_AIM_ZEASE)
-    if (self.enemy.flags & FL_CLIENT)
-    {
-        vector v;
-        v = real_origin(self.enemy);
-        pre_pos_z = (pre_pos_z + v_z) * 0.5;
-    }
-    */
-
-    if(self.aim_flags & TFL_AIM_GROUND2)
-    {
-        tracebox(pre_pos + '0 0 32',self.enemy.mins,self.enemy.maxs,pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy);
-        if(trace_fraction != 1.0)
-            pre_pos = trace_endpos;
-    }
-
-    /*
-    // This turret should hit the ground neer a target rather the do a direct hit
-    if (self.aim_flags & TFL_AIM_GROUND)
-    {
-        traceline(pre_pos + '0 0 8',pre_pos - '0 0 10000',MOVE_WORLDONLY,self.enemy);
-        pre_pos = trace_endpos;
-    }
-    */
-
-    return pre_pos;
-}
+/*
+* Generic aim
+
+supports:
+TFL_AIM_NO
+TFL_AIM_GROUND
+TFL_AIM_LEAD
+TFL_AIM_SHOTTIMECOMPENSATE
+TFL_AIM_INFRONT
+TFL_AIM_BEHIND
+TFL_AIM_ZEASE
+
+not supported:
+TFL_AIM_BALISTIC
+*/
+vector turret_stdproc_aim_generic()
+{
+
+    vector pre_pos,prep;
+    float distance,impact_time,i,mintime;
+
+    turret_tag_fire_update();
+
+    if(self.aim_flags & TFL_AIM_SIMPLE)
+        return real_origin(self.enemy);
+
+    // Keep track of when we can shoot the next time and
+    // try to predict where the target will be then, so we can put our aimpoint there.
+    // + sys_ticrate for non hitscan, becouse spawned
+    // projectiles dont move during the first tic of their life.
+    if (self.turrcaps_flags & TFL_TURRCAPS_HITSCAN)
+        mintime = max(self.attack_finished_single - time,0);
+    else
+        mintime = max(self.attack_finished_single - time,0) + sys_ticrate;
+
+    // Baseline
+    pre_pos = real_origin(self.enemy);// + (self.enemy.velocity * mintime);
+
+    if (self.aim_flags & TFL_AIM_INFRONT)   // Aim a bit in front of the target
+        pre_pos = pre_pos + (normalize(self.enemy.velocity) * 64);
+
+    if (self.aim_flags & TFL_AIM_BEHIND)    // Aim a bit behind the target
+        pre_pos = pre_pos - (normalize(self.enemy.velocity) * 32);
+
+    // Lead?
+    if (self.aim_flags & TFL_AIM_LEAD)
+    if (self.aim_flags & TFL_AIM_SHOTTIMECOMPENSATE)       // Need to conpensate for shot traveltime
+    {
+        // FIXME: this cant be the best way to do this..
+
+
+        prep = pre_pos;
+        for(i = 0; i < 4; ++i)
+        {
+            distance = vlen(prep - self.tur_shotorg);
+            impact_time = distance / self.shot_speed;
+            prep = pre_pos + self.enemy.velocity * impact_time;
+        }
+
+
+        // tnx to Rudolf "div0" Polzer for this solution.
+        // hmm tobad it dont work.
+        /*
+        vector q;
+        q = solve_quadratic(self.enemy.velocity*self.enemy.velocity - self.shot_speed*self.shot_speed, 2*(pre_pos*self.enemy.velocity), pre_pos * pre_pos);
+        if(q_x > 0)
+            impact_time = q_x;
+        else
+            impact_time = q_y;
+        */
+
+        prep = pre_pos + (self.enemy.velocity * (impact_time + mintime));
+
+        if(self.aim_flags & TFL_AIM_ZPREDICT)
+        if not(self.enemy.flags & FL_ONGROUND)
+        if(self.enemy.movetype == MOVETYPE_WALK || self.enemy.movetype == MOVETYPE_TOSS || self.enemy.movetype == MOVETYPE_BOUNCE)
+        {
+            float vz;
+            prep_z = pre_pos_z;
+            vz = self.enemy.velocity_z;
+            for(i = 0; i < impact_time; i += sys_ticrate)
+            {
+                vz = vz - (sv_gravity * sys_ticrate);
+                prep_z = prep_z + vz * sys_ticrate;
+            }
+        }
+
+
+        pre_pos = prep;
+    }
+    else
+        pre_pos = pre_pos + self.enemy.velocity * mintime;
+
+    // Smooth out predict-Z?
+    /*
+    if (self.aim_flags & TFL_AIM_ZEASE)
+    if (self.enemy.flags & FL_CLIENT)
+    {
+        vector v;
+        v = real_origin(self.enemy);
+        pre_pos_z = (pre_pos_z + v_z) * 0.5;
+    }
+    */
+
+    if(self.aim_flags & TFL_AIM_GROUND2)
+    {
+        tracebox(pre_pos + '0 0 32',self.enemy.mins,self.enemy.maxs,pre_pos -'0 0 64',MOVE_WORLDONLY,self.enemy);
+        if(trace_fraction != 1.0)
+            pre_pos = trace_endpos;
+    }
+
+    /*
+    // This turret should hit the ground neer a target rather the do a direct hit
+    if (self.aim_flags & TFL_AIM_GROUND)
+    {
+        traceline(pre_pos + '0 0 8',pre_pos - '0 0 10000',MOVE_WORLDONLY,self.enemy);
+        pre_pos = trace_endpos;
+    }
+    */
+
+    return pre_pos;
+}


Property changes on: trunk/data/qcsrc/server/tturrets/system/system_aimprocs.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/system/system_main.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_main.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/system/system_main.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,1258 +1,1258 @@
-#define cvar_base "g_turrets_unit_"
-
-/*
-float turret_customizeentityforclient()
-{
-}
-
-float Turret_SendEntity(entity to, float sf)
-{
-
-	WriteByte(MSG_ENTITY, ENT_CLIENT_TURRET);
-	WriteCoord(MSG_ENTITY, self.tur_head.angles_x);
-	WriteCoord(MSG_ENTITY, self.tur_head.angles_y);
-    WriteByte(MSG_ENTITY, self.tur_head.frame);
-
-	//WriteCoord(MSG_ENTITY, self.tur_head.angles_z);
-
-	return TRUE;
-}
-*/
-
-void load_unit_settings(entity ent,string unitname,float is_reload)
-{
-    string sbase;
-
-    // dprint("Reloading turret ",e_turret.netname,"\n");
-
-    if (ent == world)
-        return;
-
-    if (!ent.turret_scale_damage)    ent.turret_scale_damage  = 1;
-    if (!ent.turret_scale_range)     ent.turret_scale_range   = 1;
-    if (!ent.turret_scale_refire)    ent.turret_scale_refire  = 1;
-    if (!ent.turret_scale_ammo)      ent.turret_scale_ammo    = 1;
-    if (!ent.turret_scale_aim)       ent.turret_scale_aim     = 1;
-    if (!ent.turret_scale_health)    ent.turret_scale_health  = 1;
-    if (!ent.turret_scale_respawn)   ent.turret_scale_respawn = 1;
-
-    sbase = strcat(cvar_base,unitname);
-    if (is_reload)
-    {
-        ent.enemy = world;
-        ent.tur_head.avelocity = '0 0 0';
-
-        if (ent.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
-            ent.tur_head.angles = '0 0 0';
-        else
-            ent.tur_head.angles = ent.angles;
-    }
-
-    ent.health      = cvar(strcat(sbase,"_health")) * ent.turret_scale_health;
-    ent.respawntime = cvar(strcat(sbase,"_respawntime")) * ent.turret_scale_respawn;
-
-    ent.shot_dmg          = cvar(strcat(sbase,"_shot_dmg")) * ent.turret_scale_damage;
-    ent.shot_refire       = cvar(strcat(sbase,"_shot_refire")) * ent.turret_scale_refire;
-    ent.shot_radius       = cvar(strcat(sbase,"_shot_radius")) * ent.turret_scale_damage;
-    ent.shot_speed        = cvar(strcat(sbase,"_shot_speed"));
-    ent.shot_spread       = cvar(strcat(sbase,"_shot_spread"));
-    ent.shot_force        = cvar(strcat(sbase,"_shot_force")) * ent.turret_scale_damage;
-    ent.shot_volly        = cvar(strcat(sbase,"_shot_volly"));
-    ent.shot_volly_refire = cvar(strcat(sbase,"_shot_volly_refire")) * ent.turret_scale_refire;
-
-    ent.target_range         = cvar(strcat(sbase,"_target_range")) * ent.turret_scale_range;
-    ent.target_range_min     = cvar(strcat(sbase,"_target_range_min")) * ent.turret_scale_range;
-    //ent.target_range_fire    = cvar(strcat(sbase,"_target_range_fire")) * ent.turret_scale_range;
-    ent.target_range_optimal = cvar(strcat(sbase,"_target_range_optimal")) * ent.turret_scale_range;
-
-    ent.target_select_rangebias  = cvar(strcat(sbase,"_target_select_rangebias"));
-    ent.target_select_samebias   = cvar(strcat(sbase,"_target_select_samebias"));
-    ent.target_select_anglebias  = cvar(strcat(sbase,"_target_select_anglebias"));
-    ent.target_select_playerbias = cvar(strcat(sbase,"_target_select_playerbias"));
-    //ent.target_select_fov = cvar(cvar_gets(sbase,"_target_select_fov"));
-
-    ent.ammo_max      = cvar(strcat(sbase,"_ammo_max")) * ent.turret_scale_ammo;
-    ent.ammo_recharge = cvar(strcat(sbase,"_ammo_recharge")) * ent.turret_scale_ammo;
-
-    ent.aim_firetolerance_dist = cvar(strcat(sbase,"_aim_firetolerance_dist"));
-    ent.aim_speed    = cvar(strcat(sbase,"_aim_speed")) * ent.turret_scale_aim;
-    ent.aim_maxrot   = cvar(strcat(sbase,"_aim_maxrot"));
-    ent.aim_maxpitch = cvar(strcat(sbase,"_aim_maxpitch"));
-
-    ent.track_type        = cvar(strcat(sbase,"_track_type"));
-    ent.track_accel_pitch = cvar(strcat(sbase,"_track_accel_pitch"));
-    ent.track_accel_rot   = cvar(strcat(sbase,"_track_accel_rot"));
-    ent.track_blendrate   = cvar(strcat(sbase,"_track_blendrate"));
-
-    if(is_reload)
-        if(ent.turret_respawnhook)
-            ent.turret_respawnhook();
-
-}
-
-/*
-float turret_stdproc_true()
-{
-    return 1;
-}
-
-float turret_stdproc_false()
-{
-    return 0;
-}
-
-
-void turret_stdproc_nothing()
-{
-    return;
-}
-*/
-
-/**
-** updates enemy distances, predicted impact point/time
-** and updated aim<->predict impact distance.
-**/
-void turret_do_updates(entity t_turret)
-{
-    vector enemy_pos,oldpos;
-    entity oldself;
-
-    oldself = self;
-    self = t_turret;
-
-    enemy_pos = real_origin(self.enemy);
-
-    turret_tag_fire_update();
-
-    self.tur_shotdir_updated = normalize(v_forward);
-
-    self.tur_dist_enemy  = vlen(self.tur_shotorg - enemy_pos);
-    self.tur_dist_aimpos = vlen(self.tur_shotorg - self.tur_aimpos);
-
-    if(self.firecheck_flags & TFL_FIRECHECK_VERIFIED)
-    if(self.enemy)
-    {
-        oldpos = self.enemy.origin;
-        setorigin(self.enemy,self.tur_aimpos);
-    }
-
-    //dprint("NN: ", self.netname," THVN: ",self.tur_head.classname," frame:",ftos(self.tur_head.frame),"\n");
-    //dprint("self.tur_shotorg: ",vtos(self.tur_shotorg),"\n");
-    tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1',self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos),MOVE_NORMAL,self);
-
-    if(self.firecheck_flags & TFL_FIRECHECK_VERIFIED)
-        if(self.enemy)
-            setorigin(self.enemy,oldpos);
-
-    //self.tur_impactpoint           = trace_endpos;
-    self.tur_impactent             = trace_ent;
-    self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins)*0.5);
-    self.tur_impacttime            = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
-
-    self = oldself;
-}
-
-/*
-vector turret_fovsearch_pingpong()
-{
-    vector wish_angle;
-    if(self.phase < time)
-    {
-        if( self.tur_head.phase )
-            self.tur_head.phase = 0;
-        else
-            self.tur_head.phase = 1;
-        self.phase = time + 5;
-    }
-
-    if( self.tur_head.phase)
-        wish_angle = self.idle_aim + '0 1 0' * (self.aim_maxrot * (self.target_select_fov / 360));
-    else
-        wish_angle = self.idle_aim - '0 1 0' * (self.aim_maxrot * (self.target_select_fov / 360));
-
-    return wish_angle;
-}
-
-vector turret_fovsearch_steprot()
-{
-    vector wish_angle;
-    //float rot_add;
-
-    wish_angle   = self.tur_head.angles;
-    wish_angle_x = self.idle_aim_x;
-
-    if (self.phase < time)
-    {
-        //rot_add = self.aim_maxrot / self.target_select_fov;
-        wish_angle_y += (self.target_select_fov * 2);
-
-        if(wish_angle_y > 360)
-            wish_angle_y = wish_angle_y - 360;
-
-         self.phase = time + 1.5;
-    }
-
-    return wish_angle;
-}
-
-vector turret_fovsearch_random()
-{
-    vector wish_angle;
-
-    if (self.phase < time)
-    {
-        wish_angle_y = random() * self.aim_maxrot;
-        if(random() < 0.5)
-            wish_angle_y *= -1;
-
-        wish_angle_x = random() * self.aim_maxpitch;
-        if(random() < 0.5)
-            wish_angle_x *= -1;
-
-        self.phase = time + 5;
-
-        self.tur_aimpos = wish_angle;
-    }
-
-    return self.idle_aim + self.tur_aimpos;
-}
-*/
-
-/**
-** Handles head rotation according to
-** the units .track_type and .track_flags
-**/
-//.entity aim_mark;
-void turret_stdproc_track()
-{
-    vector target_angle; // This is where we want to aim
-    vector move_angle;   // This is where we can aim
-    float f_tmp;
-
-    if (self.track_flags == TFL_TRACK_NO)
-        return;
-
-    if(!self.tur_active)
-        target_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch);
-    else if (self.enemy == world)
-    {
-        if(time > self.lip)
-            if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
-                target_angle = self.idle_aim + self.angles;
-            else
-                target_angle = self.idle_aim;
-        else
-            target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg));
-    }
-    else
-    {
-        // Find the direction
-        target_angle = normalize(self.tur_aimpos - self.tur_shotorg);
-        target_angle = vectoangles(target_angle); // And make a angle
-    }
-
-    self.tur_head.angles_x = safeangle(self.tur_head.angles_x);
-    self.tur_head.angles_y = safeangle(self.tur_head.angles_y);
-
-    // Find the diffrence between where we currently aim and where we want to aim
-    vector a_off;
-
-
-    if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
-    {
-        move_angle = target_angle - (self.angles + self.tur_head.angles);
-        move_angle = shortangle_vxy(move_angle,(self.angles + self.tur_head.angles));
-        a_off = '0 0 0';
-
-    }
-    else
-    {
-        move_angle = target_angle - self.tur_head.angles;
-        move_angle = shortangle_vxy(move_angle,self.tur_head.angles);
-        a_off = self.angles;
-    }
-
-    switch(self.track_type)
-    {
-        case TFL_TRACKTYPE_STEPMOTOR:
-            f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
-            if (self.track_flags & TFL_TRACK_PITCH)
-            {
-                self.tur_head.angles_x += bound(-f_tmp,move_angle_x, f_tmp);
-                if(self.tur_head.angles_x + a_off_x > self.aim_maxpitch)
-                    self.tur_head.angles_x = a_off_x + self.aim_maxpitch;
-
-                if(self.tur_head.angles_x + a_off_x < -self.aim_maxpitch)
-                    self.tur_head.angles_x = a_off_x - self.aim_maxpitch;
-            }
-
-            if (self.track_flags & TFL_TRACK_ROT)
-            {
-                self.tur_head.angles_y += bound(-f_tmp, move_angle_y, f_tmp);
-                if((self.tur_head.angles_y - a_off_y) > self.aim_maxrot)
-                    self.tur_head.angles_y = a_off_y + self.aim_maxrot;
-
-                if((self.tur_head.angles_y - a_off_y) < -self.aim_maxrot)
-                    self.tur_head.angles_y = a_off_y - self.aim_maxrot;
-            }
-
-            return;
-
-        case TFL_TRACKTYPE_FLUIDINERTIA:
-            f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
-            move_angle_x = bound(-self.aim_speed, move_angle_x * self.track_accel_pitch * f_tmp,self.aim_speed);
-            move_angle_y = bound(-self.aim_speed, move_angle_y * self.track_accel_rot * f_tmp,self.aim_speed);
-            move_angle = (self.tur_head.avelocity * self.track_blendrate) + (move_angle * (1 - self.track_blendrate));
-            break;
-
-        case TFL_TRACKTYPE_FLUIDPRECISE:
-
-            move_angle_y = bound(-self.aim_speed, move_angle_y, self.aim_speed);
-            move_angle_x = bound(-self.aim_speed, move_angle_x, self.aim_speed);
-
-            break;
-    }
-
-    //  pitch
-    if (self.track_flags & TFL_TRACK_PITCH)
-    {
-        self.tur_head.avelocity_x = move_angle_x;
-        if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) + a_off_x > self.aim_maxpitch)
-        {
-            self.tur_head.avelocity_x = 0;
-            self.tur_head.angles_x = a_off_x + self.aim_maxpitch;
-        }
-        if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) + a_off_x < -self.aim_maxpitch)
-        {
-            self.tur_head.avelocity_x = 0;
-            self.tur_head.angles_x = a_off_x - self.aim_maxpitch;
-        }
-
-    }
-
-    //  rot
-    if (self.track_flags & TFL_TRACK_ROT)
-    {
-        self.tur_head.avelocity_y = move_angle_y;
-
-        if(((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate)- a_off_y) > self.aim_maxrot)
-        {
-            self.tur_head.avelocity_y = 0;
-            self.tur_head.angles_y = a_off_y + self.aim_maxrot;
-        }
-
-        if(((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) - a_off_y) < -self.aim_maxrot)
-        {
-            self.tur_head.avelocity_y = 0;
-            self.tur_head.angles_y = a_off_y - self.aim_maxrot;
-        }
-
-    }
-
-}
-
-
-/*
- + = implemented
- - = not implemented
-
- + TFL_FIRECHECK_NO
- + TFL_FIRECHECK_WORLD
- + TFL_FIRECHECK_DEAD
- + TFL_FIRECHECK_DISTANCES
- - TFL_FIRECHECK_LOS
- + TFL_FIRECHECK_AIMDIST
- + TFL_FIRECHECK_REALDIST
- - TFL_FIRECHECK_ANGLEDIST
- - TFL_FIRECHECK_TEAMCECK
- + TFL_FIRECHECK_AFF
- + TFL_FIRECHECK_OWM_AMMO
- + TFL_FIRECHECK_OTHER_AMMO
- + TFL_FIRECHECK_REFIRE
-*/
-
-/**
-** Preforms pre-fire checks based on the uints firecheck_flags
-**/
-float turret_stdproc_firecheck()
-{
-    // This one just dont care =)
-    if (self.firecheck_flags & TFL_FIRECHECK_NO) return 1;
-
-    // Ready?
-    if (self.firecheck_flags & TFL_FIRECHECK_REFIRE)
-        if (self.attack_finished_single >= time) return 0;
-
-    // Special case: volly fire turret that has to fire a full volly if a shot was fired.
-    if((self.shoot_flags & TFL_SHOOT_VOLLYALWAYS) && (self.volly_counter != self.shot_volly))
-        return 1;
-
-    // Lack of zombies makes shooting dead things unnecessary :P
-    if (self.firecheck_flags & TFL_FIRECHECK_DEAD)
-        if (self.enemy.deadflag != DEAD_NO) return 0;
-
-    // Plz stop killing the world!
-    if (self.firecheck_flags & TFL_FIRECHECK_WORLD)
-        if (self.enemy == world) return 0;
-
-    // Own ammo?
-    if (self.firecheck_flags & TFL_FIRECHECK_OWM_AMMO)
-        if (self.ammo < self.shot_dmg) return 0;
-
-    // Other's ammo? (support-supply units)
-    if (self.firecheck_flags & TFL_FIRECHECK_OTHER_AMMO)
-        if (self.enemy.ammo >= self.enemy.ammo_max) return 0;
-
-    if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES)
-    {
-        // Not close enougth?
-        //if (self.tur_dist_aimpos > self.target_range_fire) return 0;
-
-        // To close?
-        if (self.tur_dist_aimpos < self.target_range_min) return 0;
-    }
-
-    // Try to avoid FF?
-    if (self.firecheck_flags & TFL_FIRECHECK_AFF)
-        if (self.tur_impactent.team == self.team) return 0;
-
-    // aim<->predicted impact
-    if (self.firecheck_flags & TFL_FIRECHECK_AIMDIST)
-        if (self.tur_dist_impact_to_aimpos  > self.aim_firetolerance_dist)
-            if (self.tur_impactent != self.enemy)
-                return 0;
-
-    // Volly status
-    if (self.shot_volly > 1)
-        if (self.volly_counter == self.shot_volly)
-            if (self.ammo < (self.shot_dmg * self.shot_volly))
-                return 0;
-
-    if(self.firecheck_flags & TFL_FIRECHECK_VERIFIED)
-        if(self.tur_impactent != self.enemy)
-            return 0;
-
-    return 1;
-}
-
-/*
- + TFL_TARGETSELECT_NO
- + TFL_TARGETSELECT_LOS
- + TFL_TARGETSELECT_PLAYERS
- + TFL_TARGETSELECT_MISSILES
- - TFL_TARGETSELECT_TRIGGERTARGET
- + TFL_TARGETSELECT_ANGLELIMITS
- + TFL_TARGETSELECT_RANGELIMTS
- + TFL_TARGETSELECT_TEAMCHECK
- - TFL_TARGETSELECT_NOBUILTIN
- + TFL_TARGETSELECT_OWNTEAM
-*/
-
-/**
-** Evaluate a entity for target valitity based on validate_flags
-**/
-float turret_validate_target(entity e_turret,entity e_target,float validate_flags)
-{
-    vector v_tmp;
-
-    //if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN)
-    //    return -0.5;
-
-    if(e_target.owner == e_turret)
-        return -0.5;
-
-    if not(checkpvs(e_target.origin, e_turret))
-        return -1;
-
-    if (!e_target)// == world)
-        return -2;
-
-	if(g_onslaught)
-		if (substring(e_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job!
-			return - 3;
-
-    if (validate_flags & TFL_TARGETSELECT_NO)
-        return -4;
-
-    // If only this was used more..
-    if (e_target.flags & FL_NOTARGET)
-        return -5;
-
-    // Cant touch this
-    if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
-        return -6;
-
-    // player
-    if (e_target.flags & FL_CLIENT)
-    {
-        if not (validate_flags & TFL_TARGETSELECT_PLAYERS)
-            return -7;
-
-        if (e_target.deadflag != DEAD_NO)
-            return -8;
-    }
-
-	// enemy turrets
-	if (validate_flags & TFL_TARGETSELECT_NOTURRETS)
-        if (e_target.turret_firefunc || e_target.owner.tur_head == e_target)
-            if(e_target.team != e_turret.team) // Dont break support units.
-                return -9;
-
-    // Missile
-    if (e_target.flags & FL_PROJECTILE)
-        if not (validate_flags & TFL_TARGETSELECT_MISSILES)
-            return -10;
-
-    // Team check
-    if (validate_flags & TFL_TARGETSELECT_TEAMCHECK)
-    {
-        if (validate_flags & TFL_TARGETSELECT_OWNTEAM)
-        {
-            if (e_target.team != e_turret.team)
-                return -11;
-
-            if (e_turret.team != e_target.owner.team)
-                return -12;
-        }
-        else
-        {
-            if (e_target.team == e_turret.team)
-                return -13;
-
-            if (e_turret.team == e_target.owner.team)
-                return -14;
-        }
-    }
-
-    // Range limits?
-    tvt_dist = vlen(e_turret.origin - real_origin(e_target));
-    if (validate_flags & TFL_TARGETSELECT_RANGELIMTS)
-    {
-        if (tvt_dist < e_turret.target_range_min)
-            return -15;
-
-        if (tvt_dist > e_turret.target_range)
-            return -16;
-    }
-
-    // Can we even aim this thing?
-    if(e_turret.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
-    {
-        tvt_thadv = angleofs3(e_turret.tur_head.origin,e_turret.angles + e_turret.tur_head.angles ,e_target);
-        //tvt_thadv = angleofs(e_turret.angles,e_target);
-    }
-    else
-    {
-        tvt_thadv = angleofs(e_turret.tur_head,e_target);
-    }
-
-    tvt_tadv  = shortangle_vxy(angleofs(e_turret,e_target),e_turret.angles);
-    tvt_thadf = vlen(tvt_thadv);
-    tvt_tadf  = vlen(tvt_tadv);
-
-    /*
-    if(validate_flags & TFL_TARGETSELECT_FOV)
-    {
-        if(e_turret.target_select_fov < tvt_thadf)
-            return -21;
-    }
-    */
-
-    if (validate_flags & TFL_TARGETSELECT_ANGLELIMITS)
-    {
-        if (fabs(tvt_tadv_x) > e_turret.aim_maxpitch)
-            return -17;
-
-        if (fabs(tvt_tadv_y) > e_turret.aim_maxrot)
-            return -18;
-    }
-
-    // Line of sight?
-    if (validate_flags & TFL_TARGETSELECT_LOS)
-    {
-        v_tmp = real_origin(e_target) + ((e_target.mins + e_target.maxs) * 0.5);
-        traceline(e_turret.tur_shotorg,v_tmp,0,e_turret);
-
-        if (e_turret.aim_firetolerance_dist < vlen(v_tmp - trace_endpos))
-            return -19;
-    }
-
-    if (e_target.classname == "grapplinghook")
-        return -20;
-
-#ifdef TURRET_DEBUG_TARGETSELECT
-    dprint("Target:",e_target.netname," is a valid target for ",e_turret.netname,"\n");
-#endif
-
-    return 1;
-}
-
-entity turret_select_target()
-{
-    entity e;        // target looper entity
-    float  score;    // target looper entity score
-    entity e_enemy;  // currently best scoreing target
-    float  m_score;  // currently best scoreing target's score
-    float f;
-
-    m_score = 0;
-    if(self.enemy)
-    if(turret_validate_target(self,self.enemy,self.target_validate_flags) > 0)
-    {
-        e_enemy = self.enemy;
-        m_score = self.turret_score_target(self,e_enemy) * self.target_select_samebias;
-    }
-
-    e = findradius(self.origin,self.target_range);
-
-    // Nothing to aim at?
-    if (!e) return world;
-
-    while (e)
-    {
-        f = turret_validate_target(self,e,self.target_select_flags);
-        if (f > 0)
-        {
-            score = self.turret_score_target(self,e);
-            if ((score > m_score) && (score > 0))
-            {
-                e_enemy = e;
-                m_score = score;
-            }
-        }
-        e = e.chain;
-    }
-
-    return e_enemy;
-}
-
-void turret_think()
-{
-    entity e;
-
-    self.nextthink = time + self.ticrate;
-
-    // ONS uses somewhat backwards linking.
-    if (teamplay)
-    {
-        if not (g_onslaught)
-            if (self.target)
-            {
-                e = find(world,targetname,self.target);
-                if (e != world)
-                    self.team = e.team;
-            }
-
-        if (self.team != self.tur_head.team)
-            turret_stdproc_respawn();
-    }
-
-
-    if (cvar("g_turrets_reloadcvars") == 1)
-    {
-        e = nextent(world);
-        while (e)
-        {
-            if (e.tur_head != world)
-            {
-
-                load_unit_settings(e,e.cvar_basename,1);
-                if(e.turret_postthink)
-                    e.turret_postthink();
-            }
-
-            e = nextent(e);
-        }
-
-        cvar_set("g_turrets_reloadcvars","0");
-    }
-
-#ifdef TURRET_DEBUG
-    if (self.tur_dbg_tmr1 < time)
-    {
-        if (self.enemy) paint_target (self.enemy,128,self.tur_dbg_rvec,0.9);
-        paint_target(self,256,self.tur_dbg_rvec,0.9);
-        self.tur_dbg_tmr1 = time + 1;
-    }
-#endif
-
-    // Handle ammo
-    if not (self.spawnflags & TSF_NO_AMMO_REGEN)
-    if (self.ammo < self.ammo_max)
-        self.ammo = min(self.ammo + self.ammo_recharge,self.ammo_max);
-
-
-    // Inactive turrets needs to run the think loop,
-    // So they can handle animation and wake up if need be.
-    if not (self.tur_active)
-    {
-        turret_stdproc_track();
-        return;
-    }
-
-    //This is just wrong :|
-    if(self.deadflag != DEAD_NO)
-    {
-        dprint("WARNING: dead turret running the think function!\n");
-        return;
-    }
-
-    // This is typicaly used for zaping every target in range
-    // turret_fusionreactor uses this to recharge friendlys.
-    if (self.shoot_flags & TFL_SHOOT_HITALLVALID)
-    {
-
-        // Do a self.turret_fire for every valid target.
-        e = findradius(self.origin,self.target_range);
-        while (e)
-        {
-            if (turret_validate_target(self,e,self.target_validate_flags))
-            {
-                self.enemy = e;
-
-                turret_do_updates(self);
-
-                if (self.turret_firecheckfunc())
-                    turret_fire();
-            }
-
-            e = e.chain;
-        }
-        self.enemy = world;
-    }
-    else if(self.shoot_flags & TFL_SHOOT_CUSTOM)
-    {
-        // This one is doing something.. oddball. assume its handles what needs to be handled.
-
-        // Predict?
-        if not((self.aim_flags & TFL_AIM_NO))
-            self.tur_aimpos = turret_stdproc_aim_generic();
-
-        // Turn & pitch?
-        if (!self.track_flags & TFL_TRACK_NO)
-            turret_stdproc_track();
-
-        turret_do_updates(self);
-
-        // Fire?
-        if (self.turret_firecheckfunc())
-            turret_fire();
-    }
-    else
-    {
-        // Special case for volly always. if it fired once it must compleate the volly.
-        if(self.shoot_flags & TFL_SHOOT_VOLLYALWAYS)
-            if(self.volly_counter != self.shot_volly)
-            {
-                // Predict or whatnot
-                if not((self.aim_flags & TFL_AIM_NO))
-                    self.tur_aimpos = turret_stdproc_aim_generic();
-
-                // Turn & pitch
-                if (!self.track_flags & TFL_TRACK_NO)
-                    turret_stdproc_track();
-
-                turret_do_updates(self);
-
-                // Fire!
-                if (self.turret_firecheckfunc() != 0)
-                    turret_fire();
-
-                if(self.turret_postthink)
-                    self.turret_postthink();
-
-                return;
-            }
-
-        // Check if we have a vailid enemy, and try to find one if we dont.
-        if( ((self.target_select_time + cvar("g_turrets_targetscan_maxdelay")) < time)
-          || (turret_validate_target(self,self.enemy,self.target_validate_flags) <= 0) )
-        if not (self.target_select_time + cvar("g_turrets_targetscan_mindelay") > time)
-        {
-            self.enemy = turret_select_target();
-            //if(self.enemy)
-                self.target_select_time = time;
-
-        }
-
-
-        // No target, just go to idle, do any custom stuff and bail.
-        if (self.enemy == world)
-        {
-            // Turn & pitch
-            if (!self.track_flags & TFL_TRACK_NO)
-                turret_stdproc_track();
-
-            // do any per-turret stuff
-            if(self.turret_postthink)
-                self.turret_postthink();
-
-            // And bail.
-            return;
-        }
-        else
-            self.lip = time + cvar("g_turrets_aimidle_delay"); // Keep track of the last time we had a target.
-
-        // Predict?
-        if not((self.aim_flags & TFL_AIM_NO))
-            self.tur_aimpos = turret_stdproc_aim_generic();
-
-        // Turn & pitch?
-        if (!self.track_flags & TFL_TRACK_NO)
-            turret_stdproc_track();
-
-        turret_do_updates(self);
-        // Fire?
-        if (self.turret_firecheckfunc())
-            turret_fire();
-    }
-
-    // do any per-turret stuff
-    if(self.turret_postthink)
-        self.turret_postthink();
-}
-
-void turret_fire()
-{
-    if (cvar("g_turrets_nofire") != 0)
-        return;
-
-    if ((!self.tur_active) || (self.deadflag != DEAD_NO))
-        return;
-
-    self.turret_firefunc();
-
-    self.attack_finished_single = time + self.shot_refire;
-    self.ammo                   = self.ammo - self.shot_dmg;
-    self.volly_counter          = self.volly_counter - 1;
-    if (self.volly_counter <= 0)
-    {
-        self.volly_counter = self.shot_volly;
-
-        if (self.shoot_flags & TFL_SHOOT_CLEARTARGET)
-            self.enemy = world;
-
-        if (self.shot_volly > 1)
-            self.attack_finished_single = time + self.shot_volly_refire;
-    }
-
-
-#ifdef TURRET_DEBUG
-    if (self.enemy) paint_target3(self.tur_aimpos, 64, self.tur_dbg_rvec, self.tur_impacttime + 0.25);
-#endif
-}
-
-void turret_stdproc_fire()
-{
-    dprint("^1Bang, ^3your dead^7 ",self.enemy.netname,"! ^1(turret with no real firefunc)\n");
-}
-
-/*
-    When .used a turret switch team to activator.team.
-    If activator is world, the turrets goes inactive.
-*/
-void turret_stdproc_use()
-{
-    dprint("Turret ",self.netname, " used by ",activator.classname,"\n");
-
-    self.team = activator.team;
-
-    if(self.team == 0)
-        self.tur_active = 0;
-    else
-        self.tur_active = 1;
-
-}
-
-void turret_link()
-{
-    //Net_LinkEntity(self, FALSE, 0, Turret_SendEntity);
-    self.think      = turret_think;
-    self.nextthink  = time;
-}
-
-/*
-* Standard turret initialization. use this!
-* (unless you have a very good reason not to)
-* if the return value is 0, the turret should be removed.
-*/
-float turret_stdproc_init (string cvar_base_name, float csqc_shared)
-{
-	entity e,ee;
-
-    if(csqc_shared)
-    {
-        dprint("turrets: csqc_shared requested but not implemented. expect strange things to happen.\n");
-        csqc_shared = 0;
-    }
-
-    // Are turrets allowed atm?
-    if (cvar("g_turrets") == 0)
-        return 0;
-
-    // Better more then once then never.
-    // turret_gibs_precash();
-
-    // Terrainbase spawnflag. This puts a enlongated model
-    // under the turret, so it looks ok on uneaven surfaces.
-    if (self.spawnflags & TSF_TERRAINBASE)
-    {
-        entity tb;
-        //precache_model("models/turrets/terrainbase.md3");
-        tb = spawn();
-        setmodel(tb,"models/turrets/terrainbase.md3");
-        setorigin(tb,self.origin);
-        tb.solid = SOLID_BBOX;
-        //makestatic(tb);
-    }
-
-    self.cvar_basename = cvar_base_name;
-    load_unit_settings(self,self.cvar_basename,0);
-
-    // Handle turret teams.
-    if (cvar("g_assult") != 0)
-    {
-        if (!self.team)
-            self.team = 14; // Assume turrets are on the defending side if not explicitly set otehrwize
-    }
-    else if (!teamplay)
-		self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team iso they dont kill eachother.
-	else if(g_onslaught && self.targetname)
-	{
-		e = find(world,target,self.targetname);
-		if(e != world)
-		{
-			self.team = e.team;
-			ee = e;
-		}
-	}
-	else if(!self.team)
-		self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team iso they dont kill eachother.
-
-
-
-    /*
-    * Try to guess some reasonaly defaults
-    * for missing params and do sanety checks
-    * thise checks could produce some "interesting" results
-    * if it hits a glitch in my logic :P so try to set as mutch
-    * as possible beforehand.
-    */
-    if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
-        if (!self.ticrate) self.ticrate = 0.2;     // Support units generaly dont need to have a high speed ai-loop
-    else
-        if (!self.ticrate) self.ticrate = 0.1;     // 10 fps for normal turrets
-
-    self.ticrate = bound(sys_ticrate,self.ticrate,60);  // keep it sane
-
-// General stuff
-    if (self.netname == "")
-        self.netname = self.classname;
-
-    if (!self.respawntime)
-        self.respawntime = 60;
-    self.respawntime = max(-1,self.respawntime);
-
-    if (!self.health)
-        self.health = 1000;
-    self.tur_health = max(1,self.health);
-
-    if (!self.turrcaps_flags)
-        self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
-
-    if (!self.damage_flags)
-        self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
-
-// Shot stuff.
-    if (!self.shot_refire)
-        self.shot_refire = 1;
-    self.shot_refire = bound(0.01,self.shot_refire,9999);
-
-    if (!self.shot_dmg)
-        self.shot_dmg  = self.shot_refire * 50;
-    self.shot_dmg = max(1,self.shot_dmg);
-
-    if (!self.shot_radius)
-        self.shot_radius = self.shot_dmg * 0.5;
-    self.shot_radius = max(1,self.shot_radius);
-
-    if (!self.shot_speed)
-        self.shot_speed = 2500;
-    self.shot_speed = max(1,self.shot_speed);
-
-    if (!self.shot_spread)
-        self.shot_spread = 0.0125;
-    self.shot_spread = bound(0.0001,self.shot_spread,500);
-
-    if (!self.shot_force)
-        self.shot_force = self.shot_dmg * 0.5 + self.shot_radius * 0.5;
-    self.shot_force = bound(0.001,self.shot_force,MAX_SHOT_DISTANCE * 0.5);
-
-    if (!self.shot_volly)
-        self.shot_volly = 1;
-    self.shot_volly = bound(1,self.shot_volly,floor(self.ammo_max / self.shot_dmg));
-
-    if (!self.shot_volly_refire)
-        self.shot_volly_refire = self.shot_refire * self.shot_volly;
-    self.shot_volly_refire = bound(self.shot_refire,self.shot_volly_refire,60);
-
-    if (!self.firecheck_flags)
-        self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES |
-                               TFL_FIRECHECK_LOS | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCECK |
-                               TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_WORLD;
-
-// Range stuff.
-    if (!self.target_range)
-        self.target_range = self.shot_speed * 0.5;
-    self.target_range = bound(0,self.target_range,MAX_SHOT_DISTANCE);
-
-    if (!self.target_range_min)
-        self.target_range_min = self.shot_radius * 2;
-    self.target_range_min = bound(0,self.target_range_min,MAX_SHOT_DISTANCE);
-
-    //if (!self.target_range_fire)
-    //    self.target_range_fire = self.target_range * 0.8;
-    //self.target_range_fire = bound(0,self.target_range_fire,MAX_SHOT_DISTANCE);
-
-    if (!self.target_range_optimal)
-        self.target_range_optimal = self.target_range * 0.5;
-    self.target_range_optimal = bound(0,self.target_range_optimal,MAX_SHOT_DISTANCE);
-
-
-// Aim stuff.
-    if (!self.aim_maxrot)
-        self.aim_maxrot = 90;
-    self.aim_maxrot = bound(0,self.aim_maxrot,360);
-
-    if (!self.aim_maxpitch)
-        self.aim_maxpitch = 20;
-    self.aim_maxpitch = bound(0,self.aim_maxpitch,90);
-
-    if (!self.aim_speed)
-        self.aim_speed = 36;
-    self.aim_speed  = bound(0.1,self.aim_speed, 1000);
-
-    if (!self.aim_firetolerance_dist)
-        self.aim_firetolerance_dist  = 5 + (self.shot_radius * 2);
-    self.aim_firetolerance_dist = bound(0.1,self.aim_firetolerance_dist,MAX_SHOT_DISTANCE);
-
-    if (!self.aim_flags)
-    {
-        self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-        if(self.turrcaps_flags & TFL_TURRCAPS_RADIUSDMG)
-            self.aim_flags |= TFL_AIM_GROUND2;
-    }
-
-    // Sill the most tested (and aim-effective)
-    if (!self.track_type) self.track_type = TFL_TRACKTYPE_STEPMOTOR;
-
-    if (self.track_type != TFL_TRACKTYPE_STEPMOTOR)
-    {
-        // Fluid / Ineria mode. Looks mutch nicer, bit experimental &
-        // Can inmapt aim preformance alot.
-        // needs a bit diffrent aimspeed
-
-        if (!self.aim_speed)
-            self.aim_speed = 180;
-        self.aim_speed = bound(0.1,self.aim_speed, 1000);
-
-        if (!self.track_accel_pitch)
-            self.track_accel_pitch = 0.5;
-
-        if (!self.track_accel_rot)
-            self.track_accel_rot   = 0.5;
-
-        if (!self.track_blendrate)
-            self.track_blendrate   = 0.35;
-    }
-
-    if (!self.track_flags)
-        self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROT;
-
-
-// Target selection stuff.
-    if (!self.target_select_rangebias)
-        self.target_select_rangebias = 1;
-    self.target_select_rangebias = bound(-10,self.target_select_rangebias,10);
-
-    if (!self.target_select_samebias)
-        self.target_select_samebias = 1;
-    self.target_select_samebias = bound(-10,self.target_select_samebias,10);
-
-    if (!self.target_select_anglebias)
-        self.target_select_anglebias = 1;
-    self.target_select_anglebias = bound(-10,self.target_select_anglebias,10);
-
-    if (!self.target_select_missilebias)
-        self.target_select_missilebias = -10;
-
-    self.target_select_missilebias = bound(-10,self.target_select_missilebias,10);
-    self.target_select_playerbias = bound(-10,self.target_select_playerbias,10);
-
-    if (!self.target_select_flags)
-    {
-            self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_TEAMCHECK
-                                     | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
-
-        if (self.turrcaps_flags & TFL_TURRCAPS_MISSILEKILL)
-            self.target_select_flags |= TFL_TARGETSELECT_MISSILES;
-
-        if (self.turrcaps_flags & TFL_TURRCAPS_PLAYERKILL)
-            self.target_select_flags |= TFL_TARGETSELECT_PLAYERS;
-        //else
-        //    self.target_select_flags = TFL_TARGETSELECT_NO;
-    }
-
-    self.target_validate_flags = self.target_select_flags;
-
-
-// Ammo stuff
-    if (!self.ammo_max)
-        self.ammo_max = self.shot_dmg * 10;
-    self.ammo_max = max(self.shot_dmg,self.ammo_max);
-
-    if (!self.ammo)
-        self.ammo = self.shot_dmg * 5;
-    self.ammo = bound(0,self.ammo,self.ammo_max);
-
-    if (!self.ammo_recharge)
-        self.ammo_recharge = self.shot_dmg * 0.5;
-    self.ammo_recharge = max(0,self.ammo_recharge);
-
-    // Convert the recharge from X per sec to X per ticrate
-    self.ammo_recharge = self.ammo_recharge * self.ticrate;
-
-    if (!self.ammo_flags)
-        self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
-
-// Damage stuff
-    if(self.spawnflags & TSL_NO_RESPAWN)
-        if not (self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
-            self.damage_flags |= TFL_DMG_DEATH_NORESPAWN;
-
-// Offsets & origins
-    if (!self.tur_shotorg)   self.tur_shotorg = '50 0 50';
-
-// End of default & sanety checks, start building the turret.
-
-// Spawn extra bits
-    self.tur_head         = spawn();
-    self.tur_head.netname = self.tur_head.classname = "turret_head";
-    self.tur_head.team    = self.team;
-    self.tur_head.owner   = self;
-
-    // Defend mode?
-    if(!self.tur_defend)
-    if (self.target != "")
-    {
-        self.tur_defend = find(world, targetname, self.target);
-        if (self.tur_defend == world)
-        {
-            self.target = "";
-            dprint("Turret has invalid defendpoint!\n");
-        }
-    }
-
-// Put pices in place
-    if not (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
-        setorigin(self.tur_head,self.origin);
-
-    // In target defend mode, aim on the spot to defend when idle.
-    if(self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
-    {
-        if (self.tur_defend)
-            self.idle_aim  = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend);
-        else
-            self.idle_aim  = '0 0 0';
-    }
-    else
-    {
-        if (self.tur_defend)
-            self.idle_aim  = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend);
-        else
-            self.idle_aim  = self.angles;
-    }
-
-    if not (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
-        self.tur_head.angles    = self.idle_aim;
-
-    if (!self.health)
-        self.health = 150;
-
-    self.tur_health      = self.health;
-    self.tur_head.health = self.health;
-
-    self.solid          = SOLID_BBOX;
-    self.tur_head.solid = SOLID_BBOX;
-
-    self.takedamage          = DAMAGE_AIM;
-    self.tur_head.takedamage = DAMAGE_AIM;
-
-    self.movetype            = MOVETYPE_NOCLIP;
-    self.tur_head.movetype   = MOVETYPE_NOCLIP;
-
-    // Team color
-    if (self.team == COLOR_TEAM1) self.colormod = '1.4 0.8 0.8';
-    if (self.team == COLOR_TEAM2) self.colormod = '0.8 0.8 1.4';
-
-    // Attach stdprocs. override when and what needed
-    if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
-    {
-        self.turret_score_target    = turret_stdproc_targetscore_support;
-        self.turret_firecheckfunc   = turret_stdproc_firecheck;
-        self.turret_firefunc        = turret_stdproc_fire;
-        //self.turret_postthink       = turret_stdproc_nothing;
-        self.event_damage           = turret_stdproc_damage;
-        self.tur_head.event_damage  = turret_stdproc_damage;
-    }
-    else
-    {
-        self.turret_score_target    = turret_stdproc_targetscore_generic;
-        self.turret_firecheckfunc   = turret_stdproc_firecheck;
-        self.turret_firefunc        = turret_stdproc_fire;
-        //self.turret_postthink       = turret_stdproc_nothing;
-        self.event_damage           = turret_stdproc_damage;
-        self.tur_head.event_damage  = turret_stdproc_damage;
-        //self.turret_addtarget       = turret_stdproc_false;
-    }
-
-    self.use = turret_stdproc_use;
-    self.bot_attack = TRUE;
-
-    // Initiate the main AI loop
-    if(csqc_shared)
-        self.think     = turret_link;
-    else
-        self.think     = turret_think;
-
-    self.nextthink = time + self.ticrate;
-
-    self.tur_head.team = self.team;
-    self.view_ofs = '0 0 0';
-
-#ifdef TURRET_DEBUG
-    self.tur_dbg_start = self.nextthink;
-    while (vlen(self.tur_dbg_rvec) < 2)
-        self.tur_dbg_rvec  = randomvec() * 4;
-
-    self.tur_dbg_rvec_x = fabs(self.tur_dbg_rvec_x);
-    self.tur_dbg_rvec_y = fabs(self.tur_dbg_rvec_y);
-    self.tur_dbg_rvec_z = fabs(self.tur_dbg_rvec_z);
-#endif
-
-    // Its all good.
-    self.classname = "turret_main";
-
-    self.tur_active = 1;
-
-    // In ONS mode, and linked to a ONS ent. need to call the use to set team.
-    if (g_onslaught && ee)
-    {
-        activator = ee;
-        self.use();
-    }
-
-    return 1;
-}
-
-
+#define cvar_base "g_turrets_unit_"
+
+/*
+float turret_customizeentityforclient()
+{
+}
+
+float Turret_SendEntity(entity to, float sf)
+{
+
+	WriteByte(MSG_ENTITY, ENT_CLIENT_TURRET);
+	WriteCoord(MSG_ENTITY, self.tur_head.angles_x);
+	WriteCoord(MSG_ENTITY, self.tur_head.angles_y);
+    WriteByte(MSG_ENTITY, self.tur_head.frame);
+
+	//WriteCoord(MSG_ENTITY, self.tur_head.angles_z);
+
+	return TRUE;
+}
+*/
+
+void load_unit_settings(entity ent,string unitname,float is_reload)
+{
+    string sbase;
+
+    // dprint("Reloading turret ",e_turret.netname,"\n");
+
+    if (ent == world)
+        return;
+
+    if (!ent.turret_scale_damage)    ent.turret_scale_damage  = 1;
+    if (!ent.turret_scale_range)     ent.turret_scale_range   = 1;
+    if (!ent.turret_scale_refire)    ent.turret_scale_refire  = 1;
+    if (!ent.turret_scale_ammo)      ent.turret_scale_ammo    = 1;
+    if (!ent.turret_scale_aim)       ent.turret_scale_aim     = 1;
+    if (!ent.turret_scale_health)    ent.turret_scale_health  = 1;
+    if (!ent.turret_scale_respawn)   ent.turret_scale_respawn = 1;
+
+    sbase = strcat(cvar_base,unitname);
+    if (is_reload)
+    {
+        ent.enemy = world;
+        ent.tur_head.avelocity = '0 0 0';
+
+        if (ent.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
+            ent.tur_head.angles = '0 0 0';
+        else
+            ent.tur_head.angles = ent.angles;
+    }
+
+    ent.health      = cvar(strcat(sbase,"_health")) * ent.turret_scale_health;
+    ent.respawntime = cvar(strcat(sbase,"_respawntime")) * ent.turret_scale_respawn;
+
+    ent.shot_dmg          = cvar(strcat(sbase,"_shot_dmg")) * ent.turret_scale_damage;
+    ent.shot_refire       = cvar(strcat(sbase,"_shot_refire")) * ent.turret_scale_refire;
+    ent.shot_radius       = cvar(strcat(sbase,"_shot_radius")) * ent.turret_scale_damage;
+    ent.shot_speed        = cvar(strcat(sbase,"_shot_speed"));
+    ent.shot_spread       = cvar(strcat(sbase,"_shot_spread"));
+    ent.shot_force        = cvar(strcat(sbase,"_shot_force")) * ent.turret_scale_damage;
+    ent.shot_volly        = cvar(strcat(sbase,"_shot_volly"));
+    ent.shot_volly_refire = cvar(strcat(sbase,"_shot_volly_refire")) * ent.turret_scale_refire;
+
+    ent.target_range         = cvar(strcat(sbase,"_target_range")) * ent.turret_scale_range;
+    ent.target_range_min     = cvar(strcat(sbase,"_target_range_min")) * ent.turret_scale_range;
+    //ent.target_range_fire    = cvar(strcat(sbase,"_target_range_fire")) * ent.turret_scale_range;
+    ent.target_range_optimal = cvar(strcat(sbase,"_target_range_optimal")) * ent.turret_scale_range;
+
+    ent.target_select_rangebias  = cvar(strcat(sbase,"_target_select_rangebias"));
+    ent.target_select_samebias   = cvar(strcat(sbase,"_target_select_samebias"));
+    ent.target_select_anglebias  = cvar(strcat(sbase,"_target_select_anglebias"));
+    ent.target_select_playerbias = cvar(strcat(sbase,"_target_select_playerbias"));
+    //ent.target_select_fov = cvar(cvar_gets(sbase,"_target_select_fov"));
+
+    ent.ammo_max      = cvar(strcat(sbase,"_ammo_max")) * ent.turret_scale_ammo;
+    ent.ammo_recharge = cvar(strcat(sbase,"_ammo_recharge")) * ent.turret_scale_ammo;
+
+    ent.aim_firetolerance_dist = cvar(strcat(sbase,"_aim_firetolerance_dist"));
+    ent.aim_speed    = cvar(strcat(sbase,"_aim_speed")) * ent.turret_scale_aim;
+    ent.aim_maxrot   = cvar(strcat(sbase,"_aim_maxrot"));
+    ent.aim_maxpitch = cvar(strcat(sbase,"_aim_maxpitch"));
+
+    ent.track_type        = cvar(strcat(sbase,"_track_type"));
+    ent.track_accel_pitch = cvar(strcat(sbase,"_track_accel_pitch"));
+    ent.track_accel_rot   = cvar(strcat(sbase,"_track_accel_rot"));
+    ent.track_blendrate   = cvar(strcat(sbase,"_track_blendrate"));
+
+    if(is_reload)
+        if(ent.turret_respawnhook)
+            ent.turret_respawnhook();
+
+}
+
+/*
+float turret_stdproc_true()
+{
+    return 1;
+}
+
+float turret_stdproc_false()
+{
+    return 0;
+}
+
+
+void turret_stdproc_nothing()
+{
+    return;
+}
+*/
+
+/**
+** updates enemy distances, predicted impact point/time
+** and updated aim<->predict impact distance.
+**/
+void turret_do_updates(entity t_turret)
+{
+    vector enemy_pos,oldpos;
+    entity oldself;
+
+    oldself = self;
+    self = t_turret;
+
+    enemy_pos = real_origin(self.enemy);
+
+    turret_tag_fire_update();
+
+    self.tur_shotdir_updated = normalize(v_forward);
+
+    self.tur_dist_enemy  = vlen(self.tur_shotorg - enemy_pos);
+    self.tur_dist_aimpos = vlen(self.tur_shotorg - self.tur_aimpos);
+
+    if(self.firecheck_flags & TFL_FIRECHECK_VERIFIED)
+    if(self.enemy)
+    {
+        oldpos = self.enemy.origin;
+        setorigin(self.enemy,self.tur_aimpos);
+    }
+
+    //dprint("NN: ", self.netname," THVN: ",self.tur_head.classname," frame:",ftos(self.tur_head.frame),"\n");
+    //dprint("self.tur_shotorg: ",vtos(self.tur_shotorg),"\n");
+    tracebox(self.tur_shotorg, '-1 -1 -1','1 1 1',self.tur_shotorg + (self.tur_shotdir_updated * self.tur_dist_aimpos),MOVE_NORMAL,self);
+
+    if(self.firecheck_flags & TFL_FIRECHECK_VERIFIED)
+        if(self.enemy)
+            setorigin(self.enemy,oldpos);
+
+    //self.tur_impactpoint           = trace_endpos;
+    self.tur_impactent             = trace_ent;
+    self.tur_dist_impact_to_aimpos = vlen(trace_endpos - self.tur_aimpos) - (vlen(self.enemy.maxs - self.enemy.mins)*0.5);
+    self.tur_impacttime            = vlen(self.tur_shotorg - trace_endpos) / self.shot_speed;
+
+    self = oldself;
+}
+
+/*
+vector turret_fovsearch_pingpong()
+{
+    vector wish_angle;
+    if(self.phase < time)
+    {
+        if( self.tur_head.phase )
+            self.tur_head.phase = 0;
+        else
+            self.tur_head.phase = 1;
+        self.phase = time + 5;
+    }
+
+    if( self.tur_head.phase)
+        wish_angle = self.idle_aim + '0 1 0' * (self.aim_maxrot * (self.target_select_fov / 360));
+    else
+        wish_angle = self.idle_aim - '0 1 0' * (self.aim_maxrot * (self.target_select_fov / 360));
+
+    return wish_angle;
+}
+
+vector turret_fovsearch_steprot()
+{
+    vector wish_angle;
+    //float rot_add;
+
+    wish_angle   = self.tur_head.angles;
+    wish_angle_x = self.idle_aim_x;
+
+    if (self.phase < time)
+    {
+        //rot_add = self.aim_maxrot / self.target_select_fov;
+        wish_angle_y += (self.target_select_fov * 2);
+
+        if(wish_angle_y > 360)
+            wish_angle_y = wish_angle_y - 360;
+
+         self.phase = time + 1.5;
+    }
+
+    return wish_angle;
+}
+
+vector turret_fovsearch_random()
+{
+    vector wish_angle;
+
+    if (self.phase < time)
+    {
+        wish_angle_y = random() * self.aim_maxrot;
+        if(random() < 0.5)
+            wish_angle_y *= -1;
+
+        wish_angle_x = random() * self.aim_maxpitch;
+        if(random() < 0.5)
+            wish_angle_x *= -1;
+
+        self.phase = time + 5;
+
+        self.tur_aimpos = wish_angle;
+    }
+
+    return self.idle_aim + self.tur_aimpos;
+}
+*/
+
+/**
+** Handles head rotation according to
+** the units .track_type and .track_flags
+**/
+//.entity aim_mark;
+void turret_stdproc_track()
+{
+    vector target_angle; // This is where we want to aim
+    vector move_angle;   // This is where we can aim
+    float f_tmp;
+
+    if (self.track_flags == TFL_TRACK_NO)
+        return;
+
+    if(!self.tur_active)
+        target_angle = self.idle_aim - ('1 0 0' * self.aim_maxpitch);
+    else if (self.enemy == world)
+    {
+        if(time > self.lip)
+            if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
+                target_angle = self.idle_aim + self.angles;
+            else
+                target_angle = self.idle_aim;
+        else
+            target_angle = vectoangles(normalize(self.tur_aimpos - self.tur_shotorg));
+    }
+    else
+    {
+        // Find the direction
+        target_angle = normalize(self.tur_aimpos - self.tur_shotorg);
+        target_angle = vectoangles(target_angle); // And make a angle
+    }
+
+    self.tur_head.angles_x = safeangle(self.tur_head.angles_x);
+    self.tur_head.angles_y = safeangle(self.tur_head.angles_y);
+
+    // Find the diffrence between where we currently aim and where we want to aim
+    vector a_off;
+
+
+    if (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
+    {
+        move_angle = target_angle - (self.angles + self.tur_head.angles);
+        move_angle = shortangle_vxy(move_angle,(self.angles + self.tur_head.angles));
+        a_off = '0 0 0';
+
+    }
+    else
+    {
+        move_angle = target_angle - self.tur_head.angles;
+        move_angle = shortangle_vxy(move_angle,self.tur_head.angles);
+        a_off = self.angles;
+    }
+
+    switch(self.track_type)
+    {
+        case TFL_TRACKTYPE_STEPMOTOR:
+            f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
+            if (self.track_flags & TFL_TRACK_PITCH)
+            {
+                self.tur_head.angles_x += bound(-f_tmp,move_angle_x, f_tmp);
+                if(self.tur_head.angles_x + a_off_x > self.aim_maxpitch)
+                    self.tur_head.angles_x = a_off_x + self.aim_maxpitch;
+
+                if(self.tur_head.angles_x + a_off_x < -self.aim_maxpitch)
+                    self.tur_head.angles_x = a_off_x - self.aim_maxpitch;
+            }
+
+            if (self.track_flags & TFL_TRACK_ROT)
+            {
+                self.tur_head.angles_y += bound(-f_tmp, move_angle_y, f_tmp);
+                if((self.tur_head.angles_y - a_off_y) > self.aim_maxrot)
+                    self.tur_head.angles_y = a_off_y + self.aim_maxrot;
+
+                if((self.tur_head.angles_y - a_off_y) < -self.aim_maxrot)
+                    self.tur_head.angles_y = a_off_y - self.aim_maxrot;
+            }
+
+            return;
+
+        case TFL_TRACKTYPE_FLUIDINERTIA:
+            f_tmp = self.aim_speed * self.ticrate; // dgr/sec -> dgr/tic
+            move_angle_x = bound(-self.aim_speed, move_angle_x * self.track_accel_pitch * f_tmp,self.aim_speed);
+            move_angle_y = bound(-self.aim_speed, move_angle_y * self.track_accel_rot * f_tmp,self.aim_speed);
+            move_angle = (self.tur_head.avelocity * self.track_blendrate) + (move_angle * (1 - self.track_blendrate));
+            break;
+
+        case TFL_TRACKTYPE_FLUIDPRECISE:
+
+            move_angle_y = bound(-self.aim_speed, move_angle_y, self.aim_speed);
+            move_angle_x = bound(-self.aim_speed, move_angle_x, self.aim_speed);
+
+            break;
+    }
+
+    //  pitch
+    if (self.track_flags & TFL_TRACK_PITCH)
+    {
+        self.tur_head.avelocity_x = move_angle_x;
+        if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) + a_off_x > self.aim_maxpitch)
+        {
+            self.tur_head.avelocity_x = 0;
+            self.tur_head.angles_x = a_off_x + self.aim_maxpitch;
+        }
+        if((self.tur_head.angles_x + self.tur_head.avelocity_x * self.ticrate) + a_off_x < -self.aim_maxpitch)
+        {
+            self.tur_head.avelocity_x = 0;
+            self.tur_head.angles_x = a_off_x - self.aim_maxpitch;
+        }
+
+    }
+
+    //  rot
+    if (self.track_flags & TFL_TRACK_ROT)
+    {
+        self.tur_head.avelocity_y = move_angle_y;
+
+        if(((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate)- a_off_y) > self.aim_maxrot)
+        {
+            self.tur_head.avelocity_y = 0;
+            self.tur_head.angles_y = a_off_y + self.aim_maxrot;
+        }
+
+        if(((self.tur_head.angles_y + self.tur_head.avelocity_y * self.ticrate) - a_off_y) < -self.aim_maxrot)
+        {
+            self.tur_head.avelocity_y = 0;
+            self.tur_head.angles_y = a_off_y - self.aim_maxrot;
+        }
+
+    }
+
+}
+
+
+/*
+ + = implemented
+ - = not implemented
+
+ + TFL_FIRECHECK_NO
+ + TFL_FIRECHECK_WORLD
+ + TFL_FIRECHECK_DEAD
+ + TFL_FIRECHECK_DISTANCES
+ - TFL_FIRECHECK_LOS
+ + TFL_FIRECHECK_AIMDIST
+ + TFL_FIRECHECK_REALDIST
+ - TFL_FIRECHECK_ANGLEDIST
+ - TFL_FIRECHECK_TEAMCECK
+ + TFL_FIRECHECK_AFF
+ + TFL_FIRECHECK_OWM_AMMO
+ + TFL_FIRECHECK_OTHER_AMMO
+ + TFL_FIRECHECK_REFIRE
+*/
+
+/**
+** Preforms pre-fire checks based on the uints firecheck_flags
+**/
+float turret_stdproc_firecheck()
+{
+    // This one just dont care =)
+    if (self.firecheck_flags & TFL_FIRECHECK_NO) return 1;
+
+    // Ready?
+    if (self.firecheck_flags & TFL_FIRECHECK_REFIRE)
+        if (self.attack_finished_single >= time) return 0;
+
+    // Special case: volly fire turret that has to fire a full volly if a shot was fired.
+    if((self.shoot_flags & TFL_SHOOT_VOLLYALWAYS) && (self.volly_counter != self.shot_volly))
+        return 1;
+
+    // Lack of zombies makes shooting dead things unnecessary :P
+    if (self.firecheck_flags & TFL_FIRECHECK_DEAD)
+        if (self.enemy.deadflag != DEAD_NO) return 0;
+
+    // Plz stop killing the world!
+    if (self.firecheck_flags & TFL_FIRECHECK_WORLD)
+        if (self.enemy == world) return 0;
+
+    // Own ammo?
+    if (self.firecheck_flags & TFL_FIRECHECK_OWM_AMMO)
+        if (self.ammo < self.shot_dmg) return 0;
+
+    // Other's ammo? (support-supply units)
+    if (self.firecheck_flags & TFL_FIRECHECK_OTHER_AMMO)
+        if (self.enemy.ammo >= self.enemy.ammo_max) return 0;
+
+    if (self.firecheck_flags & TFL_FIRECHECK_DISTANCES)
+    {
+        // Not close enougth?
+        //if (self.tur_dist_aimpos > self.target_range_fire) return 0;
+
+        // To close?
+        if (self.tur_dist_aimpos < self.target_range_min) return 0;
+    }
+
+    // Try to avoid FF?
+    if (self.firecheck_flags & TFL_FIRECHECK_AFF)
+        if (self.tur_impactent.team == self.team) return 0;
+
+    // aim<->predicted impact
+    if (self.firecheck_flags & TFL_FIRECHECK_AIMDIST)
+        if (self.tur_dist_impact_to_aimpos  > self.aim_firetolerance_dist)
+            if (self.tur_impactent != self.enemy)
+                return 0;
+
+    // Volly status
+    if (self.shot_volly > 1)
+        if (self.volly_counter == self.shot_volly)
+            if (self.ammo < (self.shot_dmg * self.shot_volly))
+                return 0;
+
+    if(self.firecheck_flags & TFL_FIRECHECK_VERIFIED)
+        if(self.tur_impactent != self.enemy)
+            return 0;
+
+    return 1;
+}
+
+/*
+ + TFL_TARGETSELECT_NO
+ + TFL_TARGETSELECT_LOS
+ + TFL_TARGETSELECT_PLAYERS
+ + TFL_TARGETSELECT_MISSILES
+ - TFL_TARGETSELECT_TRIGGERTARGET
+ + TFL_TARGETSELECT_ANGLELIMITS
+ + TFL_TARGETSELECT_RANGELIMTS
+ + TFL_TARGETSELECT_TEAMCHECK
+ - TFL_TARGETSELECT_NOBUILTIN
+ + TFL_TARGETSELECT_OWNTEAM
+*/
+
+/**
+** Evaluate a entity for target valitity based on validate_flags
+**/
+float turret_validate_target(entity e_turret,entity e_target,float validate_flags)
+{
+    vector v_tmp;
+
+    //if(!validate_flags & TFL_TARGETSELECT_NOBUILTIN)
+    //    return -0.5;
+
+    if(e_target.owner == e_turret)
+        return -0.5;
+
+    if not(checkpvs(e_target.origin, e_turret))
+        return -1;
+
+    if (!e_target)// == world)
+        return -2;
+
+	if(g_onslaught)
+		if (substring(e_target.classname, 0, 10) == "onslaught_") // don't attack onslaught targets, that's the player's job!
+			return - 3;
+
+    if (validate_flags & TFL_TARGETSELECT_NO)
+        return -4;
+
+    // If only this was used more..
+    if (e_target.flags & FL_NOTARGET)
+        return -5;
+
+    // Cant touch this
+    if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
+        return -6;
+
+    // player
+    if (e_target.flags & FL_CLIENT)
+    {
+        if not (validate_flags & TFL_TARGETSELECT_PLAYERS)
+            return -7;
+
+        if (e_target.deadflag != DEAD_NO)
+            return -8;
+    }
+
+	// enemy turrets
+	if (validate_flags & TFL_TARGETSELECT_NOTURRETS)
+        if (e_target.turret_firefunc || e_target.owner.tur_head == e_target)
+            if(e_target.team != e_turret.team) // Dont break support units.
+                return -9;
+
+    // Missile
+    if (e_target.flags & FL_PROJECTILE)
+        if not (validate_flags & TFL_TARGETSELECT_MISSILES)
+            return -10;
+
+    // Team check
+    if (validate_flags & TFL_TARGETSELECT_TEAMCHECK)
+    {
+        if (validate_flags & TFL_TARGETSELECT_OWNTEAM)
+        {
+            if (e_target.team != e_turret.team)
+                return -11;
+
+            if (e_turret.team != e_target.owner.team)
+                return -12;
+        }
+        else
+        {
+            if (e_target.team == e_turret.team)
+                return -13;
+
+            if (e_turret.team == e_target.owner.team)
+                return -14;
+        }
+    }
+
+    // Range limits?
+    tvt_dist = vlen(e_turret.origin - real_origin(e_target));
+    if (validate_flags & TFL_TARGETSELECT_RANGELIMTS)
+    {
+        if (tvt_dist < e_turret.target_range_min)
+            return -15;
+
+        if (tvt_dist > e_turret.target_range)
+            return -16;
+    }
+
+    // Can we even aim this thing?
+    if(e_turret.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
+    {
+        tvt_thadv = angleofs3(e_turret.tur_head.origin,e_turret.angles + e_turret.tur_head.angles ,e_target);
+        //tvt_thadv = angleofs(e_turret.angles,e_target);
+    }
+    else
+    {
+        tvt_thadv = angleofs(e_turret.tur_head,e_target);
+    }
+
+    tvt_tadv  = shortangle_vxy(angleofs(e_turret,e_target),e_turret.angles);
+    tvt_thadf = vlen(tvt_thadv);
+    tvt_tadf  = vlen(tvt_tadv);
+
+    /*
+    if(validate_flags & TFL_TARGETSELECT_FOV)
+    {
+        if(e_turret.target_select_fov < tvt_thadf)
+            return -21;
+    }
+    */
+
+    if (validate_flags & TFL_TARGETSELECT_ANGLELIMITS)
+    {
+        if (fabs(tvt_tadv_x) > e_turret.aim_maxpitch)
+            return -17;
+
+        if (fabs(tvt_tadv_y) > e_turret.aim_maxrot)
+            return -18;
+    }
+
+    // Line of sight?
+    if (validate_flags & TFL_TARGETSELECT_LOS)
+    {
+        v_tmp = real_origin(e_target) + ((e_target.mins + e_target.maxs) * 0.5);
+        traceline(e_turret.tur_shotorg,v_tmp,0,e_turret);
+
+        if (e_turret.aim_firetolerance_dist < vlen(v_tmp - trace_endpos))
+            return -19;
+    }
+
+    if (e_target.classname == "grapplinghook")
+        return -20;
+
+#ifdef TURRET_DEBUG_TARGETSELECT
+    dprint("Target:",e_target.netname," is a valid target for ",e_turret.netname,"\n");
+#endif
+
+    return 1;
+}
+
+entity turret_select_target()
+{
+    entity e;        // target looper entity
+    float  score;    // target looper entity score
+    entity e_enemy;  // currently best scoreing target
+    float  m_score;  // currently best scoreing target's score
+    float f;
+
+    m_score = 0;
+    if(self.enemy)
+    if(turret_validate_target(self,self.enemy,self.target_validate_flags) > 0)
+    {
+        e_enemy = self.enemy;
+        m_score = self.turret_score_target(self,e_enemy) * self.target_select_samebias;
+    }
+
+    e = findradius(self.origin,self.target_range);
+
+    // Nothing to aim at?
+    if (!e) return world;
+
+    while (e)
+    {
+        f = turret_validate_target(self,e,self.target_select_flags);
+        if (f > 0)
+        {
+            score = self.turret_score_target(self,e);
+            if ((score > m_score) && (score > 0))
+            {
+                e_enemy = e;
+                m_score = score;
+            }
+        }
+        e = e.chain;
+    }
+
+    return e_enemy;
+}
+
+void turret_think()
+{
+    entity e;
+
+    self.nextthink = time + self.ticrate;
+
+    // ONS uses somewhat backwards linking.
+    if (teamplay)
+    {
+        if not (g_onslaught)
+            if (self.target)
+            {
+                e = find(world,targetname,self.target);
+                if (e != world)
+                    self.team = e.team;
+            }
+
+        if (self.team != self.tur_head.team)
+            turret_stdproc_respawn();
+    }
+
+
+    if (cvar("g_turrets_reloadcvars") == 1)
+    {
+        e = nextent(world);
+        while (e)
+        {
+            if (e.tur_head != world)
+            {
+
+                load_unit_settings(e,e.cvar_basename,1);
+                if(e.turret_postthink)
+                    e.turret_postthink();
+            }
+
+            e = nextent(e);
+        }
+
+        cvar_set("g_turrets_reloadcvars","0");
+    }
+
+#ifdef TURRET_DEBUG
+    if (self.tur_dbg_tmr1 < time)
+    {
+        if (self.enemy) paint_target (self.enemy,128,self.tur_dbg_rvec,0.9);
+        paint_target(self,256,self.tur_dbg_rvec,0.9);
+        self.tur_dbg_tmr1 = time + 1;
+    }
+#endif
+
+    // Handle ammo
+    if not (self.spawnflags & TSF_NO_AMMO_REGEN)
+    if (self.ammo < self.ammo_max)
+        self.ammo = min(self.ammo + self.ammo_recharge,self.ammo_max);
+
+
+    // Inactive turrets needs to run the think loop,
+    // So they can handle animation and wake up if need be.
+    if not (self.tur_active)
+    {
+        turret_stdproc_track();
+        return;
+    }
+
+    //This is just wrong :|
+    if(self.deadflag != DEAD_NO)
+    {
+        dprint("WARNING: dead turret running the think function!\n");
+        return;
+    }
+
+    // This is typicaly used for zaping every target in range
+    // turret_fusionreactor uses this to recharge friendlys.
+    if (self.shoot_flags & TFL_SHOOT_HITALLVALID)
+    {
+
+        // Do a self.turret_fire for every valid target.
+        e = findradius(self.origin,self.target_range);
+        while (e)
+        {
+            if (turret_validate_target(self,e,self.target_validate_flags))
+            {
+                self.enemy = e;
+
+                turret_do_updates(self);
+
+                if (self.turret_firecheckfunc())
+                    turret_fire();
+            }
+
+            e = e.chain;
+        }
+        self.enemy = world;
+    }
+    else if(self.shoot_flags & TFL_SHOOT_CUSTOM)
+    {
+        // This one is doing something.. oddball. assume its handles what needs to be handled.
+
+        // Predict?
+        if not((self.aim_flags & TFL_AIM_NO))
+            self.tur_aimpos = turret_stdproc_aim_generic();
+
+        // Turn & pitch?
+        if (!self.track_flags & TFL_TRACK_NO)
+            turret_stdproc_track();
+
+        turret_do_updates(self);
+
+        // Fire?
+        if (self.turret_firecheckfunc())
+            turret_fire();
+    }
+    else
+    {
+        // Special case for volly always. if it fired once it must compleate the volly.
+        if(self.shoot_flags & TFL_SHOOT_VOLLYALWAYS)
+            if(self.volly_counter != self.shot_volly)
+            {
+                // Predict or whatnot
+                if not((self.aim_flags & TFL_AIM_NO))
+                    self.tur_aimpos = turret_stdproc_aim_generic();
+
+                // Turn & pitch
+                if (!self.track_flags & TFL_TRACK_NO)
+                    turret_stdproc_track();
+
+                turret_do_updates(self);
+
+                // Fire!
+                if (self.turret_firecheckfunc() != 0)
+                    turret_fire();
+
+                if(self.turret_postthink)
+                    self.turret_postthink();
+
+                return;
+            }
+
+        // Check if we have a vailid enemy, and try to find one if we dont.
+        if( ((self.target_select_time + cvar("g_turrets_targetscan_maxdelay")) < time)
+          || (turret_validate_target(self,self.enemy,self.target_validate_flags) <= 0) )
+        if not (self.target_select_time + cvar("g_turrets_targetscan_mindelay") > time)
+        {
+            self.enemy = turret_select_target();
+            //if(self.enemy)
+                self.target_select_time = time;
+
+        }
+
+
+        // No target, just go to idle, do any custom stuff and bail.
+        if (self.enemy == world)
+        {
+            // Turn & pitch
+            if (!self.track_flags & TFL_TRACK_NO)
+                turret_stdproc_track();
+
+            // do any per-turret stuff
+            if(self.turret_postthink)
+                self.turret_postthink();
+
+            // And bail.
+            return;
+        }
+        else
+            self.lip = time + cvar("g_turrets_aimidle_delay"); // Keep track of the last time we had a target.
+
+        // Predict?
+        if not((self.aim_flags & TFL_AIM_NO))
+            self.tur_aimpos = turret_stdproc_aim_generic();
+
+        // Turn & pitch?
+        if (!self.track_flags & TFL_TRACK_NO)
+            turret_stdproc_track();
+
+        turret_do_updates(self);
+        // Fire?
+        if (self.turret_firecheckfunc())
+            turret_fire();
+    }
+
+    // do any per-turret stuff
+    if(self.turret_postthink)
+        self.turret_postthink();
+}
+
+void turret_fire()
+{
+    if (cvar("g_turrets_nofire") != 0)
+        return;
+
+    if ((!self.tur_active) || (self.deadflag != DEAD_NO))
+        return;
+
+    self.turret_firefunc();
+
+    self.attack_finished_single = time + self.shot_refire;
+    self.ammo                   = self.ammo - self.shot_dmg;
+    self.volly_counter          = self.volly_counter - 1;
+    if (self.volly_counter <= 0)
+    {
+        self.volly_counter = self.shot_volly;
+
+        if (self.shoot_flags & TFL_SHOOT_CLEARTARGET)
+            self.enemy = world;
+
+        if (self.shot_volly > 1)
+            self.attack_finished_single = time + self.shot_volly_refire;
+    }
+
+
+#ifdef TURRET_DEBUG
+    if (self.enemy) paint_target3(self.tur_aimpos, 64, self.tur_dbg_rvec, self.tur_impacttime + 0.25);
+#endif
+}
+
+void turret_stdproc_fire()
+{
+    dprint("^1Bang, ^3your dead^7 ",self.enemy.netname,"! ^1(turret with no real firefunc)\n");
+}
+
+/*
+    When .used a turret switch team to activator.team.
+    If activator is world, the turrets goes inactive.
+*/
+void turret_stdproc_use()
+{
+    dprint("Turret ",self.netname, " used by ",activator.classname,"\n");
+
+    self.team = activator.team;
+
+    if(self.team == 0)
+        self.tur_active = 0;
+    else
+        self.tur_active = 1;
+
+}
+
+void turret_link()
+{
+    //Net_LinkEntity(self, FALSE, 0, Turret_SendEntity);
+    self.think      = turret_think;
+    self.nextthink  = time;
+}
+
+/*
+* Standard turret initialization. use this!
+* (unless you have a very good reason not to)
+* if the return value is 0, the turret should be removed.
+*/
+float turret_stdproc_init (string cvar_base_name, float csqc_shared)
+{
+	entity e,ee;
+
+    if(csqc_shared)
+    {
+        dprint("turrets: csqc_shared requested but not implemented. expect strange things to happen.\n");
+        csqc_shared = 0;
+    }
+
+    // Are turrets allowed atm?
+    if (cvar("g_turrets") == 0)
+        return 0;
+
+    // Better more then once then never.
+    // turret_gibs_precash();
+
+    // Terrainbase spawnflag. This puts a enlongated model
+    // under the turret, so it looks ok on uneaven surfaces.
+    if (self.spawnflags & TSF_TERRAINBASE)
+    {
+        entity tb;
+        //precache_model("models/turrets/terrainbase.md3");
+        tb = spawn();
+        setmodel(tb,"models/turrets/terrainbase.md3");
+        setorigin(tb,self.origin);
+        tb.solid = SOLID_BBOX;
+        //makestatic(tb);
+    }
+
+    self.cvar_basename = cvar_base_name;
+    load_unit_settings(self,self.cvar_basename,0);
+
+    // Handle turret teams.
+    if (cvar("g_assult") != 0)
+    {
+        if (!self.team)
+            self.team = 14; // Assume turrets are on the defending side if not explicitly set otehrwize
+    }
+    else if (!teamplay)
+		self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team iso they dont kill eachother.
+	else if(g_onslaught && self.targetname)
+	{
+		e = find(world,target,self.targetname);
+		if(e != world)
+		{
+			self.team = e.team;
+			ee = e;
+		}
+	}
+	else if(!self.team)
+		self.team = MAX_SHOT_DISTANCE; // Group all turrets into the same team iso they dont kill eachother.
+
+
+
+    /*
+    * Try to guess some reasonaly defaults
+    * for missing params and do sanety checks
+    * thise checks could produce some "interesting" results
+    * if it hits a glitch in my logic :P so try to set as mutch
+    * as possible beforehand.
+    */
+    if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
+        if (!self.ticrate) self.ticrate = 0.2;     // Support units generaly dont need to have a high speed ai-loop
+    else
+        if (!self.ticrate) self.ticrate = 0.1;     // 10 fps for normal turrets
+
+    self.ticrate = bound(sys_ticrate,self.ticrate,60);  // keep it sane
+
+// General stuff
+    if (self.netname == "")
+        self.netname = self.classname;
+
+    if (!self.respawntime)
+        self.respawntime = 60;
+    self.respawntime = max(-1,self.respawntime);
+
+    if (!self.health)
+        self.health = 1000;
+    self.tur_health = max(1,self.health);
+
+    if (!self.turrcaps_flags)
+        self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
+
+    if (!self.damage_flags)
+        self.damage_flags = TFL_DMG_YES | TFL_DMG_RETALIATE | TFL_DMG_AIMSHAKE;
+
+// Shot stuff.
+    if (!self.shot_refire)
+        self.shot_refire = 1;
+    self.shot_refire = bound(0.01,self.shot_refire,9999);
+
+    if (!self.shot_dmg)
+        self.shot_dmg  = self.shot_refire * 50;
+    self.shot_dmg = max(1,self.shot_dmg);
+
+    if (!self.shot_radius)
+        self.shot_radius = self.shot_dmg * 0.5;
+    self.shot_radius = max(1,self.shot_radius);
+
+    if (!self.shot_speed)
+        self.shot_speed = 2500;
+    self.shot_speed = max(1,self.shot_speed);
+
+    if (!self.shot_spread)
+        self.shot_spread = 0.0125;
+    self.shot_spread = bound(0.0001,self.shot_spread,500);
+
+    if (!self.shot_force)
+        self.shot_force = self.shot_dmg * 0.5 + self.shot_radius * 0.5;
+    self.shot_force = bound(0.001,self.shot_force,MAX_SHOT_DISTANCE * 0.5);
+
+    if (!self.shot_volly)
+        self.shot_volly = 1;
+    self.shot_volly = bound(1,self.shot_volly,floor(self.ammo_max / self.shot_dmg));
+
+    if (!self.shot_volly_refire)
+        self.shot_volly_refire = self.shot_refire * self.shot_volly;
+    self.shot_volly_refire = bound(self.shot_refire,self.shot_volly_refire,60);
+
+    if (!self.firecheck_flags)
+        self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES |
+                               TFL_FIRECHECK_LOS | TFL_FIRECHECK_AIMDIST | TFL_FIRECHECK_TEAMCECK |
+                               TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_WORLD;
+
+// Range stuff.
+    if (!self.target_range)
+        self.target_range = self.shot_speed * 0.5;
+    self.target_range = bound(0,self.target_range,MAX_SHOT_DISTANCE);
+
+    if (!self.target_range_min)
+        self.target_range_min = self.shot_radius * 2;
+    self.target_range_min = bound(0,self.target_range_min,MAX_SHOT_DISTANCE);
+
+    //if (!self.target_range_fire)
+    //    self.target_range_fire = self.target_range * 0.8;
+    //self.target_range_fire = bound(0,self.target_range_fire,MAX_SHOT_DISTANCE);
+
+    if (!self.target_range_optimal)
+        self.target_range_optimal = self.target_range * 0.5;
+    self.target_range_optimal = bound(0,self.target_range_optimal,MAX_SHOT_DISTANCE);
+
+
+// Aim stuff.
+    if (!self.aim_maxrot)
+        self.aim_maxrot = 90;
+    self.aim_maxrot = bound(0,self.aim_maxrot,360);
+
+    if (!self.aim_maxpitch)
+        self.aim_maxpitch = 20;
+    self.aim_maxpitch = bound(0,self.aim_maxpitch,90);
+
+    if (!self.aim_speed)
+        self.aim_speed = 36;
+    self.aim_speed  = bound(0.1,self.aim_speed, 1000);
+
+    if (!self.aim_firetolerance_dist)
+        self.aim_firetolerance_dist  = 5 + (self.shot_radius * 2);
+    self.aim_firetolerance_dist = bound(0.1,self.aim_firetolerance_dist,MAX_SHOT_DISTANCE);
+
+    if (!self.aim_flags)
+    {
+        self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+        if(self.turrcaps_flags & TFL_TURRCAPS_RADIUSDMG)
+            self.aim_flags |= TFL_AIM_GROUND2;
+    }
+
+    // Sill the most tested (and aim-effective)
+    if (!self.track_type) self.track_type = TFL_TRACKTYPE_STEPMOTOR;
+
+    if (self.track_type != TFL_TRACKTYPE_STEPMOTOR)
+    {
+        // Fluid / Ineria mode. Looks mutch nicer, bit experimental &
+        // Can inmapt aim preformance alot.
+        // needs a bit diffrent aimspeed
+
+        if (!self.aim_speed)
+            self.aim_speed = 180;
+        self.aim_speed = bound(0.1,self.aim_speed, 1000);
+
+        if (!self.track_accel_pitch)
+            self.track_accel_pitch = 0.5;
+
+        if (!self.track_accel_rot)
+            self.track_accel_rot   = 0.5;
+
+        if (!self.track_blendrate)
+            self.track_blendrate   = 0.35;
+    }
+
+    if (!self.track_flags)
+        self.track_flags = TFL_TRACK_PITCH | TFL_TRACK_ROT;
+
+
+// Target selection stuff.
+    if (!self.target_select_rangebias)
+        self.target_select_rangebias = 1;
+    self.target_select_rangebias = bound(-10,self.target_select_rangebias,10);
+
+    if (!self.target_select_samebias)
+        self.target_select_samebias = 1;
+    self.target_select_samebias = bound(-10,self.target_select_samebias,10);
+
+    if (!self.target_select_anglebias)
+        self.target_select_anglebias = 1;
+    self.target_select_anglebias = bound(-10,self.target_select_anglebias,10);
+
+    if (!self.target_select_missilebias)
+        self.target_select_missilebias = -10;
+
+    self.target_select_missilebias = bound(-10,self.target_select_missilebias,10);
+    self.target_select_playerbias = bound(-10,self.target_select_playerbias,10);
+
+    if (!self.target_select_flags)
+    {
+            self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_TEAMCHECK
+                                     | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_ANGLELIMITS;
+
+        if (self.turrcaps_flags & TFL_TURRCAPS_MISSILEKILL)
+            self.target_select_flags |= TFL_TARGETSELECT_MISSILES;
+
+        if (self.turrcaps_flags & TFL_TURRCAPS_PLAYERKILL)
+            self.target_select_flags |= TFL_TARGETSELECT_PLAYERS;
+        //else
+        //    self.target_select_flags = TFL_TARGETSELECT_NO;
+    }
+
+    self.target_validate_flags = self.target_select_flags;
+
+
+// Ammo stuff
+    if (!self.ammo_max)
+        self.ammo_max = self.shot_dmg * 10;
+    self.ammo_max = max(self.shot_dmg,self.ammo_max);
+
+    if (!self.ammo)
+        self.ammo = self.shot_dmg * 5;
+    self.ammo = bound(0,self.ammo,self.ammo_max);
+
+    if (!self.ammo_recharge)
+        self.ammo_recharge = self.shot_dmg * 0.5;
+    self.ammo_recharge = max(0,self.ammo_recharge);
+
+    // Convert the recharge from X per sec to X per ticrate
+    self.ammo_recharge = self.ammo_recharge * self.ticrate;
+
+    if (!self.ammo_flags)
+        self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
+
+// Damage stuff
+    if(self.spawnflags & TSL_NO_RESPAWN)
+        if not (self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
+            self.damage_flags |= TFL_DMG_DEATH_NORESPAWN;
+
+// Offsets & origins
+    if (!self.tur_shotorg)   self.tur_shotorg = '50 0 50';
+
+// End of default & sanety checks, start building the turret.
+
+// Spawn extra bits
+    self.tur_head         = spawn();
+    self.tur_head.netname = self.tur_head.classname = "turret_head";
+    self.tur_head.team    = self.team;
+    self.tur_head.owner   = self;
+
+    // Defend mode?
+    if(!self.tur_defend)
+    if (self.target != "")
+    {
+        self.tur_defend = find(world, targetname, self.target);
+        if (self.tur_defend == world)
+        {
+            self.target = "";
+            dprint("Turret has invalid defendpoint!\n");
+        }
+    }
+
+// Put pices in place
+    if not (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
+        setorigin(self.tur_head,self.origin);
+
+    // In target defend mode, aim on the spot to defend when idle.
+    if(self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
+    {
+        if (self.tur_defend)
+            self.idle_aim  = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend);
+        else
+            self.idle_aim  = '0 0 0';
+    }
+    else
+    {
+        if (self.tur_defend)
+            self.idle_aim  = self.tur_head.angles + angleofs(self.tur_head,self.tur_defend);
+        else
+            self.idle_aim  = self.angles;
+    }
+
+    if not (self.turrcaps_flags & TFL_TURRCAPS_HEADATTACHED)
+        self.tur_head.angles    = self.idle_aim;
+
+    if (!self.health)
+        self.health = 150;
+
+    self.tur_health      = self.health;
+    self.tur_head.health = self.health;
+
+    self.solid          = SOLID_BBOX;
+    self.tur_head.solid = SOLID_BBOX;
+
+    self.takedamage          = DAMAGE_AIM;
+    self.tur_head.takedamage = DAMAGE_AIM;
+
+    self.movetype            = MOVETYPE_NOCLIP;
+    self.tur_head.movetype   = MOVETYPE_NOCLIP;
+
+    // Team color
+    if (self.team == COLOR_TEAM1) self.colormod = '1.4 0.8 0.8';
+    if (self.team == COLOR_TEAM2) self.colormod = '0.8 0.8 1.4';
+
+    // Attach stdprocs. override when and what needed
+    if (self.turrcaps_flags & TFL_TURRCAPS_SUPPORT)
+    {
+        self.turret_score_target    = turret_stdproc_targetscore_support;
+        self.turret_firecheckfunc   = turret_stdproc_firecheck;
+        self.turret_firefunc        = turret_stdproc_fire;
+        //self.turret_postthink       = turret_stdproc_nothing;
+        self.event_damage           = turret_stdproc_damage;
+        self.tur_head.event_damage  = turret_stdproc_damage;
+    }
+    else
+    {
+        self.turret_score_target    = turret_stdproc_targetscore_generic;
+        self.turret_firecheckfunc   = turret_stdproc_firecheck;
+        self.turret_firefunc        = turret_stdproc_fire;
+        //self.turret_postthink       = turret_stdproc_nothing;
+        self.event_damage           = turret_stdproc_damage;
+        self.tur_head.event_damage  = turret_stdproc_damage;
+        //self.turret_addtarget       = turret_stdproc_false;
+    }
+
+    self.use = turret_stdproc_use;
+    self.bot_attack = TRUE;
+
+    // Initiate the main AI loop
+    if(csqc_shared)
+        self.think     = turret_link;
+    else
+        self.think     = turret_think;
+
+    self.nextthink = time + self.ticrate;
+
+    self.tur_head.team = self.team;
+    self.view_ofs = '0 0 0';
+
+#ifdef TURRET_DEBUG
+    self.tur_dbg_start = self.nextthink;
+    while (vlen(self.tur_dbg_rvec) < 2)
+        self.tur_dbg_rvec  = randomvec() * 4;
+
+    self.tur_dbg_rvec_x = fabs(self.tur_dbg_rvec_x);
+    self.tur_dbg_rvec_y = fabs(self.tur_dbg_rvec_y);
+    self.tur_dbg_rvec_z = fabs(self.tur_dbg_rvec_z);
+#endif
+
+    // Its all good.
+    self.classname = "turret_main";
+
+    self.tur_active = 1;
+
+    // In ONS mode, and linked to a ONS ent. need to call the use to set team.
+    if (g_onslaught && ee)
+    {
+        activator = ee;
+        self.use();
+    }
+
+    return 1;
+}
+
+


Property changes on: trunk/data/qcsrc/server/tturrets/system/system_main.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/system/system_misc.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_misc.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/system/system_misc.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,406 +1,406 @@
-//--// Some support routines //--//
-
-#define anglemodss(a) (a - floor(a / 360) * 360)
-float(float v) anglemods =
-{
-	v = v - 360 * floor(v / 360);
-	return v;
-};
-float safeangle(float a)
-{
-    if((a > -361) && (a < 361))
-        return a;
-
-    a -= (360 * floor(a / 360));
-
-    return a;
-}
-
-float shortangle_f(float ang1,float ang2)
-{
-    if(ang1 > ang2)
-    {
-        if(ang1 > 180)
-            return ang1 - 360;
-    }
-    else
-    {
-        if(ang1 < -180)
-            return ang1 + 360;
-    }
-
-    return ang1;
-}
-
-vector shortangle_v(vector ang1,vector ang2)
-{
-    vector vtmp;
-
-    vtmp_x = shortangle_f(ang1_x,ang2_x);
-    vtmp_y = shortangle_f(ang1_y,ang2_y);
-    vtmp_z = shortangle_f(ang1_z,ang2_z);
-
-    return vtmp;
-}
-
-vector shortangle_vxy(vector ang1,vector ang2)
-{
-    vector vtmp;
-
-    vtmp_x = shortangle_f(ang1_x,ang2_x);
-    vtmp_y = shortangle_f(ang1_y,ang2_y);
-
-    return vtmp;
-}
-
-// Get real origin
-vector real_origin(entity ent)
-{
-    entity e;
-    vector v;
-
-    e = ent.tag_entity;
-    while(e)
-    {
-        // v = v + e.origin;
-        v = v + ((e.absmin + e.absmax) * 0.5);
-        e = e.tag_entity;
-    }
-    //v = v + ent.origin;
-    v = v + ((ent.absmin + ent.absmax) * 0.5);
-    return v;
-}
-
-// Plug this into wherever precache is done.
-void g_turrets_common_precash()
-{
-    precache_model ("models/turrets/c512.md3");
-    precache_model ("models/marker.md3");
-}
-
-void SUB_Remove();
-void marker_think()
-{
-    if(self.cnt)
-    if(self.cnt < time)
-    {
-        self.think = SUB_Remove;
-        self.nextthink = time;
-        return;
-    }
-
-    self.frame += 1;
-    if(self.frame > 29)
-        self.frame = 0;
-
-    self.nextthink = time;
-}
-
-void mark_error(vector where,float lifetime)
-{
-    entity err;
-
-    err = spawn();
-    err.classname = "error_marker";
-    setmodel(err,"models/marker.md3");
-    setorigin(err,where);
-    err.movetype = MOVETYPE_NONE;
-    err.think = marker_think;
-    err.nextthink = time;
-    err.skin = 0;
-    if(lifetime)
-        err.cnt = lifetime + time;
-}
-
-void mark_info(vector where,float lifetime)
-{
-    entity err;
-
-    err = spawn();
-    err.classname = "info_marker";
-    setmodel(err,"models/marker.md3");
-    setorigin(err,where);
-    err.movetype = MOVETYPE_NONE;
-    err.think = marker_think;
-    err.nextthink = time;
-    err.skin = 1;
-    if(lifetime)
-        err.cnt = lifetime + time;
-}
-
-entity mark_misc(vector where,float lifetime)
-{
-    entity err;
-
-    err = spawn();
-    err.classname = "mark_misc";
-    setmodel(err,"models/marker.md3");
-    setorigin(err,where);
-    err.movetype = MOVETYPE_NONE;
-    err.think = marker_think;
-    err.nextthink = time;
-    err.skin = 3;
-    if(lifetime)
-        err.cnt = lifetime + time;
-    return err;
-}
-
-/*
-* Paint a v_color colord circle on target onwho
-* that fades away over f_time
-*/
-void paint_target(entity onwho, float f_size, vector v_color, float f_time)
-{
-    entity e;
-
-    e = spawn();
-    setmodel(e, "models/turrets/c512.md3"); // precision set above
-    e.scale = (f_size/512);
-    //setsize(e, '0 0 0', '0 0 0');
-    //setattachment(e,onwho,"");
-    setorigin(e,onwho.origin + '0 0 1');
-    e.alpha = 0.15;
-    e.movetype = MOVETYPE_FLY;
-
-    e.velocity = (v_color * 32); // + '0 0 1' * 64;
-
-    e.colormod = v_color;
-    SUB_SetFade(e,time,f_time);
-}
-
-void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
-{
-    entity e;
-
-    e = spawn();
-    setmodel(e, "models/turrets/c512.md3"); // precision set above
-    e.scale = (f_size/512);
-    setsize(e, '0 0 0', '0 0 0');
-
-    setorigin(e,onwho.origin + '0 0 1');
-    e.alpha = 0.15;
-    e.movetype = MOVETYPE_FLY;
-
-    e.velocity = (v_color * 32); // + '0 0 1' * 64;
-    e.avelocity_x = -128;
-
-    e.colormod = v_color;
-    SUB_SetFade(e,time,f_time);
-}
-
-void paint_target3(vector where, float f_size, vector v_color, float f_time)
-{
-    entity e;
-    e = spawn();
-    setmodel(e, "models/turrets/c512.md3"); // precision set above
-    e.scale = (f_size/512);
-    setsize(e, '0 0 0', '0 0 0');
-    setorigin(e,where+ '0 0 1');
-    e.movetype = MOVETYPE_NONE;
-    e.velocity = '0 0 0';
-    e.colormod = v_color;
-    SUB_SetFade(e,time,f_time);
-}
-
-/*
-* Return the angle between two enteties
-*/
-vector angleofs(entity from, entity to)
-{
-    vector v_res;
-
-    // makevectors(from.angles);
-    v_res = normalize(to.origin - from.origin);
-    v_res = vectoangles(v_res);
-    v_res = v_res - from.angles;
-
-    if (v_res_x < 0) v_res_x += 360;
-    if (v_res_x > 180) v_res_x -= 360;
-
-    if (v_res_y < 0) v_res_y += 360;
-    if (v_res_y > 180) v_res_y -= 360;
-
-    return v_res;
-}
-
-vector angleofs2(entity from, vector to)
-{
-    vector v_res;
-
-    // makevectors(from.angles);
-    v_res = normalize(to - from.origin);
-    v_res = vectoangles(v_res);
-    v_res = v_res - from.angles;
-
-    if (v_res_x < 0) v_res_x += 360;
-    if (v_res_x > 180) v_res_x -= 360;
-
-    if (v_res_y < 0) v_res_y += 360;
-    if (v_res_y > 180) v_res_y -= 360;
-
-    return v_res;
-}
-
-vector angleofs3(vector from,vector from_a, entity to)
-{
-    vector v_res;
-
-    // makevectors(from.angles);
-    v_res = normalize(to.origin - from);
-    v_res = vectoangles(v_res);
-    v_res = v_res - from_a;
-
-    if (v_res_x < 0) v_res_x += 360;
-    if (v_res_x > 180) v_res_x -= 360;
-
-    if (v_res_y < 0) v_res_y += 360;
-    if (v_res_y > 180) v_res_y -= 360;
-
-    return v_res;
-}
-
-float turret_tag_setup()
-{
-    if(!self.tur_head)
-    {
-        dprint("Call to turret_tag_setup with self.tur_head missing!\n");
-        self.tur_shotorg = '0 0 0';
-        return 0;
-    }
-
-    setorigin(self.tur_head,gettaginfo(self,gettagindex(self,"tag_head")));
-    self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
-
-    v_forward = normalize(v_forward);
-
-    return 1;
-}
-
-float turret_tag_fire_update()
-{
-    if(!self.tur_head)
-    {
-        dprint("Call to turret_tag_fire_update with self.tur_head missing!\n");
-        self.tur_shotorg = '0 0 0';
-        return 0;
-    }
-
-    self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
-    v_forward = normalize(v_forward);
-
-    //dprint("update: tur_shotorg: ",vtos(self.tur_shotorg)," origin:", vtos(self.tur_head.origin), " angels: ", vtos(self.tur_head.angles),"\n");
-
-    return 1;
-}
-
-void FireImoBeam (vector start,vector end,vector smin,vector smax,
-                  float bforce,float f_dmg,float f_velfactor, float deathtype)
-
-{
-    local vector hitloc, force, endpoint, dir;
-    local entity ent;
-
-    dir = normalize(end - start);
-    force = dir * bforce;
-
-    // go a little bit into the wall because we need to hit this wall later
-    end = end + dir;
-
-    // trace multiple times until we hit a wall, each obstacle will be made unsolid.
-    // note down which entities were hit so we can damage them later
-    while (1)
-    {
-        tracebox(start, smin, smax, end, FALSE, self);
-
-        // if it is world we can't hurt it so stop now
-        if (trace_ent == world || trace_fraction == 1)
-            break;
-
-        if (trace_ent.solid == SOLID_BSP)
-            break;
-
-        // make the entity non-solid so we can hit the next one
-        trace_ent.railgunhit = TRUE;
-        trace_ent.railgunhitloc = end;
-        trace_ent.railgunhitsolidbackup = trace_ent.solid;
-
-        // stop if this is a wall
-
-        // make the entity non-solid
-        trace_ent.solid = SOLID_NOT;
-    }
-
-    endpoint = trace_endpos;
-
-    // find all the entities the railgun hit and restore their solid state
-    ent = findfloat(world, railgunhit, TRUE);
-    while (ent)
-    {
-        // restore their solid type
-        ent.solid = ent.railgunhitsolidbackup;
-        ent = findfloat(ent, railgunhit, TRUE);
-    }
-
-    // find all the entities the railgun hit and hurt them
-    ent = findfloat(world, railgunhit, TRUE);
-    while (ent)
-    {
-        // get the details we need to call the damage function
-        hitloc = ent.railgunhitloc;
-        ent.railgunhitloc = '0 0 0';
-        ent.railgunhitsolidbackup = SOLID_NOT;
-        ent.railgunhit = FALSE;
-
-        // apply the damage
-        if (ent.takedamage)
-        {
-            Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
-            ent.velocity = ent.velocity * f_velfactor;
-            //ent.alpha = 0.25 + random() * 0.75;
-        }
-
-        // advance to the next entity
-        ent = findfloat(ent, railgunhit, TRUE);
-    }
-    trace_endpos = endpoint;
-}
-
-void turrets_precash()
-{
-    precache_model ("models/turrets/base-gib1.md3");
-    precache_model ("models/turrets/base-gib2.md3");
-    precache_model ("models/turrets/base-gib3.md3");
-    precache_model ("models/turrets/base-gib4.md3");
-
-    precache_model ("models/turrets/head-gib1.md3");
-    precache_model ("models/turrets/head-gib2.md3");
-    precache_model ("models/turrets/head-gib3.md3");
-    precache_model ("models/turrets/head-gib4.md3");
-    precache_model ("models/turrets/terrainbase.md3");
-
-    //precache_model ("models/turrets/base.md3");
-    //precache_model ("models/turrets/flac.md3");
-    //precache_model ("models/turrets/pd_proj.md3");
-    //precache_model ("models/turrets/reactor.md3");
-    //precache_model ("models/turrets/mlrs_rocket.md3");
-    //precache_model ("models/turrets/hellion.md3");
-    //precache_model ("models/turrets/hunter2.md3");
-    //precache_model ("models/turrets/hk.md3");
-    //precache_model ("models/turrets/machinegun.md3");
-    //precache_model ("models/turrets/rocket.md3");
-    //precache_model ("models/turrets/mlrs.md3");
-    //precache_model ("models/turrets/phaser.md3");
-    //precache_model ("models/turrets/phaser_beam.md3");
-    //precache_model ("models/turrets/plasmad.md3");
-    //precache_model ("models/turrets/plasma.md3");
-    //precache_model ("models/turrets/tesla_head.md3");
-    //precache_model ("models/turrets/tesla_base.md3");
-
-#if 0
-    precache_model ("models/turrets/c512.md3");
-    precache_model ("models/pathlib/goodsquare.md3");
-    precache_model ("models/pathlib/badsquare.md3");
-    precache_model ("models/pathlib/square.md3");
-    precache_model ("models/pathlib/edge.md3");
-#endif
-}
+//--// Some support routines //--//
+
+#define anglemodss(a) (a - floor(a / 360) * 360)
+float(float v) anglemods =
+{
+	v = v - 360 * floor(v / 360);
+	return v;
+};
+float safeangle(float a)
+{
+    if((a > -361) && (a < 361))
+        return a;
+
+    a -= (360 * floor(a / 360));
+
+    return a;
+}
+
+float shortangle_f(float ang1,float ang2)
+{
+    if(ang1 > ang2)
+    {
+        if(ang1 > 180)
+            return ang1 - 360;
+    }
+    else
+    {
+        if(ang1 < -180)
+            return ang1 + 360;
+    }
+
+    return ang1;
+}
+
+vector shortangle_v(vector ang1,vector ang2)
+{
+    vector vtmp;
+
+    vtmp_x = shortangle_f(ang1_x,ang2_x);
+    vtmp_y = shortangle_f(ang1_y,ang2_y);
+    vtmp_z = shortangle_f(ang1_z,ang2_z);
+
+    return vtmp;
+}
+
+vector shortangle_vxy(vector ang1,vector ang2)
+{
+    vector vtmp;
+
+    vtmp_x = shortangle_f(ang1_x,ang2_x);
+    vtmp_y = shortangle_f(ang1_y,ang2_y);
+
+    return vtmp;
+}
+
+// Get real origin
+vector real_origin(entity ent)
+{
+    entity e;
+    vector v;
+
+    e = ent.tag_entity;
+    while(e)
+    {
+        // v = v + e.origin;
+        v = v + ((e.absmin + e.absmax) * 0.5);
+        e = e.tag_entity;
+    }
+    //v = v + ent.origin;
+    v = v + ((ent.absmin + ent.absmax) * 0.5);
+    return v;
+}
+
+// Plug this into wherever precache is done.
+void g_turrets_common_precash()
+{
+    precache_model ("models/turrets/c512.md3");
+    precache_model ("models/marker.md3");
+}
+
+void SUB_Remove();
+void marker_think()
+{
+    if(self.cnt)
+    if(self.cnt < time)
+    {
+        self.think = SUB_Remove;
+        self.nextthink = time;
+        return;
+    }
+
+    self.frame += 1;
+    if(self.frame > 29)
+        self.frame = 0;
+
+    self.nextthink = time;
+}
+
+void mark_error(vector where,float lifetime)
+{
+    entity err;
+
+    err = spawn();
+    err.classname = "error_marker";
+    setmodel(err,"models/marker.md3");
+    setorigin(err,where);
+    err.movetype = MOVETYPE_NONE;
+    err.think = marker_think;
+    err.nextthink = time;
+    err.skin = 0;
+    if(lifetime)
+        err.cnt = lifetime + time;
+}
+
+void mark_info(vector where,float lifetime)
+{
+    entity err;
+
+    err = spawn();
+    err.classname = "info_marker";
+    setmodel(err,"models/marker.md3");
+    setorigin(err,where);
+    err.movetype = MOVETYPE_NONE;
+    err.think = marker_think;
+    err.nextthink = time;
+    err.skin = 1;
+    if(lifetime)
+        err.cnt = lifetime + time;
+}
+
+entity mark_misc(vector where,float lifetime)
+{
+    entity err;
+
+    err = spawn();
+    err.classname = "mark_misc";
+    setmodel(err,"models/marker.md3");
+    setorigin(err,where);
+    err.movetype = MOVETYPE_NONE;
+    err.think = marker_think;
+    err.nextthink = time;
+    err.skin = 3;
+    if(lifetime)
+        err.cnt = lifetime + time;
+    return err;
+}
+
+/*
+* Paint a v_color colord circle on target onwho
+* that fades away over f_time
+*/
+void paint_target(entity onwho, float f_size, vector v_color, float f_time)
+{
+    entity e;
+
+    e = spawn();
+    setmodel(e, "models/turrets/c512.md3"); // precision set above
+    e.scale = (f_size/512);
+    //setsize(e, '0 0 0', '0 0 0');
+    //setattachment(e,onwho,"");
+    setorigin(e,onwho.origin + '0 0 1');
+    e.alpha = 0.15;
+    e.movetype = MOVETYPE_FLY;
+
+    e.velocity = (v_color * 32); // + '0 0 1' * 64;
+
+    e.colormod = v_color;
+    SUB_SetFade(e,time,f_time);
+}
+
+void paint_target2(entity onwho, float f_size, vector v_color, float f_time)
+{
+    entity e;
+
+    e = spawn();
+    setmodel(e, "models/turrets/c512.md3"); // precision set above
+    e.scale = (f_size/512);
+    setsize(e, '0 0 0', '0 0 0');
+
+    setorigin(e,onwho.origin + '0 0 1');
+    e.alpha = 0.15;
+    e.movetype = MOVETYPE_FLY;
+
+    e.velocity = (v_color * 32); // + '0 0 1' * 64;
+    e.avelocity_x = -128;
+
+    e.colormod = v_color;
+    SUB_SetFade(e,time,f_time);
+}
+
+void paint_target3(vector where, float f_size, vector v_color, float f_time)
+{
+    entity e;
+    e = spawn();
+    setmodel(e, "models/turrets/c512.md3"); // precision set above
+    e.scale = (f_size/512);
+    setsize(e, '0 0 0', '0 0 0');
+    setorigin(e,where+ '0 0 1');
+    e.movetype = MOVETYPE_NONE;
+    e.velocity = '0 0 0';
+    e.colormod = v_color;
+    SUB_SetFade(e,time,f_time);
+}
+
+/*
+* Return the angle between two enteties
+*/
+vector angleofs(entity from, entity to)
+{
+    vector v_res;
+
+    // makevectors(from.angles);
+    v_res = normalize(to.origin - from.origin);
+    v_res = vectoangles(v_res);
+    v_res = v_res - from.angles;
+
+    if (v_res_x < 0) v_res_x += 360;
+    if (v_res_x > 180) v_res_x -= 360;
+
+    if (v_res_y < 0) v_res_y += 360;
+    if (v_res_y > 180) v_res_y -= 360;
+
+    return v_res;
+}
+
+vector angleofs2(entity from, vector to)
+{
+    vector v_res;
+
+    // makevectors(from.angles);
+    v_res = normalize(to - from.origin);
+    v_res = vectoangles(v_res);
+    v_res = v_res - from.angles;
+
+    if (v_res_x < 0) v_res_x += 360;
+    if (v_res_x > 180) v_res_x -= 360;
+
+    if (v_res_y < 0) v_res_y += 360;
+    if (v_res_y > 180) v_res_y -= 360;
+
+    return v_res;
+}
+
+vector angleofs3(vector from,vector from_a, entity to)
+{
+    vector v_res;
+
+    // makevectors(from.angles);
+    v_res = normalize(to.origin - from);
+    v_res = vectoangles(v_res);
+    v_res = v_res - from_a;
+
+    if (v_res_x < 0) v_res_x += 360;
+    if (v_res_x > 180) v_res_x -= 360;
+
+    if (v_res_y < 0) v_res_y += 360;
+    if (v_res_y > 180) v_res_y -= 360;
+
+    return v_res;
+}
+
+float turret_tag_setup()
+{
+    if(!self.tur_head)
+    {
+        dprint("Call to turret_tag_setup with self.tur_head missing!\n");
+        self.tur_shotorg = '0 0 0';
+        return 0;
+    }
+
+    setorigin(self.tur_head,gettaginfo(self,gettagindex(self,"tag_head")));
+    self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
+
+    v_forward = normalize(v_forward);
+
+    return 1;
+}
+
+float turret_tag_fire_update()
+{
+    if(!self.tur_head)
+    {
+        dprint("Call to turret_tag_fire_update with self.tur_head missing!\n");
+        self.tur_shotorg = '0 0 0';
+        return 0;
+    }
+
+    self.tur_shotorg = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire"));
+    v_forward = normalize(v_forward);
+
+    //dprint("update: tur_shotorg: ",vtos(self.tur_shotorg)," origin:", vtos(self.tur_head.origin), " angels: ", vtos(self.tur_head.angles),"\n");
+
+    return 1;
+}
+
+void FireImoBeam (vector start,vector end,vector smin,vector smax,
+                  float bforce,float f_dmg,float f_velfactor, float deathtype)
+
+{
+    local vector hitloc, force, endpoint, dir;
+    local entity ent;
+
+    dir = normalize(end - start);
+    force = dir * bforce;
+
+    // go a little bit into the wall because we need to hit this wall later
+    end = end + dir;
+
+    // trace multiple times until we hit a wall, each obstacle will be made unsolid.
+    // note down which entities were hit so we can damage them later
+    while (1)
+    {
+        tracebox(start, smin, smax, end, FALSE, self);
+
+        // if it is world we can't hurt it so stop now
+        if (trace_ent == world || trace_fraction == 1)
+            break;
+
+        if (trace_ent.solid == SOLID_BSP)
+            break;
+
+        // make the entity non-solid so we can hit the next one
+        trace_ent.railgunhit = TRUE;
+        trace_ent.railgunhitloc = end;
+        trace_ent.railgunhitsolidbackup = trace_ent.solid;
+
+        // stop if this is a wall
+
+        // make the entity non-solid
+        trace_ent.solid = SOLID_NOT;
+    }
+
+    endpoint = trace_endpos;
+
+    // find all the entities the railgun hit and restore their solid state
+    ent = findfloat(world, railgunhit, TRUE);
+    while (ent)
+    {
+        // restore their solid type
+        ent.solid = ent.railgunhitsolidbackup;
+        ent = findfloat(ent, railgunhit, TRUE);
+    }
+
+    // find all the entities the railgun hit and hurt them
+    ent = findfloat(world, railgunhit, TRUE);
+    while (ent)
+    {
+        // get the details we need to call the damage function
+        hitloc = ent.railgunhitloc;
+        ent.railgunhitloc = '0 0 0';
+        ent.railgunhitsolidbackup = SOLID_NOT;
+        ent.railgunhit = FALSE;
+
+        // apply the damage
+        if (ent.takedamage)
+        {
+            Damage (ent, self, self, f_dmg, deathtype, hitloc, force);
+            ent.velocity = ent.velocity * f_velfactor;
+            //ent.alpha = 0.25 + random() * 0.75;
+        }
+
+        // advance to the next entity
+        ent = findfloat(ent, railgunhit, TRUE);
+    }
+    trace_endpos = endpoint;
+}
+
+void turrets_precash()
+{
+    precache_model ("models/turrets/base-gib1.md3");
+    precache_model ("models/turrets/base-gib2.md3");
+    precache_model ("models/turrets/base-gib3.md3");
+    precache_model ("models/turrets/base-gib4.md3");
+
+    precache_model ("models/turrets/head-gib1.md3");
+    precache_model ("models/turrets/head-gib2.md3");
+    precache_model ("models/turrets/head-gib3.md3");
+    precache_model ("models/turrets/head-gib4.md3");
+    precache_model ("models/turrets/terrainbase.md3");
+
+    //precache_model ("models/turrets/base.md3");
+    //precache_model ("models/turrets/flac.md3");
+    //precache_model ("models/turrets/pd_proj.md3");
+    //precache_model ("models/turrets/reactor.md3");
+    //precache_model ("models/turrets/mlrs_rocket.md3");
+    //precache_model ("models/turrets/hellion.md3");
+    //precache_model ("models/turrets/hunter2.md3");
+    //precache_model ("models/turrets/hk.md3");
+    //precache_model ("models/turrets/machinegun.md3");
+    //precache_model ("models/turrets/rocket.md3");
+    //precache_model ("models/turrets/mlrs.md3");
+    //precache_model ("models/turrets/phaser.md3");
+    //precache_model ("models/turrets/phaser_beam.md3");
+    //precache_model ("models/turrets/plasmad.md3");
+    //precache_model ("models/turrets/plasma.md3");
+    //precache_model ("models/turrets/tesla_head.md3");
+    //precache_model ("models/turrets/tesla_base.md3");
+
+#if 0
+    precache_model ("models/turrets/c512.md3");
+    precache_model ("models/pathlib/goodsquare.md3");
+    precache_model ("models/pathlib/badsquare.md3");
+    precache_model ("models/pathlib/square.md3");
+    precache_model ("models/pathlib/edge.md3");
+#endif
+}


Property changes on: trunk/data/qcsrc/server/tturrets/system/system_misc.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,166 +1,166 @@
-/*
-.float target_select_flags; /// target selection flags
-float TFL_TARGETSELECT_NO            = 1;   /// Dont select a target on its own.
-float TFL_TARGETSELECT_LOS           = 2;   /// Need line of sight
-float TFL_TARGETSELECT_PLAYERS       = 4;   /// Players are valid targets
-float TFL_TARGETSELECT_MISSILES      = 8;   /// Missiles are valid targets
-float TFL_TARGETSELECT_TRIGGERTARGET = 16;  /// Responds to turret_trigger_target events
-float TFL_TARGETSELECT_ANGLELIMITS   = 32;  /// Angular limitations of turret head limits target selection
-float TFL_TARGETSELECT_RANGELIMTS    = 64;  /// Range limits apply in targetselection
-float TFL_TARGETSELECT_TEAMCHECK     = 128; /// Consider team own <-> targets team
-float TFL_TARGETSELECT_NOBUILTIN     = 256; /// Cant select targets on its own. needs to be triggerd or slaved.
-float TFL_TARGETSELECT_OWNTEAM       = 512;
-*/
-
-float turret_stdproc_targetscore_support(entity e_turret,entity e_target)
-{
-    float score;        // Total score
-    float s_score,d_score;
-
-    if (e_turret.enemy == e_target) s_score = 1;
-
-    d_score = min(e_turret.target_range_optimal,tvt_dist) / max(e_turret.target_range_optimal,tvt_dist);
-
-    score = (d_score * e_turret.target_select_rangebias) +
-            (s_score * e_turret.target_select_samebias);
-
-    return score;
-}
-
-/*
-* Generic bias aware score system.
-*/
-float turret_stdproc_targetscore_generic(entity e_turret,entity e_target)
-{
-    //vector v_tmp;
-    float d_dist;       // Defendmode Distance
-
-    float score;        // Total score
-
-    float d_score;      // Distance score
-    float a_score;      // Angular score
-    float m_score;      // missile score
-    float p_score;      // player score
-    //float da_score;   // Distance from aimpoint score
-
-    float ikr;          // ideal kill range
-
-    if(!e_target) return 0;
-
-    //if (e_target == e_turret.enemy) s_score = 1;
-
-    if (e_turret.tur_defend)
-    {
-        d_dist = vlen(real_origin(e_target) - e_turret.tur_defend.origin);
-        ikr = vlen(e_turret.origin - e_turret.tur_defend.origin);
-        d_score = 1 - d_dist / e_turret.target_range;
-    }
-    else
-    {
-        // Make a normlized value base on the targets distance from our optimal killzone
-        ikr = e_turret.target_range_optimal;
-        d_score = min(ikr,tvt_dist) / max(ikr,tvt_dist);
-    }
-
-    /*
-    // Determine the maximum time it could take this turrent to aim at someting.
-    max_aim_delay = (max(e_turret.aim_maxrot,e_turret.aim_maxpitch) / e_turret.aim_speed * 2);
-
-    // Find out how long it would take to aim at this taget.
-    aim_delay = (thadf+0.01) / e_turret.aim_speed;
-
-    // Turn this info into a normalized value.
-    aim_delay = (min(max_aim_delay,aim_delay) / max_aim_delay);
-    a_score = 1 - aim_delay;
-    */
-
-    //a_score = 1 - (tvt_thadf / max(e_turret.aim_maxrot,e_turret.aim_maxpitch));
-    a_score = 1 - tvt_thadf / e_turret.aim_maxrot;
-
-    if ((e_turret.target_select_missilebias > 0) && (e_target.flags & FL_PROJECTILE))
-        m_score = 1;
-
-    if ((e_turret.target_select_playerbias > 0) && (e_target.flags & FL_CLIENT))
-        p_score = 1;
-
-    d_score = max(d_score,0);
-    a_score = max(a_score,0);
-    m_score = max(m_score,0);
-    p_score = max(p_score,0);
-
-    score = (d_score * e_turret.target_select_rangebias) +
-            (a_score * e_turret.target_select_anglebias) +
-            (m_score * e_turret.target_select_missilebias) +
-            (p_score * e_turret.target_select_playerbias);
-
-    if(e_turret.target_range < vlen(e_turret.tur_shotorg - real_origin(e_target)))
-    {
-        dprint("Wtf?\n");
-        score *= 0.001;
-    }
-
-#ifdef TURRET_DEBUG
-    string sd,sa,sm,sp,ss;
-    string sdt,sat,smt,spt;
-
-    sd = ftos(d_score);
-    d_score *= e_turret.target_select_rangebias;
-    sdt = ftos(d_score);
-
-    //sv = ftos(v_score);
-    //v_score *= e_turret.target_select_samebias;
-    //svt = ftos(v_score);
-
-    sa = ftos(a_score);
-    a_score *= e_turret.target_select_anglebias;
-    sat = ftos(a_score);
-
-    sm = ftos(m_score);
-    m_score *= e_turret.target_select_missilebias;
-    smt = ftos(m_score);
-
-    sp = ftos(p_score);
-    p_score *= e_turret.target_select_playerbias;
-    spt = ftos(p_score);
-
-
-    ss = ftos(score);
-    bprint("^3Target scores^7 \[  ",e_turret.netname, "  \] ^3for^7 \[  ", e_target.netname,"  \]\n");
-    bprint("^5Range:\[  ",sd,  "  \]^2+bias:\[  ",sdt,"  \]\n");
-    bprint("^5Angle:\[  ",sa,  "  \]^2+bias:\[  ",sat,"  \]\n");
-    bprint("^5Missile:\[  ",sm,"  \]^2+bias:\[  ",smt,"  \]\n");
-    bprint("^5Player:\[  ",sp, "  \]^2+bias:\[  ",spt,"  \]\n");
-    bprint("^3Total (w/bias):\[^1",ss,"\]\n");
-
-#endif
-
-    return score;
-}
-
-/*
-float turret_stdproc_targetscore_close(entity e_turret,entity e_target)
-{
-    return 1 - (tvt_dist / e_turret.target_range);
-}
-
-float turret_stdproc_targetscore_far (entity e_turret,entity e_target)
-{
-    return  tvt_dist / e_turret.target_range;
-}
-
-float turret_stdproc_targetscore_optimal(entity e_turret,entity e_target)
-{
-    return  min(e_turret.target_range_optimal,tvt_dist) / max(e_turret.target_range_optimal,tvt_dist);
-}
-
-float turret_stdproc_score_angular(entity e_turret,entity e_target)
-{
-    return 1 - (tvt_thadf / e_turret.aim_maxrot);
-}
-
-float turret_stdproc_targetscore_defend(entity e_turret,entity e_target)
-{
-    return 0;
-    //min(e_target.origin,e_turret.tur_defend.origin) / max(e_target.origin,e_turret.tur_defend.origin);
-}
-*/
+/*
+.float target_select_flags; /// target selection flags
+float TFL_TARGETSELECT_NO            = 1;   /// Dont select a target on its own.
+float TFL_TARGETSELECT_LOS           = 2;   /// Need line of sight
+float TFL_TARGETSELECT_PLAYERS       = 4;   /// Players are valid targets
+float TFL_TARGETSELECT_MISSILES      = 8;   /// Missiles are valid targets
+float TFL_TARGETSELECT_TRIGGERTARGET = 16;  /// Responds to turret_trigger_target events
+float TFL_TARGETSELECT_ANGLELIMITS   = 32;  /// Angular limitations of turret head limits target selection
+float TFL_TARGETSELECT_RANGELIMTS    = 64;  /// Range limits apply in targetselection
+float TFL_TARGETSELECT_TEAMCHECK     = 128; /// Consider team own <-> targets team
+float TFL_TARGETSELECT_NOBUILTIN     = 256; /// Cant select targets on its own. needs to be triggerd or slaved.
+float TFL_TARGETSELECT_OWNTEAM       = 512;
+*/
+
+float turret_stdproc_targetscore_support(entity e_turret,entity e_target)
+{
+    float score;        // Total score
+    float s_score,d_score;
+
+    if (e_turret.enemy == e_target) s_score = 1;
+
+    d_score = min(e_turret.target_range_optimal,tvt_dist) / max(e_turret.target_range_optimal,tvt_dist);
+
+    score = (d_score * e_turret.target_select_rangebias) +
+            (s_score * e_turret.target_select_samebias);
+
+    return score;
+}
+
+/*
+* Generic bias aware score system.
+*/
+float turret_stdproc_targetscore_generic(entity e_turret,entity e_target)
+{
+    //vector v_tmp;
+    float d_dist;       // Defendmode Distance
+
+    float score;        // Total score
+
+    float d_score;      // Distance score
+    float a_score;      // Angular score
+    float m_score;      // missile score
+    float p_score;      // player score
+    //float da_score;   // Distance from aimpoint score
+
+    float ikr;          // ideal kill range
+
+    if(!e_target) return 0;
+
+    //if (e_target == e_turret.enemy) s_score = 1;
+
+    if (e_turret.tur_defend)
+    {
+        d_dist = vlen(real_origin(e_target) - e_turret.tur_defend.origin);
+        ikr = vlen(e_turret.origin - e_turret.tur_defend.origin);
+        d_score = 1 - d_dist / e_turret.target_range;
+    }
+    else
+    {
+        // Make a normlized value base on the targets distance from our optimal killzone
+        ikr = e_turret.target_range_optimal;
+        d_score = min(ikr,tvt_dist) / max(ikr,tvt_dist);
+    }
+
+    /*
+    // Determine the maximum time it could take this turrent to aim at someting.
+    max_aim_delay = (max(e_turret.aim_maxrot,e_turret.aim_maxpitch) / e_turret.aim_speed * 2);
+
+    // Find out how long it would take to aim at this taget.
+    aim_delay = (thadf+0.01) / e_turret.aim_speed;
+
+    // Turn this info into a normalized value.
+    aim_delay = (min(max_aim_delay,aim_delay) / max_aim_delay);
+    a_score = 1 - aim_delay;
+    */
+
+    //a_score = 1 - (tvt_thadf / max(e_turret.aim_maxrot,e_turret.aim_maxpitch));
+    a_score = 1 - tvt_thadf / e_turret.aim_maxrot;
+
+    if ((e_turret.target_select_missilebias > 0) && (e_target.flags & FL_PROJECTILE))
+        m_score = 1;
+
+    if ((e_turret.target_select_playerbias > 0) && (e_target.flags & FL_CLIENT))
+        p_score = 1;
+
+    d_score = max(d_score,0);
+    a_score = max(a_score,0);
+    m_score = max(m_score,0);
+    p_score = max(p_score,0);
+
+    score = (d_score * e_turret.target_select_rangebias) +
+            (a_score * e_turret.target_select_anglebias) +
+            (m_score * e_turret.target_select_missilebias) +
+            (p_score * e_turret.target_select_playerbias);
+
+    if(e_turret.target_range < vlen(e_turret.tur_shotorg - real_origin(e_target)))
+    {
+        dprint("Wtf?\n");
+        score *= 0.001;
+    }
+
+#ifdef TURRET_DEBUG
+    string sd,sa,sm,sp,ss;
+    string sdt,sat,smt,spt;
+
+    sd = ftos(d_score);
+    d_score *= e_turret.target_select_rangebias;
+    sdt = ftos(d_score);
+
+    //sv = ftos(v_score);
+    //v_score *= e_turret.target_select_samebias;
+    //svt = ftos(v_score);
+
+    sa = ftos(a_score);
+    a_score *= e_turret.target_select_anglebias;
+    sat = ftos(a_score);
+
+    sm = ftos(m_score);
+    m_score *= e_turret.target_select_missilebias;
+    smt = ftos(m_score);
+
+    sp = ftos(p_score);
+    p_score *= e_turret.target_select_playerbias;
+    spt = ftos(p_score);
+
+
+    ss = ftos(score);
+    bprint("^3Target scores^7 \[  ",e_turret.netname, "  \] ^3for^7 \[  ", e_target.netname,"  \]\n");
+    bprint("^5Range:\[  ",sd,  "  \]^2+bias:\[  ",sdt,"  \]\n");
+    bprint("^5Angle:\[  ",sa,  "  \]^2+bias:\[  ",sat,"  \]\n");
+    bprint("^5Missile:\[  ",sm,"  \]^2+bias:\[  ",smt,"  \]\n");
+    bprint("^5Player:\[  ",sp, "  \]^2+bias:\[  ",spt,"  \]\n");
+    bprint("^3Total (w/bias):\[^1",ss,"\]\n");
+
+#endif
+
+    return score;
+}
+
+/*
+float turret_stdproc_targetscore_close(entity e_turret,entity e_target)
+{
+    return 1 - (tvt_dist / e_turret.target_range);
+}
+
+float turret_stdproc_targetscore_far (entity e_turret,entity e_target)
+{
+    return  tvt_dist / e_turret.target_range;
+}
+
+float turret_stdproc_targetscore_optimal(entity e_turret,entity e_target)
+{
+    return  min(e_turret.target_range_optimal,tvt_dist) / max(e_turret.target_range_optimal,tvt_dist);
+}
+
+float turret_stdproc_score_angular(entity e_turret,entity e_target)
+{
+    return 1 - (tvt_thadf / e_turret.aim_maxrot);
+}
+
+float turret_stdproc_targetscore_defend(entity e_turret,entity e_target)
+{
+    return 0;
+    //min(e_target.origin,e_turret.tur_defend.origin) / max(e_target.origin,e_turret.tur_defend.origin);
+}
+*/


Property changes on: trunk/data/qcsrc/server/tturrets/system/system_scoreprocs.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,70 +1,70 @@
-/**
-    turret_checkpoint
-**/
-
-
-#define checkpoint_target goalstack03
-
-/*
-#define checkpoint_cache_who  flagcarried
-#define checkpoint_cache_from lastrocket
-#define checkpoint_cache_to   selected_player
-*/
-
-#define pathgoal    goalstack01
-#define pathcurrent goalstack02
-
-/*
-entity path_makeorcache(entity forwho,entity start, entity end)
-{
-    entity oldself;
-    entity pth;
-    oldself = self;
-    self = forwho;
-
-    //pth = pathlib_makepath(start.origin,end.origin,PFL_GROUNDSNAP,500,1.5,PT_QUICKSTAR);
-
-    self = oldself;
-    return pth;
-}
-*/
-
-void turret_checkpoint_use()
-{
-}
-
-/*QUAKED turret_checkpoint (1 0 1) (-32 -32 -32) (32 32 32)
------------KEYS------------
-target: .targetname of next waypoint in chain.
-wait:   Pause at this point # seconds.
------------SPAWNFLAGS-----------
----------NOTES----------
-If a loop is of targets are formed, any unit entering this loop will patrol it indefinitly.
-If the checkpoint chain in not looped, the unit will go "Roaming" when the last point is reached.
-*/
-void turret_checkpoint_init()
-{
-    traceline(self.origin, self.origin - '0 0 1024', MOVE_WORLDONLY, self);
-    setorigin(self,trace_endpos + '0 0 8');
-
-    if(self.target != "")
-    {
-        self.enemy = find(world,targetname,self.target);
-        if(self.enemy == world)
-            dprint("A turret_checkpoint faild to find its target!\n");
-    }
-}
-
-void spawnfunc_turret_checkpoint()
-{
-    setorigin(self,self.origin);
-    self.think = turret_checkpoint_init;
-    self.nextthink = time + 0.1;
-}
-
-// Compat.
-void spawnfunc_walker_checkpoint()
-{
-    self.classname = "turret_checkpoint";
-    spawnfunc_turret_checkpoint();
-}
+/**
+    turret_checkpoint
+**/
+
+
+#define checkpoint_target goalstack03
+
+/*
+#define checkpoint_cache_who  flagcarried
+#define checkpoint_cache_from lastrocket
+#define checkpoint_cache_to   selected_player
+*/
+
+#define pathgoal    goalstack01
+#define pathcurrent goalstack02
+
+/*
+entity path_makeorcache(entity forwho,entity start, entity end)
+{
+    entity oldself;
+    entity pth;
+    oldself = self;
+    self = forwho;
+
+    //pth = pathlib_makepath(start.origin,end.origin,PFL_GROUNDSNAP,500,1.5,PT_QUICKSTAR);
+
+    self = oldself;
+    return pth;
+}
+*/
+
+void turret_checkpoint_use()
+{
+}
+
+/*QUAKED turret_checkpoint (1 0 1) (-32 -32 -32) (32 32 32)
+-----------KEYS------------
+target: .targetname of next waypoint in chain.
+wait:   Pause at this point # seconds.
+-----------SPAWNFLAGS-----------
+---------NOTES----------
+If a loop is of targets are formed, any unit entering this loop will patrol it indefinitly.
+If the checkpoint chain in not looped, the unit will go "Roaming" when the last point is reached.
+*/
+void turret_checkpoint_init()
+{
+    traceline(self.origin, self.origin - '0 0 1024', MOVE_WORLDONLY, self);
+    setorigin(self,trace_endpos + '0 0 8');
+
+    if(self.target != "")
+    {
+        self.enemy = find(world,targetname,self.target);
+        if(self.enemy == world)
+            dprint("A turret_checkpoint faild to find its target!\n");
+    }
+}
+
+void spawnfunc_turret_checkpoint()
+{
+    setorigin(self,self.origin);
+    self.think = turret_checkpoint_init;
+    self.nextthink = time + 0.1;
+}
+
+// Compat.
+void spawnfunc_walker_checkpoint()
+{
+    self.classname = "turret_checkpoint";
+    spawnfunc_turret_checkpoint();
+}


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_checkpoint.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_common.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_common.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_common.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1 +1 @@
-
+


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_common.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_ewheel.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_ewheel.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_ewheel.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,520 +1,520 @@
-void turret_ewheel_projectile_explode()
-{
-    vector org2;
-
-    org2 = findbetterlocation (self.origin, 8);
-    pointparticles(particleeffectnum("laser_impact"), org2, trace_plane_normal * 1000, 1);
-    //w_deathtypestring = "saw the eweel. to late.";
-#ifdef TURRET_DEBUG
-    float d;
-
-    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
-    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#else
-    RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-#endif
-    sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
-
-    remove (self);
-}
-
-
-void ewheel_attack()
-{
-    entity proj;
-    float i;
-
-    for (i=0;i<1;++i)
-    {
-        turret_do_updates(self);
-
-        sound (self, CHAN_WEAPON, "weapons/lasergun_fire.wav", VOL_BASE, ATTN_NORM);
-        pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
-        proj                    = spawn ();
-        setorigin(proj, self.tur_shotorg);
-        //setsize(proj, '-0.5 -0.5 -0.5', '0.5 0.5 0.5');
-        //setmodel(proj, "models/laser.mdl"); // precision set above
-        proj.classname       = "ewheel bolt";
-        proj.owner           = self;
-        proj.bot_dodge       = FALSE;
-        proj.bot_dodgerating = self.shot_dmg;
-        proj.think           = turret_ewheel_projectile_explode;
-        proj.nextthink       = time + 9;
-        proj.solid           = SOLID_BBOX;
-        proj.movetype        = MOVETYPE_FLYMISSILE;
-        proj.velocity        = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
-        proj.angles          = vectoangles(proj.velocity);
-        proj.touch           = turret_ewheel_projectile_explode;
-        //proj.effects         = EF_LOWPRECISION |  EF_BRIGHTFIELD;
-        proj.enemy           = self.enemy;
-        proj.flags           = FL_PROJECTILE | FL_NOTARGET;
-
-        CSQCProjectile(proj, TRUE, PROJECTILE_LASER, TRUE);
-
-        self.tur_head.frame += 2;
-
-        if (self.tur_head.frame > 3)
-            self.tur_head.frame = 0;
-    }
-
-}
-
-float ewheel_moveverb_roam(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-
-        if (!self.enemy)
-            return verb.verb_static_value;
-
-        return VS_CALL_NO;
-
-    case VCM_DO:
-        self.angles_z = 0;
-        makevectors(self.angles);
-        self.moveto = v_forward * 128;
-        self.steerto = steerlib_beamsteer(v_forward,1024,32,36,128);
-        self.frame += 1;
-        movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
-
-        return VS_CALL_YES_DOING;
-
-    case VCM_REMOVE:
-
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-float ewheel_moveverb_path(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-
-        if (self.pathcurrent)
-            return verb.verb_static_value;
-
-        return VS_CALL_NO;
-
-    case VCM_DO:
-        // Do we have a path?
-        if not(self.pathcurrent)
-            return VS_CALL_NO;
-        else
-        {
-            // Are we close enougth to a path node to switch to the next?
-            if (vlen(self.origin  - self.pathcurrent.origin) < 64)
-                if (self.pathcurrent.path_next == world)
-                {
-                    // Path endpoint reached
-                    pathlib_deletepath(self.pathcurrent.owner);
-                    self.pathcurrent = world;
-
-                    if (self.pathgoal)
-                    {
-                        if (self.pathgoal.use)
-                            self.pathgoal.use();
-
-                        if (self.pathgoal.enemy)
-                        {
-                            self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
-                            self.pathgoal = self.pathgoal.enemy;
-                        }
-                    }
-                    else
-                        self.pathgoal = world;
-                }
-                else
-                    self.pathcurrent = self.pathcurrent.path_next;
-        }
-
-
-        if (self.pathcurrent)
-        {
-            switch (self.waterlevel)
-            {
-            case 0:
-            case 1:
-            case 2:
-            case 3:
-            }
-
-            self.moveto = self.pathcurrent.origin;
-            self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
-
-            self.frame += 1;
-            movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
-
-            return VS_CALL_YES_DOING;
-        }
-        else
-            return VS_CALL_YES_DONE;
-
-    case VCM_REMOVE:
-
-        if (self.pathcurrent)
-            pathlib_deletepath(self.pathcurrent.owner);
-
-        self.pathcurrent = world;
-
-        return VS_CALL_YES_DONE;
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-float ewheel_moveverb_enemy(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-        if (self.enemy)
-        {
-            if (self.spawnflags & TSF_NO_PATHBREAK)
-                if (self.pathcurrent)
-                    return VS_CALL_NO;
-
-            return verb.verb_static_value;
-        }
-
-        return VS_CALL_NO;
-
-    case VCM_DO:
-
-        self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
-        self.steerto = steerlib_beamsteer(self.steerto,1024,64,68,256);
-        self.moveto  = self.origin + self.steerto * 128;
-
-        makevectors(self.angles);
-
-        if (self.tur_dist_enemy > self.target_range_optimal)
-        {
-            if ( self.tur_head.spawnshieldtime < 1 )
-            {
-                self.frame += 2;
-                movelib_move_simple(v_forward ,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
-            }
-            else if (self.tur_head.spawnshieldtime < 2)
-            {
-
-                self.frame += 1;
-                movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_slow"),0.4);
-           }
-            else
-            {
-                self.frame += 1;
-                movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_slower"),0.4);
-            }
-        }
-        else if (self.tur_dist_enemy < self.target_range_min)
-        {
-            self.frame -= 1;
-            movelib_move_simple(v_forward * -1,cvar("g_turrets_unit_ewheel_speed_slow"),0.4);
-        }
-        else
-        {
-            movelib_beak_simple(cvar("g_turrets_unit_ewheel_speed_stop"));
-        }
-
-        return VS_CALL_YES_DOING;
-    }
-
-
-    return VS_CALL_YES_DONE;
-}
-
-float ewheel_moveverb_runaway(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-        if (self.spawnflags & TSF_NO_PATHBREAK)
-            if (self.pathcurrent)
-                return VS_CALL_NO;
-
-        if (self.enemy)
-            if (self.health < 50)
-                return verb.verb_static_value;
-
-        return VS_CALL_NO;
-
-    case VCM_DO:
-        self.steerto = (steerlib_push(self.enemy.origin) * 0.7) + (steerlib_traceavoid_flat(0.3, 500, '0 0 128') * 0.3);
-        self.moveto  = self.origin + self.steerto * 1000;
-
-        self.frame += 2;
-        movelib_move_simple(v_forward ,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
-
-        return VS_CALL_YES_DOING;
-
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-float ewheel_moveverb_idle(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-        if (self.enemy)
-            return VS_CALL_NO;
-
-        return verb.verb_static_value;
-
-    case VCM_DO:
-        self.moveto = self.origin;
-
-        if (vlen(self.velocity))
-            movelib_beak_simple(cvar("g_turrets_unit_ewheel_speed_stop"));
-
-        return VS_CALL_YES_DOING;
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-void ewheel_postthink()
-{
-    float vz;
-    vector wish_angle,real_angle;
-
-    vz = self.velocity_z;
-
-    self.angles_x = anglemods(self.angles_x);
-    self.angles_y = anglemods(self.angles_y);
-
-    self.angles_x *= -1;
-    makevectors(self.angles);
-    self.angles_x *= -1;
-
-    wish_angle = normalize(self.steerto);
-    wish_angle = vectoangles(wish_angle);
-    real_angle = wish_angle - self.angles;
-    real_angle = shortangle_vxy(real_angle,self.tur_head.angles);
-
-    self.tur_head.spawnshieldtime = fabs(real_angle_y);
-    real_angle_y  = bound(-self.tur_head.aim_speed,real_angle_y,self.tur_head.aim_speed);
-    self.angles_y = (self.angles_y + real_angle_y);
-
-    // Simulate banking
-    self.angles_z = bound(-45,real_angle_y * -2.5,45);
-
-    verbstack_pop(self.verbs_move);
-
-    if (self.frame > 40)
-        self.frame = 1;
-
-    if (self.frame < 1)
-        self.frame = 40;
-
-
-    self.velocity_z = vz;
-}
-
-void ewheel_respawnhook()
-{
-    entity e;
-
-    setorigin(self,self.pos1);
-
-    if (self.target != "")
-    {
-        e = find(world,targetname,self.target);
-        if (!e)
-        {
-            dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
-            self.target = "";
-        }
-
-        if (e.classname != "turret_checkpoint")
-            dprint("Warning: not a turrret path\n");
-        else
-        {
-            self.pathcurrent = WALKER_PATH(self.origin,e.origin);
-            self.pathgoal = e;
-        }
-    }
-}
-
-void ewheel_diehook()
-{
-    turret_trowgib2(self.origin,self.velocity + v_up * 400,'-0.6 -0.2 -02',self,time + random() * 2 +3);
-
-    if (self.pathcurrent)
-        pathlib_deletepath(self.pathcurrent.owner);
-
-    self.pathcurrent = world;
-
-    if (self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
-    {
-        verbstack_flush(self.verbs_move);
-        remove(self.verbs_move);
-    }
-
-}
-
-/*
-float test_stack_1(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-        return verb.verb_static_value;
-
-    case VCM_DO:
-        dprint("test_stack_1\n");
-        return VS_CALL_REMOVE;
-    }
-
-    return VS_CALL_REMOVE;
-}
-
-float test_stack_2(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-        return verb.verb_static_value;
-
-    case VCM_DO:
-        dprint("test_stack_2\n");
-        return VS_CALL_REMOVE;
-    }
-
-    return VS_CALL_REMOVE;
-}
-
-float ccnntt;
-float test_stack_3(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-        return verb.verb_static_value;
-
-    case VCM_DO:
-        dprint("test_stack_3\n");
-        ++ccnntt;
-        if(ccnntt > 3)
-            return VS_CALL_REMOVE;
-        else
-            return VS_CALL_YES_DONE;
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-.entity test_stack;
-*/
-void turret_ewheel_dinit()
-{
-    entity e;
-
-    if (self.netname == "")      self.netname     = "eWheel Turret";
-
-    if (self.target != "")
-    {
-        e = find(world,targetname,self.target);
-        if (!e)
-        {
-            bprint("Warning! initital waypoint for ewheel does NOT exsist!\n");
-            self.target = "";
-        }
-
-        if (e.classname != "turret_checkpoint")
-            dprint("Warning: not a turrret path\n");
-        else
-            self.goalcurrent = e;
-    }
-
-    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-    self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM | TFL_TURRCAPS_HEADATTACHED;
-    //self.aim_flags = TFL_AIM_SIMPLE;// TFL_AIM_LEAD | TFL_AIM_ZEASE;
-
-    self.turret_respawnhook = ewheel_respawnhook;
-    self.turret_diehook = ewheel_diehook;
-
-    if (turret_stdproc_init("ewheel_std",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;// | TFL_TARGETSELECT_LOS;
-    self.damage_flags          |= TFL_DMG_DEATH_NOGIBS;
-
-    self.iscreature = TRUE;
-    self.movetype   = MOVETYPE_WALK;
-    self.solid      = SOLID_SLIDEBOX;
-    self.takedamage = DAMAGE_AIM;
-
-    setmodel(self,"models/turrets/ewheel-base.md3");
-    setmodel(self.tur_head,"models/turrets/ewheel-gun1.md3");
-    setattachment(self.tur_head,self,"tag_head");
-
-    self.pos1 = self.origin;
-
-    self.idle_aim = '0 0 0';
-
-    // Our fire routine
-    self.turret_firefunc  = ewheel_attack;
-    self.turret_postthink = ewheel_postthink;
-    self.tur_head.frame = 1;
-
-    self.verbs_move = spawn();
-
-    //verbstack_push(self.verbs_move, ewheel_moveverb_roam,   WVM_IDLE,  0, self);
-    verbstack_push(self.verbs_move, ewheel_moveverb_idle,   WVM_IDLE,  0, self);
-    verbstack_push(self.verbs_move, ewheel_moveverb_enemy,  WVM_ENEMY, 0, self);
-    verbstack_push(self.verbs_move, ewheel_moveverb_path,   WVM_PATH,  0, self);
-    //verbstack_push(self.verbs_move, ewheel_moveverb_runaway,WVM_PANIC,  0, self);
-
-    /*
-    self.test_stack = spawn();
-    verbstack_push(self.test_stack, test_stack_1,1,  0, self);
-    verbstack_push(self.test_stack, test_stack_2,2,  0, self);
-    verbstack_push(self.test_stack, test_stack_3,100,0, self);
-    while(verbstack_popfifo(self.test_stack) != 0)
-    */
-
-
-
-    // Convert from dgr / sec to dgr / tic
-    self.tur_head.aim_speed = cvar("g_turrets_unit_ewheel_turnrate");
-    self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
-
-    if (self.target != "")
-    {
-        e = find(world,targetname,self.target);
-        if (!e)
-        {
-            dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
-            self.target = "";
-        }
-
-        if (e.classname != "turret_checkpoint")
-            dprint("Warning: not a turrret path\n");
-        else
-        {
-            self.pathcurrent = WALKER_PATH(self.origin,e.origin);
-            self.pathgoal = e;
-        }
-    }
-}
-
-void spawnfunc_turret_ewheel()
-{
-    g_turrets_common_precash();
-
-    precache_model ("models/turrets/ewheel-base.md3");
-    precache_model ("models/turrets/ewheel-gun1.md3");
-
-    self.think = turret_ewheel_dinit;
-    self.nextthink = time + 0.5;
-}
+void turret_ewheel_projectile_explode()
+{
+    vector org2;
+
+    org2 = findbetterlocation (self.origin, 8);
+    pointparticles(particleeffectnum("laser_impact"), org2, trace_plane_normal * 1000, 1);
+    //w_deathtypestring = "saw the eweel. to late.";
+#ifdef TURRET_DEBUG
+    float d;
+
+    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
+    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#else
+    RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+#endif
+    sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
+
+    remove (self);
+}
+
+
+void ewheel_attack()
+{
+    entity proj;
+    float i;
+
+    for (i=0;i<1;++i)
+    {
+        turret_do_updates(self);
+
+        sound (self, CHAN_WEAPON, "weapons/lasergun_fire.wav", VOL_BASE, ATTN_NORM);
+        pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+
+        proj                    = spawn ();
+        setorigin(proj, self.tur_shotorg);
+        //setsize(proj, '-0.5 -0.5 -0.5', '0.5 0.5 0.5');
+        //setmodel(proj, "models/laser.mdl"); // precision set above
+        proj.classname       = "ewheel bolt";
+        proj.owner           = self;
+        proj.bot_dodge       = FALSE;
+        proj.bot_dodgerating = self.shot_dmg;
+        proj.think           = turret_ewheel_projectile_explode;
+        proj.nextthink       = time + 9;
+        proj.solid           = SOLID_BBOX;
+        proj.movetype        = MOVETYPE_FLYMISSILE;
+        proj.velocity        = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+        proj.angles          = vectoangles(proj.velocity);
+        proj.touch           = turret_ewheel_projectile_explode;
+        //proj.effects         = EF_LOWPRECISION |  EF_BRIGHTFIELD;
+        proj.enemy           = self.enemy;
+        proj.flags           = FL_PROJECTILE | FL_NOTARGET;
+
+        CSQCProjectile(proj, TRUE, PROJECTILE_LASER, TRUE);
+
+        self.tur_head.frame += 2;
+
+        if (self.tur_head.frame > 3)
+            self.tur_head.frame = 0;
+    }
+
+}
+
+float ewheel_moveverb_roam(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+
+        if (!self.enemy)
+            return verb.verb_static_value;
+
+        return VS_CALL_NO;
+
+    case VCM_DO:
+        self.angles_z = 0;
+        makevectors(self.angles);
+        self.moveto = v_forward * 128;
+        self.steerto = steerlib_beamsteer(v_forward,1024,32,36,128);
+        self.frame += 1;
+        movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
+
+        return VS_CALL_YES_DOING;
+
+    case VCM_REMOVE:
+
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+float ewheel_moveverb_path(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+
+        if (self.pathcurrent)
+            return verb.verb_static_value;
+
+        return VS_CALL_NO;
+
+    case VCM_DO:
+        // Do we have a path?
+        if not(self.pathcurrent)
+            return VS_CALL_NO;
+        else
+        {
+            // Are we close enougth to a path node to switch to the next?
+            if (vlen(self.origin  - self.pathcurrent.origin) < 64)
+                if (self.pathcurrent.path_next == world)
+                {
+                    // Path endpoint reached
+                    pathlib_deletepath(self.pathcurrent.owner);
+                    self.pathcurrent = world;
+
+                    if (self.pathgoal)
+                    {
+                        if (self.pathgoal.use)
+                            self.pathgoal.use();
+
+                        if (self.pathgoal.enemy)
+                        {
+                            self.pathcurrent = pathlib_astar(self.pathgoal.origin,self.pathgoal.enemy.origin);
+                            self.pathgoal = self.pathgoal.enemy;
+                        }
+                    }
+                    else
+                        self.pathgoal = world;
+                }
+                else
+                    self.pathcurrent = self.pathcurrent.path_next;
+        }
+
+
+        if (self.pathcurrent)
+        {
+            switch (self.waterlevel)
+            {
+            case 0:
+            case 1:
+            case 2:
+            case 3:
+            }
+
+            self.moveto = self.pathcurrent.origin;
+            self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
+
+            self.frame += 1;
+            movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
+
+            return VS_CALL_YES_DOING;
+        }
+        else
+            return VS_CALL_YES_DONE;
+
+    case VCM_REMOVE:
+
+        if (self.pathcurrent)
+            pathlib_deletepath(self.pathcurrent.owner);
+
+        self.pathcurrent = world;
+
+        return VS_CALL_YES_DONE;
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+float ewheel_moveverb_enemy(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+        if (self.enemy)
+        {
+            if (self.spawnflags & TSF_NO_PATHBREAK)
+                if (self.pathcurrent)
+                    return VS_CALL_NO;
+
+            return verb.verb_static_value;
+        }
+
+        return VS_CALL_NO;
+
+    case VCM_DO:
+
+        self.steerto = steerlib_arrive(self.enemy.origin,self.target_range_optimal);
+        self.steerto = steerlib_beamsteer(self.steerto,1024,64,68,256);
+        self.moveto  = self.origin + self.steerto * 128;
+
+        makevectors(self.angles);
+
+        if (self.tur_dist_enemy > self.target_range_optimal)
+        {
+            if ( self.tur_head.spawnshieldtime < 1 )
+            {
+                self.frame += 2;
+                movelib_move_simple(v_forward ,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
+            }
+            else if (self.tur_head.spawnshieldtime < 2)
+            {
+
+                self.frame += 1;
+                movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_slow"),0.4);
+           }
+            else
+            {
+                self.frame += 1;
+                movelib_move_simple(v_forward,cvar("g_turrets_unit_ewheel_speed_slower"),0.4);
+            }
+        }
+        else if (self.tur_dist_enemy < self.target_range_min)
+        {
+            self.frame -= 1;
+            movelib_move_simple(v_forward * -1,cvar("g_turrets_unit_ewheel_speed_slow"),0.4);
+        }
+        else
+        {
+            movelib_beak_simple(cvar("g_turrets_unit_ewheel_speed_stop"));
+        }
+
+        return VS_CALL_YES_DOING;
+    }
+
+
+    return VS_CALL_YES_DONE;
+}
+
+float ewheel_moveverb_runaway(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+        if (self.spawnflags & TSF_NO_PATHBREAK)
+            if (self.pathcurrent)
+                return VS_CALL_NO;
+
+        if (self.enemy)
+            if (self.health < 50)
+                return verb.verb_static_value;
+
+        return VS_CALL_NO;
+
+    case VCM_DO:
+        self.steerto = (steerlib_push(self.enemy.origin) * 0.7) + (steerlib_traceavoid_flat(0.3, 500, '0 0 128') * 0.3);
+        self.moveto  = self.origin + self.steerto * 1000;
+
+        self.frame += 2;
+        movelib_move_simple(v_forward ,cvar("g_turrets_unit_ewheel_speed_fast"),0.4);
+
+        return VS_CALL_YES_DOING;
+
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+float ewheel_moveverb_idle(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+        if (self.enemy)
+            return VS_CALL_NO;
+
+        return verb.verb_static_value;
+
+    case VCM_DO:
+        self.moveto = self.origin;
+
+        if (vlen(self.velocity))
+            movelib_beak_simple(cvar("g_turrets_unit_ewheel_speed_stop"));
+
+        return VS_CALL_YES_DOING;
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+void ewheel_postthink()
+{
+    float vz;
+    vector wish_angle,real_angle;
+
+    vz = self.velocity_z;
+
+    self.angles_x = anglemods(self.angles_x);
+    self.angles_y = anglemods(self.angles_y);
+
+    self.angles_x *= -1;
+    makevectors(self.angles);
+    self.angles_x *= -1;
+
+    wish_angle = normalize(self.steerto);
+    wish_angle = vectoangles(wish_angle);
+    real_angle = wish_angle - self.angles;
+    real_angle = shortangle_vxy(real_angle,self.tur_head.angles);
+
+    self.tur_head.spawnshieldtime = fabs(real_angle_y);
+    real_angle_y  = bound(-self.tur_head.aim_speed,real_angle_y,self.tur_head.aim_speed);
+    self.angles_y = (self.angles_y + real_angle_y);
+
+    // Simulate banking
+    self.angles_z = bound(-45,real_angle_y * -2.5,45);
+
+    verbstack_pop(self.verbs_move);
+
+    if (self.frame > 40)
+        self.frame = 1;
+
+    if (self.frame < 1)
+        self.frame = 40;
+
+
+    self.velocity_z = vz;
+}
+
+void ewheel_respawnhook()
+{
+    entity e;
+
+    setorigin(self,self.pos1);
+
+    if (self.target != "")
+    {
+        e = find(world,targetname,self.target);
+        if (!e)
+        {
+            dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
+            self.target = "";
+        }
+
+        if (e.classname != "turret_checkpoint")
+            dprint("Warning: not a turrret path\n");
+        else
+        {
+            self.pathcurrent = WALKER_PATH(self.origin,e.origin);
+            self.pathgoal = e;
+        }
+    }
+}
+
+void ewheel_diehook()
+{
+    turret_trowgib2(self.origin,self.velocity + v_up * 400,'-0.6 -0.2 -02',self,time + random() * 2 +3);
+
+    if (self.pathcurrent)
+        pathlib_deletepath(self.pathcurrent.owner);
+
+    self.pathcurrent = world;
+
+    if (self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
+    {
+        verbstack_flush(self.verbs_move);
+        remove(self.verbs_move);
+    }
+
+}
+
+/*
+float test_stack_1(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+        return verb.verb_static_value;
+
+    case VCM_DO:
+        dprint("test_stack_1\n");
+        return VS_CALL_REMOVE;
+    }
+
+    return VS_CALL_REMOVE;
+}
+
+float test_stack_2(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+        return verb.verb_static_value;
+
+    case VCM_DO:
+        dprint("test_stack_2\n");
+        return VS_CALL_REMOVE;
+    }
+
+    return VS_CALL_REMOVE;
+}
+
+float ccnntt;
+float test_stack_3(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+        return verb.verb_static_value;
+
+    case VCM_DO:
+        dprint("test_stack_3\n");
+        ++ccnntt;
+        if(ccnntt > 3)
+            return VS_CALL_REMOVE;
+        else
+            return VS_CALL_YES_DONE;
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+.entity test_stack;
+*/
+void turret_ewheel_dinit()
+{
+    entity e;
+
+    if (self.netname == "")      self.netname     = "eWheel Turret";
+
+    if (self.target != "")
+    {
+        e = find(world,targetname,self.target);
+        if (!e)
+        {
+            bprint("Warning! initital waypoint for ewheel does NOT exsist!\n");
+            self.target = "";
+        }
+
+        if (e.classname != "turret_checkpoint")
+            dprint("Warning: not a turrret path\n");
+        else
+            self.goalcurrent = e;
+    }
+
+    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+    self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_ROAM | TFL_TURRCAPS_HEADATTACHED;
+    //self.aim_flags = TFL_AIM_SIMPLE;// TFL_AIM_LEAD | TFL_AIM_ZEASE;
+
+    self.turret_respawnhook = ewheel_respawnhook;
+    self.turret_diehook = ewheel_diehook;
+
+    if (turret_stdproc_init("ewheel_std",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
+    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;// | TFL_TARGETSELECT_LOS;
+    self.damage_flags          |= TFL_DMG_DEATH_NOGIBS;
+
+    self.iscreature = TRUE;
+    self.movetype   = MOVETYPE_WALK;
+    self.solid      = SOLID_SLIDEBOX;
+    self.takedamage = DAMAGE_AIM;
+
+    setmodel(self,"models/turrets/ewheel-base.md3");
+    setmodel(self.tur_head,"models/turrets/ewheel-gun1.md3");
+    setattachment(self.tur_head,self,"tag_head");
+
+    self.pos1 = self.origin;
+
+    self.idle_aim = '0 0 0';
+
+    // Our fire routine
+    self.turret_firefunc  = ewheel_attack;
+    self.turret_postthink = ewheel_postthink;
+    self.tur_head.frame = 1;
+
+    self.verbs_move = spawn();
+
+    //verbstack_push(self.verbs_move, ewheel_moveverb_roam,   WVM_IDLE,  0, self);
+    verbstack_push(self.verbs_move, ewheel_moveverb_idle,   WVM_IDLE,  0, self);
+    verbstack_push(self.verbs_move, ewheel_moveverb_enemy,  WVM_ENEMY, 0, self);
+    verbstack_push(self.verbs_move, ewheel_moveverb_path,   WVM_PATH,  0, self);
+    //verbstack_push(self.verbs_move, ewheel_moveverb_runaway,WVM_PANIC,  0, self);
+
+    /*
+    self.test_stack = spawn();
+    verbstack_push(self.test_stack, test_stack_1,1,  0, self);
+    verbstack_push(self.test_stack, test_stack_2,2,  0, self);
+    verbstack_push(self.test_stack, test_stack_3,100,0, self);
+    while(verbstack_popfifo(self.test_stack) != 0)
+    */
+
+
+
+    // Convert from dgr / sec to dgr / tic
+    self.tur_head.aim_speed = cvar("g_turrets_unit_ewheel_turnrate");
+    self.tur_head.aim_speed = self.tur_head.aim_speed / (1 / self.ticrate);
+
+    if (self.target != "")
+    {
+        e = find(world,targetname,self.target);
+        if (!e)
+        {
+            dprint("Initital waypoint for ewheel does NOT exsist, fix your map!\n");
+            self.target = "";
+        }
+
+        if (e.classname != "turret_checkpoint")
+            dprint("Warning: not a turrret path\n");
+        else
+        {
+            self.pathcurrent = WALKER_PATH(self.origin,e.origin);
+            self.pathgoal = e;
+        }
+    }
+}
+
+void spawnfunc_turret_ewheel()
+{
+    g_turrets_common_precash();
+
+    precache_model ("models/turrets/ewheel-base.md3");
+    precache_model ("models/turrets/ewheel-gun1.md3");
+
+    self.think = turret_ewheel_dinit;
+    self.nextthink = time + 0.5;
+}


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_ewheel.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_flac.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_flac.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_flac.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,128 +1,128 @@
-void spawnfunc_turret_flac();
-void turret_flac_dinit();
-void turret_flac_attack();
-void turret_flac_projectile_explode();
-
-void turret_flac_attack()
-{
-    local entity proj;
-
-    turret_tag_fire_update();
-
-    sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
-    proj = spawn ();
-    setorigin(proj, self.tur_shotorg);
-    // setmodel(proj, "models/turrets/pd_proj.md3");
-    setsize(proj, '0 0 0', '0 0 0');
-    proj.classname          = "flac_projectile";
-    proj.owner              = self;
-    proj.bot_dodge          = TRUE;
-    proj.bot_dodgerating    = self.shot_dmg;
-    proj.solid              = SOLID_BBOX;
-    proj.movetype           = MOVETYPE_FLYMISSILE;
-    proj.flags              = FL_PROJECTILE;
-    // proj.effects            = EF_LOWPRECISION;
-    proj.takedamage         = DAMAGE_NO;
-    //proj.health             =  100;
-    proj.velocity           = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
-    proj.angles             = vectoangles(proj.velocity);
-    proj.touch              = turret_flac_projectile_explode;
-    proj.think              = turret_flac_projectile_explode;
-    //proj.nextthink          = time + vlen(self.tur_shotorg - self.enemy.origin) / self.shot_speed;
-    proj.nextthink          = time + max(self.tur_impacttime,(self.shot_radius * 3) / self.shot_speed);
-    proj.enemy              = self.enemy;
-    proj.cnt                = time + 5;
-
-    CSQCProjectile(proj, TRUE, PROJECTILE_HAGAR, TRUE);
-
-    self.tur_head.frame = self.tur_head.frame + 1;
-    if (self.tur_head.frame >= 4) self.tur_head.frame = 0;
-
-}
-
-void turret_flac_projectile_explode()
-{
-    float ftmp;
-
-    // FIXME: tur_impacttime is not accurate enougth, this is a dirty hakk to make flac work.
-
-    //w_deathtypestring = "got caught in the flack.";
-
-
-
-    if( (self.enemy != world) &&
-        (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 3) )
-    {
-        // OMG HAXX!
-        setorigin(self,self.enemy.origin + randomvec() * self.owner.shot_radius);
-    }
-
-
-
-    te_explosion (self.origin);
-
-    ftmp = crandom();
-    if (ftmp<-0.7)
-        sound (self, CHAN_PROJECTILE, "weapons/hagexp1.wav", VOL_BASE, ATTN_NORM);
-    else if (ftmp<0.4)
-        sound (self, CHAN_PROJECTILE, "weapons/hagexp2.wav", VOL_BASE, ATTN_NORM);
-    else if (ftmp<1)
-        sound (self, CHAN_PROJECTILE, "weapons/hagexp3.wav", VOL_BASE, ATTN_NORM);
-
-
-    self.event_damage = SUB_Null;
-
-
-#ifdef TURRET_DEBUG
-    ftmp = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + ftmp; //self.owner.shot_dmg;
-    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#else
-    RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg * 0.5, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-#endif
-
-    remove (self);
-}
-
-
-void turret_flac_dinit()
-{
-    if (self.netname == "")      self.netname  = "FLAC Cannon";
-
-
-    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_MISSILEKILL;
-    self.ammo_flags     = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-    self.aim_flags      = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
-
-    if (turret_stdproc_init("flac_std",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    self.damage_flags |= TFL_DMG_HEADSHAKE;
-    self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS;
-
-    setmodel(self,"models/turrets/base.md3");
-    setmodel(self.tur_head,"models/turrets/flac.md3");
-
-    if (!turret_tag_setup())
-        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
-    // Our fire routine
-    self.turret_firefunc  = turret_flac_attack;
-
-}
-/*QUAKED turret_flac (0 .5 .8) ?
-*/
-
-void spawnfunc_turret_flac()
-{
-    precache_model ("models/turrets/base.md3");
-    precache_model ("models/turrets/flac.md3");
-    //precache_model("models/turrets/pd_proj.md3");
-
-    self.think = turret_flac_dinit;
-    self.nextthink = time + 0.5;
-}
-
+void spawnfunc_turret_flac();
+void turret_flac_dinit();
+void turret_flac_attack();
+void turret_flac_projectile_explode();
+
+void turret_flac_attack()
+{
+    local entity proj;
+
+    turret_tag_fire_update();
+
+    sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
+    proj = spawn ();
+    setorigin(proj, self.tur_shotorg);
+    // setmodel(proj, "models/turrets/pd_proj.md3");
+    setsize(proj, '0 0 0', '0 0 0');
+    proj.classname          = "flac_projectile";
+    proj.owner              = self;
+    proj.bot_dodge          = TRUE;
+    proj.bot_dodgerating    = self.shot_dmg;
+    proj.solid              = SOLID_BBOX;
+    proj.movetype           = MOVETYPE_FLYMISSILE;
+    proj.flags              = FL_PROJECTILE;
+    // proj.effects            = EF_LOWPRECISION;
+    proj.takedamage         = DAMAGE_NO;
+    //proj.health             =  100;
+    proj.velocity           = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+    proj.angles             = vectoangles(proj.velocity);
+    proj.touch              = turret_flac_projectile_explode;
+    proj.think              = turret_flac_projectile_explode;
+    //proj.nextthink          = time + vlen(self.tur_shotorg - self.enemy.origin) / self.shot_speed;
+    proj.nextthink          = time + max(self.tur_impacttime,(self.shot_radius * 3) / self.shot_speed);
+    proj.enemy              = self.enemy;
+    proj.cnt                = time + 5;
+
+    CSQCProjectile(proj, TRUE, PROJECTILE_HAGAR, TRUE);
+
+    self.tur_head.frame = self.tur_head.frame + 1;
+    if (self.tur_head.frame >= 4) self.tur_head.frame = 0;
+
+}
+
+void turret_flac_projectile_explode()
+{
+    float ftmp;
+
+    // FIXME: tur_impacttime is not accurate enougth, this is a dirty hakk to make flac work.
+
+    //w_deathtypestring = "got caught in the flack.";
+
+
+
+    if( (self.enemy != world) &&
+        (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 3) )
+    {
+        // OMG HAXX!
+        setorigin(self,self.enemy.origin + randomvec() * self.owner.shot_radius);
+    }
+
+
+
+    te_explosion (self.origin);
+
+    ftmp = crandom();
+    if (ftmp<-0.7)
+        sound (self, CHAN_PROJECTILE, "weapons/hagexp1.wav", VOL_BASE, ATTN_NORM);
+    else if (ftmp<0.4)
+        sound (self, CHAN_PROJECTILE, "weapons/hagexp2.wav", VOL_BASE, ATTN_NORM);
+    else if (ftmp<1)
+        sound (self, CHAN_PROJECTILE, "weapons/hagexp3.wav", VOL_BASE, ATTN_NORM);
+
+
+    self.event_damage = SUB_Null;
+
+
+#ifdef TURRET_DEBUG
+    ftmp = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + ftmp; //self.owner.shot_dmg;
+    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#else
+    RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg * 0.5, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+#endif
+
+    remove (self);
+}
+
+
+void turret_flac_dinit()
+{
+    if (self.netname == "")      self.netname  = "FLAC Cannon";
+
+
+    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_MISSILEKILL;
+    self.ammo_flags     = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+    self.aim_flags      = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE;
+
+    if (turret_stdproc_init("flac_std",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    self.damage_flags |= TFL_DMG_HEADSHAKE;
+    self.target_select_flags |= TFL_TARGETSELECT_NOTURRETS;
+
+    setmodel(self,"models/turrets/base.md3");
+    setmodel(self.tur_head,"models/turrets/flac.md3");
+
+    if (!turret_tag_setup())
+        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+    // Our fire routine
+    self.turret_firefunc  = turret_flac_attack;
+
+}
+/*QUAKED turret_flac (0 .5 .8) ?
+*/
+
+void spawnfunc_turret_flac()
+{
+    precache_model ("models/turrets/base.md3");
+    precache_model ("models/turrets/flac.md3");
+    //precache_model("models/turrets/pd_proj.md3");
+
+    self.think = turret_flac_dinit;
+    self.nextthink = time + 0.5;
+}
+


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_flac.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,83 +1,83 @@
-void spawnfunc_turret_fusionreactor();
-void turret_fusionreactor_dinit();
-void turret_fusionreactor_fire();
-
-float turret_fusionreactor_firecheck()
-{
-    if (self.enemy == world) return 0;
-
-    if (!self.enemy.ammo_flags & TFL_AMMO_RECIVE) return 0;
-    if (!self.enemy.ammo_flags & TFL_AMMO_ENERGY) return 0;
-
-    if (self.ammo < self.shot_dmg) return 0;
-    if (self.enemy.ammo >= self.enemy.ammo_max) return 0;
-    if (self.tur_dist_aimpos > self.target_range) return 0;
-    if (self.tur_dist_aimpos < self.target_range_min) return 0;
-
-    return 1;
-}
-
-
-void turret_fusionreactor_fire()
-{
-    self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
-    //te_lightning1(world,self.origin,self.enemy.origin);
-}
-
-void turret_fusionreactor_postthink()
-{
-}
-
-void turret_fusionreactor_respawnhook()
-{
-    self.tur_head.avelocity = '0 50 0';
-}
-
-void turret_fusionreactor_dinit()
-{
-    if (self.netname == "")      self.netname     = "Fusionreactor";
-
-    self.turrcaps_flags = TFL_TURRCAPS_SUPPORT | TFL_TURRCAPS_AMMOSOURCE;
-
-    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
-
-    self.target_select_flags = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMTS;
-
-    self.firecheck_flags = TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_OTHER_AMMO | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_WORLD;
-
-    self.shoot_flags = TFL_SHOOT_HITALLVALID;
-    self.aim_flags = TFL_AIM_NO;
-    self.track_flags = TFL_TRACK_NO;
-    self.turret_respawnhook = turret_fusionreactor_respawnhook;
-    if (turret_stdproc_init("fusreac_std",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    setmodel(self,"models/turrets/base.md3");
-    setmodel(self.tur_head,"models/turrets/reactor.md3");
-
-    //if(!turret_tag_setup())
-    //    dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
-    self.tur_head.scale = 0.75;
-    setorigin(self.tur_head,self.origin + '0 0 25');
-    self.tur_head.avelocity = '0 50 0';
-
-    self.turret_firecheckfunc = turret_fusionreactor_firecheck;
-    self.turret_firefunc = turret_fusionreactor_fire;
-
-    self.turret_postthink = turret_fusionreactor_postthink;
-}
-
-/*QUAKED turret_fusionreactor (0 .5 .8) ?
-*/
-void spawnfunc_turret_fusionreactor()
-{
-    precache_model ("models/turrets/reactor.md3");
-    precache_model ("models/turrets/base.md3");
-
-    self.think = turret_fusionreactor_dinit;
-    self.nextthink = time + 0.5;
-}
+void spawnfunc_turret_fusionreactor();
+void turret_fusionreactor_dinit();
+void turret_fusionreactor_fire();
+
+float turret_fusionreactor_firecheck()
+{
+    if (self.enemy == world) return 0;
+
+    if (!self.enemy.ammo_flags & TFL_AMMO_RECIVE) return 0;
+    if (!self.enemy.ammo_flags & TFL_AMMO_ENERGY) return 0;
+
+    if (self.ammo < self.shot_dmg) return 0;
+    if (self.enemy.ammo >= self.enemy.ammo_max) return 0;
+    if (self.tur_dist_aimpos > self.target_range) return 0;
+    if (self.tur_dist_aimpos < self.target_range_min) return 0;
+
+    return 1;
+}
+
+
+void turret_fusionreactor_fire()
+{
+    self.enemy.ammo = min(self.enemy.ammo + self.shot_dmg,self.enemy.ammo_max);
+    //te_lightning1(world,self.origin,self.enemy.origin);
+}
+
+void turret_fusionreactor_postthink()
+{
+}
+
+void turret_fusionreactor_respawnhook()
+{
+    self.tur_head.avelocity = '0 50 0';
+}
+
+void turret_fusionreactor_dinit()
+{
+    if (self.netname == "")      self.netname     = "Fusionreactor";
+
+    self.turrcaps_flags = TFL_TURRCAPS_SUPPORT | TFL_TURRCAPS_AMMOSOURCE;
+
+    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE;
+
+    self.target_select_flags = TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_OWNTEAM | TFL_TARGETSELECT_RANGELIMTS;
+
+    self.firecheck_flags = TFL_FIRECHECK_OWM_AMMO | TFL_FIRECHECK_OTHER_AMMO | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_WORLD;
+
+    self.shoot_flags = TFL_SHOOT_HITALLVALID;
+    self.aim_flags = TFL_AIM_NO;
+    self.track_flags = TFL_TRACK_NO;
+    self.turret_respawnhook = turret_fusionreactor_respawnhook;
+    if (turret_stdproc_init("fusreac_std",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    setmodel(self,"models/turrets/base.md3");
+    setmodel(self.tur_head,"models/turrets/reactor.md3");
+
+    //if(!turret_tag_setup())
+    //    dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+    self.tur_head.scale = 0.75;
+    setorigin(self.tur_head,self.origin + '0 0 25');
+    self.tur_head.avelocity = '0 50 0';
+
+    self.turret_firecheckfunc = turret_fusionreactor_firecheck;
+    self.turret_firefunc = turret_fusionreactor_fire;
+
+    self.turret_postthink = turret_fusionreactor_postthink;
+}
+
+/*QUAKED turret_fusionreactor (0 .5 .8) ?
+*/
+void spawnfunc_turret_fusionreactor()
+{
+    precache_model ("models/turrets/reactor.md3");
+    precache_model ("models/turrets/base.md3");
+
+    self.think = turret_fusionreactor_dinit;
+    self.nextthink = time + 0.5;
+}


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_fusionreactor.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_hellion.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_hellion.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_hellion.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,222 +1,222 @@
-.float      shot_speed_max;
-.float      shot_speed_gain;
-
-void spawnfunc_turret_hellion();
-void turret_hellion_dinit();
-void turret_hellion_attack();
-void turret_hellion_missile_explode();
-void turret_hellion_missile_think();
-void turret_hellion_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
-
-void turret_hellion_postthink()
-{
-    if (cvar("g_turrets_reloadcvars"))
-    {
-        if (!self.shot_speed_max)  self.shot_speed_max  = cvar("g_turrets_unit_hellion_std_shot_speed_max");
-        if (!self.shot_speed_gain) self.shot_speed_gain = cvar("g_turrets_unit_hellion_std_shot_speed_gain");
-    }
-
-    if (self.tur_head.frame != 0)
-        self.tur_head.frame = self.tur_head.frame + 1;
-
-    if (self.tur_head.frame > 7)
-        self.tur_head.frame = 0;
-}
-
-void turret_hellion_attack()
-{
-    local entity missile;
-
-    sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
-
-    missile = spawn ();
-    setorigin(missile, self.tur_shotorg);
-    setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-
-    missile.classname          = "hellion_missile";
-    missile.owner              = self;
-    missile.bot_dodge          = TRUE;
-    missile.bot_dodgerating    = self.shot_dmg;
-    missile.takedamage         = DAMAGE_YES;
-    missile.event_damage       = turret_hellion_missile_damage;
-    missile.damageforcescale   = 2;
-    missile.health             = 10;
-    missile.enemy              = self.enemy;
-    missile.think              = turret_hellion_missile_think;
-    missile.nextthink          = time;// + 0.2;
-    missile.solid              = SOLID_BBOX;
-    missile.movetype           = MOVETYPE_FLY;
-    missile.velocity           = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
-    missile.angles             = vectoangles(missile.velocity);
-    missile.touch              = turret_hellion_missile_explode;
-    missile.flags              = FL_PROJECTILE;
-    missile.solid              = SOLID_BBOX;
-    missile.tur_health         = time + 9;
-    missile.tur_aimpos         = randomvec() * 128;
-    te_explosion (missile.origin);
-
-	CSQCProjectile(missile, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
-
-    // switch tubes
-    self.tur_shotorg_y = self.tur_shotorg_y * -1;
-
-    if (self.tur_head.frame == 0)
-        self.tur_head.frame = self.tur_head.frame + 1;
-
-}
-
-void turret_hellion_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
-{
-    self.health = self.health - damage;
-    self.velocity = self.velocity + vforce;
-    if (self.health <= 0) turret_hellion_missile_explode();
-}
-
-void turret_hellion_missile_think()
-{
-    vector olddir,newdir;
-    vector pre_pos;
-    float itime;
-
-    self.nextthink = time + 0.05;
-
-    olddir = normalize(self.velocity);
-
-    if(self.tur_health < time)
-        turret_hellion_missile_explode();
-
-    // Enemy dead? just keep on the current heading then.
-    if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
-    {
-
-        // Make sure we dont return to tracking a respawned player
-        self.enemy = world;
-
-        // Turn model
-        self.angles = vectoangles(self.velocity);
-
-        if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 5) )
-            turret_hellion_missile_explode();
-
-        // Accelerate
-        self.velocity = olddir * min(vlen(self.velocity) * self.owner.shot_speed_gain,self.owner.shot_speed_max);
-
-        UpdateCSQCProjectile(self);
-
-        return;
-    }
-
-    // Enemy in range?
-    if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.2)
-        turret_hellion_missile_explode();
-
-    // Predict enemy position
-    itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
-    pre_pos = self.enemy.origin + self.enemy.velocity * itime;
-
-    pre_pos = (pre_pos + self.enemy.origin) * 0.5;
-
-    //pre_pos += randomvec() * 128; //self.tur_aimpos * (sin(32) * time) ;
-
-    // Find out the direction to that place
-    newdir = normalize(pre_pos - self.origin);
-
-    // Turn
-    newdir = normalize(olddir + newdir * 0.35);
-
-    // Turn model
-    self.angles = vectoangles(self.velocity);
-
-    // Accelerate
-    self.velocity = newdir * min(vlen(self.velocity) * self.owner.shot_speed_gain,self.owner.shot_speed_max);
-
-    if (itime < 0.05)
-        self.think = turret_hellion_missile_explode;
-
-    UpdateCSQCProjectile(self);
-}
-
-void turret_hellion_missile_explode()
-{
-    vector org2;
-    float d;
-
-    if(self.event_damage != SUB_Null)
-    {
-        self.event_damage = SUB_Null;
-        self.think = turret_hellion_missile_explode;
-        self.nextthink = time;
-        return;
-    }
-
-    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
-    org2 = findbetterlocation (self.origin, 16);
-
-    // LordHavoc: TE_TEI_BIGEXPLOSION
-    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
-    WriteByte (MSG_BROADCAST, 78);
-    WriteCoord (MSG_BROADCAST, org2_x);
-    WriteCoord (MSG_BROADCAST, org2_y);
-    WriteCoord (MSG_BROADCAST, org2_z);
-
-    //w_deathtypestring = "could not dodge the twin missiles.";
-    self.event_damage = SUB_Null;
-    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-
-#ifdef TURRET_DEBUG
-    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
-    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#endif
-
-    // Target dead, get another is still targeting the same.
-    if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
-        self.owner.enemy = world;
-
-    remove (self);
-}
-
-void turret_hellion_dinit()
-{
-    if (self.netname == "")      self.netname  = "Hellion Missile Turret";
-
-    if (!self.shot_speed_max)  self.shot_speed_max  = cvar("g_turrets_unit_hellion_std_shot_speed_max");
-    if (!self.shot_speed_gain) self.shot_speed_gain = cvar("g_turrets_unit_hellion_std_shot_speed_gain");
-
-    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
-    self.aim_flags = TFL_AIM_SIMPLE;
-    self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK ;
-    self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_OWM_AMMO;
-    self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-
-    if (turret_stdproc_init("hellion_std",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    setmodel(self,"models/turrets/base.md3");
-    setmodel(self.tur_head,"models/turrets/hellion.md3");
-
-    if (!turret_tag_setup())
-        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
-    // Our fire routine
-    self.turret_firefunc  = turret_hellion_attack;
-
-    // Custom animations and sutch
-    self.turret_postthink = turret_hellion_postthink;
-}
-
-/*QUAKED turret_hellion (0 .5 .8) ?
-*/
-void spawnfunc_turret_hellion()
-{
-    //precache_model ( "models/turrets/mlrs_rocket.md3");
-    precache_model ("models/turrets/hellion.md3");
-    precache_model ("models/turrets/base.md3");
-
-    self.think = turret_hellion_dinit;
-    self.nextthink = time + 0.5;
-}
-
-
+.float      shot_speed_max;
+.float      shot_speed_gain;
+
+void spawnfunc_turret_hellion();
+void turret_hellion_dinit();
+void turret_hellion_attack();
+void turret_hellion_missile_explode();
+void turret_hellion_missile_think();
+void turret_hellion_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+
+void turret_hellion_postthink()
+{
+    if (cvar("g_turrets_reloadcvars"))
+    {
+        if (!self.shot_speed_max)  self.shot_speed_max  = cvar("g_turrets_unit_hellion_std_shot_speed_max");
+        if (!self.shot_speed_gain) self.shot_speed_gain = cvar("g_turrets_unit_hellion_std_shot_speed_gain");
+    }
+
+    if (self.tur_head.frame != 0)
+        self.tur_head.frame = self.tur_head.frame + 1;
+
+    if (self.tur_head.frame > 7)
+        self.tur_head.frame = 0;
+}
+
+void turret_hellion_attack()
+{
+    local entity missile;
+
+    sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
+
+    missile = spawn ();
+    setorigin(missile, self.tur_shotorg);
+    setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
+
+    missile.classname          = "hellion_missile";
+    missile.owner              = self;
+    missile.bot_dodge          = TRUE;
+    missile.bot_dodgerating    = self.shot_dmg;
+    missile.takedamage         = DAMAGE_YES;
+    missile.event_damage       = turret_hellion_missile_damage;
+    missile.damageforcescale   = 2;
+    missile.health             = 10;
+    missile.enemy              = self.enemy;
+    missile.think              = turret_hellion_missile_think;
+    missile.nextthink          = time;// + 0.2;
+    missile.solid              = SOLID_BBOX;
+    missile.movetype           = MOVETYPE_FLY;
+    missile.velocity           = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+    missile.angles             = vectoangles(missile.velocity);
+    missile.touch              = turret_hellion_missile_explode;
+    missile.flags              = FL_PROJECTILE;
+    missile.solid              = SOLID_BBOX;
+    missile.tur_health         = time + 9;
+    missile.tur_aimpos         = randomvec() * 128;
+    te_explosion (missile.origin);
+
+	CSQCProjectile(missile, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
+
+    // switch tubes
+    self.tur_shotorg_y = self.tur_shotorg_y * -1;
+
+    if (self.tur_head.frame == 0)
+        self.tur_head.frame = self.tur_head.frame + 1;
+
+}
+
+void turret_hellion_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+{
+    self.health = self.health - damage;
+    self.velocity = self.velocity + vforce;
+    if (self.health <= 0) turret_hellion_missile_explode();
+}
+
+void turret_hellion_missile_think()
+{
+    vector olddir,newdir;
+    vector pre_pos;
+    float itime;
+
+    self.nextthink = time + 0.05;
+
+    olddir = normalize(self.velocity);
+
+    if(self.tur_health < time)
+        turret_hellion_missile_explode();
+
+    // Enemy dead? just keep on the current heading then.
+    if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
+    {
+
+        // Make sure we dont return to tracking a respawned player
+        self.enemy = world;
+
+        // Turn model
+        self.angles = vectoangles(self.velocity);
+
+        if ( (vlen(self.origin - self.owner.origin)) > (self.owner.shot_radius * 5) )
+            turret_hellion_missile_explode();
+
+        // Accelerate
+        self.velocity = olddir * min(vlen(self.velocity) * self.owner.shot_speed_gain,self.owner.shot_speed_max);
+
+        UpdateCSQCProjectile(self);
+
+        return;
+    }
+
+    // Enemy in range?
+    if (vlen(self.origin - self.enemy.origin) < self.owner.shot_radius * 0.2)
+        turret_hellion_missile_explode();
+
+    // Predict enemy position
+    itime = vlen(self.enemy.origin - self.origin) / vlen(self.velocity);
+    pre_pos = self.enemy.origin + self.enemy.velocity * itime;
+
+    pre_pos = (pre_pos + self.enemy.origin) * 0.5;
+
+    //pre_pos += randomvec() * 128; //self.tur_aimpos * (sin(32) * time) ;
+
+    // Find out the direction to that place
+    newdir = normalize(pre_pos - self.origin);
+
+    // Turn
+    newdir = normalize(olddir + newdir * 0.35);
+
+    // Turn model
+    self.angles = vectoangles(self.velocity);
+
+    // Accelerate
+    self.velocity = newdir * min(vlen(self.velocity) * self.owner.shot_speed_gain,self.owner.shot_speed_max);
+
+    if (itime < 0.05)
+        self.think = turret_hellion_missile_explode;
+
+    UpdateCSQCProjectile(self);
+}
+
+void turret_hellion_missile_explode()
+{
+    vector org2;
+    float d;
+
+    if(self.event_damage != SUB_Null)
+    {
+        self.event_damage = SUB_Null;
+        self.think = turret_hellion_missile_explode;
+        self.nextthink = time;
+        return;
+    }
+
+    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+    org2 = findbetterlocation (self.origin, 16);
+
+    // LordHavoc: TE_TEI_BIGEXPLOSION
+    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+    WriteByte (MSG_BROADCAST, 78);
+    WriteCoord (MSG_BROADCAST, org2_x);
+    WriteCoord (MSG_BROADCAST, org2_y);
+    WriteCoord (MSG_BROADCAST, org2_z);
+
+    //w_deathtypestring = "could not dodge the twin missiles.";
+    self.event_damage = SUB_Null;
+    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+
+#ifdef TURRET_DEBUG
+    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
+    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#endif
+
+    // Target dead, get another is still targeting the same.
+    if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
+        self.owner.enemy = world;
+
+    remove (self);
+}
+
+void turret_hellion_dinit()
+{
+    if (self.netname == "")      self.netname  = "Hellion Missile Turret";
+
+    if (!self.shot_speed_max)  self.shot_speed_max  = cvar("g_turrets_unit_hellion_std_shot_speed_max");
+    if (!self.shot_speed_gain) self.shot_speed_gain = cvar("g_turrets_unit_hellion_std_shot_speed_gain");
+
+    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_FASTPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
+    self.aim_flags = TFL_AIM_SIMPLE;
+    self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK ;
+    self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_DISTANCES | TFL_FIRECHECK_TEAMCECK | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF | TFL_FIRECHECK_OWM_AMMO;
+    self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+
+    if (turret_stdproc_init("hellion_std",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    setmodel(self,"models/turrets/base.md3");
+    setmodel(self.tur_head,"models/turrets/hellion.md3");
+
+    if (!turret_tag_setup())
+        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+    // Our fire routine
+    self.turret_firefunc  = turret_hellion_attack;
+
+    // Custom animations and sutch
+    self.turret_postthink = turret_hellion_postthink;
+}
+
+/*QUAKED turret_hellion (0 .5 .8) ?
+*/
+void spawnfunc_turret_hellion()
+{
+    //precache_model ( "models/turrets/mlrs_rocket.md3");
+    precache_model ("models/turrets/hellion.md3");
+    precache_model ("models/turrets/base.md3");
+
+    self.think = turret_hellion_dinit;
+    self.nextthink = time + 0.5;
+}
+
+


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_hellion.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_hk.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_hk.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_hk.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,480 +1,480 @@
-//#define TURRET_DEBUG_HK
-
-#ifdef TURRET_DEBUG_HK
-.float atime;
-#endif
-
-void spawnfunc_turret_hk();
-void turret_hk_dinit();
-void turret_hk_attack();
-void turret_hk_missile_explode();
-void turret_hk_missile_think();
-void turret_hk_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
-float turret_hk_addtarget(entity e_target,entity e_sender);
-//void turret_hk_missile_touch();
-
-float hk_maxspeed;
-float hk_minspeed;
-float hk_accel;
-float hk_accel2;
-float hk_decel;
-
-float turret_hk_addtarget(entity e_target,entity e_sender)
-{
-    if (e_target)
-    {
-        if (turret_validate_target(self,e_target,self.target_validate_flags) > 0)
-        {
-            self.enemy = e_target;
-            return 1;
-        }
-    }
-
-    return 0;
-}
-
-float hk_is_valid_target(entity e_target)
-{
-    if (e_target == world)
-        return 0;
-
-    // If only this was used more..
-    if (e_target.flags & FL_NOTARGET)
-        return 0;
-
-    // Cant touch this
-    if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
-        return 0;
-
-    // player
-    if (e_target.flags & FL_CLIENT)
-    {
-        if (self.owner.target_select_playerbias < 0)
-            return 0;
-
-        if (e_target.deadflag != DEAD_NO)
-            return 0;
-    }
-
-    // Missile
-    if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
-        return 0;
-
-    // Team check
-    if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
-        return 0;
-
-    return 1;
-}
-
-void turret_hk_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
-{
-    if (attacker.team == self.team)
-        damage *= 0.5;
-
-    self.velocity += force;
-
-    self.health -= damage;
-
-    if (self.health <= 0)
-        turret_hk_missile_explode();
-}
-
-void turret_hk_attack()
-{
-    local entity missile;
-    //local entity flash2;
-
-    sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", VOL_BASE, ATTN_NORM);
-
-    missile                    = spawn ();
-    missile.solid            = SOLID_BBOX;
-    setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-    setorigin(missile, self.tur_shotorg);
-
-    missile.scale            = 1;
-    missile.classname        = "hk_missile";
-    missile.owner            = self;
-    missile.bot_dodge        = TRUE;
-    missile.bot_dodgerating  = self.shot_dmg;
-    missile.takedamage       = DAMAGE_YES;
-    missile.damageforcescale = 4;
-    missile.health           = 10;
-    missile.think            = turret_hk_missile_think;
-    missile.event_damage     = turret_hk_missile_damage;
-    missile.nextthink        = time + 0.25;
-    missile.movetype         = MOVETYPE_BOUNCEMISSILE;
-    missile.velocity         = self.tur_shotdir_updated * (self.shot_speed * 0.75);
-    missile.angles           = vectoangles(missile.velocity);
-    missile.touch            = turret_hk_missile_explode; //turret_hk_missile_touch;
-    missile.flags            = FL_PROJECTILE;
-    missile.enemy            = self.enemy;
-    missile.team             = self.team;
-    missile.cnt              = time + 30;
-    missile.ticrate          = max(cvar("sys_ticrate"),0.05);
-
-	CSQCProjectile(missile, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, fly sound
-
-    te_explosion (missile.origin);
-
-    if (self.tur_head.frame == 0)
-        self.tur_head.frame = self.tur_head.frame + 1;
-
-}
-
-/*
-void turret_hk_missile_touch()
-{
-    if(other == self.enemy)
-        turret_hk_missile_explode();
-    else
-    {
-        if(self.cnt < time)
-        {
-            self.cnt = time + 0.25;
-            self.health = self.health - 5;
-            if(self.health <= 0)
-                turret_hk_missile_explode();
-
-        }
-    }
-}
-*/
-
-void turret_hk_missile_think()
-{
-    vector vu, vd, vf, vl, vr, ve;  // Vector (direction)
-    float  fu, fd, ff, fl, fr, fe;  // Fraction to solid
-    vector olddir,wishdir,newdir;   // Final direction
-    float lt_for;   // Length of Trace FORwrad
-    float lt_seek;  // Length of Trace SEEK (left, right, up down)
-    float pt_seek;  // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward)
-    vector pre_pos;
-    float myspeed;
-    entity e;
-    float ad,edist;
-
-    self.nextthink = time + self.ticrate;
-
-    //if (self.cnt < time)
-    //    turret_hk_missile_explode();
-
-    if (self.enemy.deadflag != DEAD_NO)
-        self.enemy = world;
-
-    // Pick the closest valid target.
-    if (!self.enemy)
-    {
-        e = findradius(self.origin, 5000);
-        while (e)
-        {
-            if (hk_is_valid_target(e))
-            {
-                if (!self.enemy)
-                    self.enemy = e;
-                else
-                    if (vlen(self.origin - e.origin) < vlen(self.origin - self.enemy.origin))
-                        self.enemy = e;
-            }
-            e = e.chain;
-        }
-    }
-
-    self.angles = vectoangles(self.velocity);
-    self.angles_x = self.angles_x * -1;
-    makevectors(self.angles);
-    self.angles_x = self.angles_x * -1;
-
-    if (self.enemy)
-    {
-        edist = vlen(self.origin - self.enemy.origin);
-        // Close enougth to do decent damage?
-        if ( edist <= (self.owner.shot_radius * 0.25) )
-        {
-            turret_hk_missile_explode();
-            return;
-        }
-
-        // Get data on enemy position
-        pre_pos = self.enemy.origin +
-                  self.enemy.velocity *
-                  min((vlen(self.enemy.origin - self.origin) / vlen(self.velocity)),0.5);
-
-        traceline(self.origin, pre_pos,TRUE,self.enemy);
-        ve = normalize(pre_pos - self.origin);
-        fe = trace_fraction;
-
-    }
-    else
-    {
-        fe = 0;
-    }
-
-    if ((fe != 1) || (self.enemy == world) || (edist > 1000))
-    {
-        myspeed = vlen(self.velocity);
-
-        lt_for  = myspeed * 3;
-        lt_seek = myspeed * 2.95;
-
-        // Trace forward
-        traceline(self.origin, self.origin + v_forward * lt_for,FALSE,self);
-        vf = trace_endpos;
-        ff = trace_fraction;
-
-        // Find angular offset
-        ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles);
-
-        // To close to something, Slow down!
-        if ( ((ff < 0.7) || (ad > 4)) && (myspeed > hk_minspeed) )
-            myspeed = max(myspeed * hk_decel,hk_minspeed);
-
-        // Failry clear, accelerate.
-        if ( (ff > 0.7) && (myspeed < hk_maxspeed) )
-            myspeed = min(myspeed * hk_accel,hk_maxspeed);
-
-        // Setup trace pitch
-        pt_seek = 1 - ff;
-        pt_seek = bound(0.15,pt_seek,0.8);
-        if (ff < 0.5) pt_seek = 1;
-
-        // Trace left
-        traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,FALSE,self);
-        vl = trace_endpos;
-        fl = trace_fraction;
-
-        // Trace right
-        traceline(self.origin,  self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
-        vr = trace_endpos;
-        fr = trace_fraction;
-
-        // Trace up
-        traceline(self.origin,  self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
-        vu = trace_endpos;
-        fu = trace_fraction;
-
-        // Trace down
-        traceline(self.origin,  self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
-        vd = trace_endpos;
-        fd = trace_fraction;
-
-        vl = normalize(vl - self.origin);
-        vr = normalize(vr - self.origin);
-        vu = normalize(vu - self.origin);
-        vd = normalize(vd - self.origin);
-
-        // Panic tresh passed, find a single direction and turn as hard as we can
-        if (pt_seek == 1)
-        {
-            wishdir = v_right;
-            if (fl > fr) wishdir = -1 * v_right;
-            if (fu > fl) wishdir = v_up;
-            if (fd > fu) wishdir = -1 * v_up;
-        }
-        else
-        {
-            // Normalize our trace vectors to make a smooth path
-            wishdir = normalize( (vl * fl) + (vr * fr) +  (vu * fu) +  (vd * fd) );
-        }
-
-        if (self.enemy)
-        {
-            if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target
-            wishdir = (wishdir * (1 - fe)) + (ve * fe);
-        }
-    }
-    else
-    {
-        // Got a clear path to target, speed up fast (if not at full speed) and go straight for it.
-        myspeed = vlen(self.velocity);
-        if (myspeed < hk_maxspeed)
-            myspeed = min(myspeed * hk_accel2,hk_maxspeed);
-
-        wishdir = ve;
-        //wishdir = normalize(self.enemy.origin - (self.enemy.origin + self.enemy.velocity));
-    }
-
-    if ((myspeed > hk_minspeed) && (self.cnt > time))
-        myspeed = min(myspeed * hk_accel2,hk_maxspeed);
-
-    // Ranoutagazfish?
-    if (self.cnt < time)
-    {
-        self.cnt = time + 0.25;
-        self.nextthink = 0;
-        self.movetype         = MOVETYPE_BOUNCE;
-        sound    (self, CHAN_VOICE, "", 0.4 * VOL_BASE, ATTN_NORM);
-        return;
-    }
-
-    // Calculate new heading
-    olddir = normalize(self.velocity);
-
-    newdir = normalize(olddir + wishdir * cvar("g_turrets_unit_hk_std_shot_speed_turnrate"));
-
-    //fu = (1 / hk_maxspeed) * myspeed;
-    //fd = fu - (0.75 - 0.25);
-    //newdir = normalize(olddir + wishdir * fd);
-
-    // Set heading & speed
-    self.velocity = newdir * myspeed;
-
-    // Align model with new heading
-    self.angles = vectoangles(self.velocity);
-
-
-#ifdef TURRET_DEBUG_HK
-    //if(self.atime < time) {
-    if ((fe <= 0.99)||(edist > 1000))
-    {
-        te_lightning2(world,self.origin, self.origin + vr * lt_seek);
-        te_lightning2(world,self.origin, self.origin + vl * lt_seek);
-        te_lightning2(world,self.origin, self.origin + vu * lt_seek);
-        te_lightning2(world,self.origin, self.origin + vd * lt_seek);
-        te_lightning2(world,self.origin, vf);
-    }
-    else
-    {
-        te_lightning2(world,self.origin, self.enemy.origin);
-    }
-    bprint("Speed: ", ftos(rint(myspeed)), "\n");
-    bprint("Trace to solid: ", ftos(rint(ff * 100)), "%\n");
-    bprint("Trace to target:", ftos(rint(fe * 100)), "%\n");
-    self.atime = time + 0.2;
-    //}
-#endif
-
-	UpdateCSQCProjectile(self);
-}
-
-void turret_hk_missile_explode()
-{
-    vector org2;
-    float d;
-
-    if(self.event_damage != SUB_Null)
-    {
-        self.event_damage = SUB_Null;
-        self.think = turret_hk_missile_explode;
-        self.nextthink = time;
-        return;
-    }
-
-    if ((other == self.owner)||(other == self.owner.tur_head))
-        return;
-
-    //w_deathtypestring = "got hunted to extinction";
-    //vector	org2;
-    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
-    org2 = findbetterlocation (self.origin, 16);
-
-    // LordHavoc: TE_TEI_BIGEXPLOSION
-    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
-    WriteByte (MSG_BROADCAST, 78);
-    WriteCoord (MSG_BROADCAST, org2_x);
-    WriteCoord (MSG_BROADCAST, org2_y);
-    WriteCoord (MSG_BROADCAST, org2_z);
-
-    self.event_damage = SUB_Null;
-    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-
-#ifdef TURRET_DEBUG
-    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
-    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#endif
-
-    // Target dead, get another is still targeting the same.
-    if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
-        self.owner.enemy = world;
-
-    remove (self);
-}
-
-void turret_hk_postthink()
-{
-    if (cvar("g_turrets_reloadcvars"))
-    {
-        hk_maxspeed = cvar("g_turrets_unit_hk_std_shot_speed_max");
-        hk_minspeed = cvar("g_turrets_unit_hk_std_shot_speed");
-        hk_accel    = cvar("g_turrets_unit_hk_std_shot_speed_accel");
-        hk_accel2   = cvar("g_turrets_unit_hk_std_shot_speed_accel2");
-        hk_decel    = cvar("g_turrets_unit_hk_std_shot_speed_decel");
-    }
-
-    if (self.tur_head.frame != 0)
-        self.tur_head.frame = self.tur_head.frame + 1;
-
-    if (self.tur_head.frame > 5)
-        self.tur_head.frame = 0;
-
-}
-
-void turret_hk_dinit()
-{
-    if (self.netname == "")      self.netname  = "Hunter-killer turret";
-
-    hk_maxspeed = cvar("g_turrets_unit_hk_std_shot_speed_max");
-    hk_minspeed = cvar("g_turrets_unit_hk_std_shot_speed");
-    hk_accel    = cvar("g_turrets_unit_hk_std_shot_speed_accel");
-    hk_accel2   = cvar("g_turrets_unit_hk_std_shot_speed_accel2");
-    hk_decel    = cvar("g_turrets_unit_hk_std_shot_speed_decel");
-
-    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_RECIVETARGETS;
-
-    self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-
-    self.aim_flags = TFL_AIM_SIMPLE;
-
-    self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
-
-    self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCECK  | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
-
-    self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
-
-    self.shoot_flags = TFL_SHOOT_CLEARTARGET;
-
-    if (turret_stdproc_init("hk_std",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
-
-    setmodel(self,"models/turrets/base.md3");
-    setmodel(self.tur_head,"models/turrets/hk.md3");
-
-    if (!turret_tag_setup())
-        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
-    // Our fire routine
-    self.turret_firefunc  = turret_hk_attack;
-
-    // re-color badge & handle recoil effect
-    self.turret_postthink = turret_hk_postthink;
-
-    // What to do when reciveing foreign target data
-    self.turret_addtarget = turret_hk_addtarget;
-}
-
-/*
-* Turret that fires Hunter-killer missiles.
-* Missiles seek their target and try to avoid obstacles. If target dies early, they
-* pick a new one on their own.
-*/
-
-/*QUAKED turret_hk (0 .5 .8) ?
-hunter-killer missiles.
-*/
-
-void spawnfunc_turret_hk()
-{
-    //precache_model ( "models/turrets/hunter2.md3");
-    precache_model ("models/turrets/base.md3");
-    precache_model ("models/turrets/hk.md3");
-
-    self.think = turret_hk_dinit;
-    self.nextthink = time + 0.5;
-}
-
-
+//#define TURRET_DEBUG_HK
+
+#ifdef TURRET_DEBUG_HK
+.float atime;
+#endif
+
+void spawnfunc_turret_hk();
+void turret_hk_dinit();
+void turret_hk_attack();
+void turret_hk_missile_explode();
+void turret_hk_missile_think();
+void turret_hk_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
+float turret_hk_addtarget(entity e_target,entity e_sender);
+//void turret_hk_missile_touch();
+
+float hk_maxspeed;
+float hk_minspeed;
+float hk_accel;
+float hk_accel2;
+float hk_decel;
+
+float turret_hk_addtarget(entity e_target,entity e_sender)
+{
+    if (e_target)
+    {
+        if (turret_validate_target(self,e_target,self.target_validate_flags) > 0)
+        {
+            self.enemy = e_target;
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
+float hk_is_valid_target(entity e_target)
+{
+    if (e_target == world)
+        return 0;
+
+    // If only this was used more..
+    if (e_target.flags & FL_NOTARGET)
+        return 0;
+
+    // Cant touch this
+    if ((e_target.takedamage == DAMAGE_NO) || (e_target.health < 0))
+        return 0;
+
+    // player
+    if (e_target.flags & FL_CLIENT)
+    {
+        if (self.owner.target_select_playerbias < 0)
+            return 0;
+
+        if (e_target.deadflag != DEAD_NO)
+            return 0;
+    }
+
+    // Missile
+    if ((e_target.flags & FL_PROJECTILE) && (self.owner.target_select_missilebias < 0))
+        return 0;
+
+    // Team check
+    if ((e_target.team == self.owner.team) || (self.owner.team == e_target.owner.team))
+        return 0;
+
+    return 1;
+}
+
+void turret_hk_missile_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+    if (attacker.team == self.team)
+        damage *= 0.5;
+
+    self.velocity += force;
+
+    self.health -= damage;
+
+    if (self.health <= 0)
+        turret_hk_missile_explode();
+}
+
+void turret_hk_attack()
+{
+    local entity missile;
+    //local entity flash2;
+
+    sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", VOL_BASE, ATTN_NORM);
+
+    missile                    = spawn ();
+    missile.solid            = SOLID_BBOX;
+    setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
+    setorigin(missile, self.tur_shotorg);
+
+    missile.scale            = 1;
+    missile.classname        = "hk_missile";
+    missile.owner            = self;
+    missile.bot_dodge        = TRUE;
+    missile.bot_dodgerating  = self.shot_dmg;
+    missile.takedamage       = DAMAGE_YES;
+    missile.damageforcescale = 4;
+    missile.health           = 10;
+    missile.think            = turret_hk_missile_think;
+    missile.event_damage     = turret_hk_missile_damage;
+    missile.nextthink        = time + 0.25;
+    missile.movetype         = MOVETYPE_BOUNCEMISSILE;
+    missile.velocity         = self.tur_shotdir_updated * (self.shot_speed * 0.75);
+    missile.angles           = vectoangles(missile.velocity);
+    missile.touch            = turret_hk_missile_explode; //turret_hk_missile_touch;
+    missile.flags            = FL_PROJECTILE;
+    missile.enemy            = self.enemy;
+    missile.team             = self.team;
+    missile.cnt              = time + 30;
+    missile.ticrate          = max(cvar("sys_ticrate"),0.05);
+
+	CSQCProjectile(missile, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, fly sound
+
+    te_explosion (missile.origin);
+
+    if (self.tur_head.frame == 0)
+        self.tur_head.frame = self.tur_head.frame + 1;
+
+}
+
+/*
+void turret_hk_missile_touch()
+{
+    if(other == self.enemy)
+        turret_hk_missile_explode();
+    else
+    {
+        if(self.cnt < time)
+        {
+            self.cnt = time + 0.25;
+            self.health = self.health - 5;
+            if(self.health <= 0)
+                turret_hk_missile_explode();
+
+        }
+    }
+}
+*/
+
+void turret_hk_missile_think()
+{
+    vector vu, vd, vf, vl, vr, ve;  // Vector (direction)
+    float  fu, fd, ff, fl, fr, fe;  // Fraction to solid
+    vector olddir,wishdir,newdir;   // Final direction
+    float lt_for;   // Length of Trace FORwrad
+    float lt_seek;  // Length of Trace SEEK (left, right, up down)
+    float pt_seek;  // Pitch of Trace SEEK (How mutch to angele left, right up, down trace towards v_forward)
+    vector pre_pos;
+    float myspeed;
+    entity e;
+    float ad,edist;
+
+    self.nextthink = time + self.ticrate;
+
+    //if (self.cnt < time)
+    //    turret_hk_missile_explode();
+
+    if (self.enemy.deadflag != DEAD_NO)
+        self.enemy = world;
+
+    // Pick the closest valid target.
+    if (!self.enemy)
+    {
+        e = findradius(self.origin, 5000);
+        while (e)
+        {
+            if (hk_is_valid_target(e))
+            {
+                if (!self.enemy)
+                    self.enemy = e;
+                else
+                    if (vlen(self.origin - e.origin) < vlen(self.origin - self.enemy.origin))
+                        self.enemy = e;
+            }
+            e = e.chain;
+        }
+    }
+
+    self.angles = vectoangles(self.velocity);
+    self.angles_x = self.angles_x * -1;
+    makevectors(self.angles);
+    self.angles_x = self.angles_x * -1;
+
+    if (self.enemy)
+    {
+        edist = vlen(self.origin - self.enemy.origin);
+        // Close enougth to do decent damage?
+        if ( edist <= (self.owner.shot_radius * 0.25) )
+        {
+            turret_hk_missile_explode();
+            return;
+        }
+
+        // Get data on enemy position
+        pre_pos = self.enemy.origin +
+                  self.enemy.velocity *
+                  min((vlen(self.enemy.origin - self.origin) / vlen(self.velocity)),0.5);
+
+        traceline(self.origin, pre_pos,TRUE,self.enemy);
+        ve = normalize(pre_pos - self.origin);
+        fe = trace_fraction;
+
+    }
+    else
+    {
+        fe = 0;
+    }
+
+    if ((fe != 1) || (self.enemy == world) || (edist > 1000))
+    {
+        myspeed = vlen(self.velocity);
+
+        lt_for  = myspeed * 3;
+        lt_seek = myspeed * 2.95;
+
+        // Trace forward
+        traceline(self.origin, self.origin + v_forward * lt_for,FALSE,self);
+        vf = trace_endpos;
+        ff = trace_fraction;
+
+        // Find angular offset
+        ad = vlen(vectoangles(normalize(self.enemy.origin - self.origin)) - self.angles);
+
+        // To close to something, Slow down!
+        if ( ((ff < 0.7) || (ad > 4)) && (myspeed > hk_minspeed) )
+            myspeed = max(myspeed * hk_decel,hk_minspeed);
+
+        // Failry clear, accelerate.
+        if ( (ff > 0.7) && (myspeed < hk_maxspeed) )
+            myspeed = min(myspeed * hk_accel,hk_maxspeed);
+
+        // Setup trace pitch
+        pt_seek = 1 - ff;
+        pt_seek = bound(0.15,pt_seek,0.8);
+        if (ff < 0.5) pt_seek = 1;
+
+        // Trace left
+        traceline(self.origin, self.origin + (-1 * (v_right * pt_seek) + (v_forward * ff)) * lt_seek,FALSE,self);
+        vl = trace_endpos;
+        fl = trace_fraction;
+
+        // Trace right
+        traceline(self.origin,  self.origin + ((v_right * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
+        vr = trace_endpos;
+        fr = trace_fraction;
+
+        // Trace up
+        traceline(self.origin,  self.origin + ((v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
+        vu = trace_endpos;
+        fu = trace_fraction;
+
+        // Trace down
+        traceline(self.origin,  self.origin + (-1 * (v_up * pt_seek) + (v_forward * ff)) * lt_seek ,FALSE,self);
+        vd = trace_endpos;
+        fd = trace_fraction;
+
+        vl = normalize(vl - self.origin);
+        vr = normalize(vr - self.origin);
+        vu = normalize(vu - self.origin);
+        vd = normalize(vd - self.origin);
+
+        // Panic tresh passed, find a single direction and turn as hard as we can
+        if (pt_seek == 1)
+        {
+            wishdir = v_right;
+            if (fl > fr) wishdir = -1 * v_right;
+            if (fu > fl) wishdir = v_up;
+            if (fd > fu) wishdir = -1 * v_up;
+        }
+        else
+        {
+            // Normalize our trace vectors to make a smooth path
+            wishdir = normalize( (vl * fl) + (vr * fr) +  (vu * fu) +  (vd * fd) );
+        }
+
+        if (self.enemy)
+        {
+            if (fe < 0.1) fe = 0.1; // Make sure we always try to move sligtly towards our target
+            wishdir = (wishdir * (1 - fe)) + (ve * fe);
+        }
+    }
+    else
+    {
+        // Got a clear path to target, speed up fast (if not at full speed) and go straight for it.
+        myspeed = vlen(self.velocity);
+        if (myspeed < hk_maxspeed)
+            myspeed = min(myspeed * hk_accel2,hk_maxspeed);
+
+        wishdir = ve;
+        //wishdir = normalize(self.enemy.origin - (self.enemy.origin + self.enemy.velocity));
+    }
+
+    if ((myspeed > hk_minspeed) && (self.cnt > time))
+        myspeed = min(myspeed * hk_accel2,hk_maxspeed);
+
+    // Ranoutagazfish?
+    if (self.cnt < time)
+    {
+        self.cnt = time + 0.25;
+        self.nextthink = 0;
+        self.movetype         = MOVETYPE_BOUNCE;
+        sound    (self, CHAN_VOICE, "", 0.4 * VOL_BASE, ATTN_NORM);
+        return;
+    }
+
+    // Calculate new heading
+    olddir = normalize(self.velocity);
+
+    newdir = normalize(olddir + wishdir * cvar("g_turrets_unit_hk_std_shot_speed_turnrate"));
+
+    //fu = (1 / hk_maxspeed) * myspeed;
+    //fd = fu - (0.75 - 0.25);
+    //newdir = normalize(olddir + wishdir * fd);
+
+    // Set heading & speed
+    self.velocity = newdir * myspeed;
+
+    // Align model with new heading
+    self.angles = vectoangles(self.velocity);
+
+
+#ifdef TURRET_DEBUG_HK
+    //if(self.atime < time) {
+    if ((fe <= 0.99)||(edist > 1000))
+    {
+        te_lightning2(world,self.origin, self.origin + vr * lt_seek);
+        te_lightning2(world,self.origin, self.origin + vl * lt_seek);
+        te_lightning2(world,self.origin, self.origin + vu * lt_seek);
+        te_lightning2(world,self.origin, self.origin + vd * lt_seek);
+        te_lightning2(world,self.origin, vf);
+    }
+    else
+    {
+        te_lightning2(world,self.origin, self.enemy.origin);
+    }
+    bprint("Speed: ", ftos(rint(myspeed)), "\n");
+    bprint("Trace to solid: ", ftos(rint(ff * 100)), "%\n");
+    bprint("Trace to target:", ftos(rint(fe * 100)), "%\n");
+    self.atime = time + 0.2;
+    //}
+#endif
+
+	UpdateCSQCProjectile(self);
+}
+
+void turret_hk_missile_explode()
+{
+    vector org2;
+    float d;
+
+    if(self.event_damage != SUB_Null)
+    {
+        self.event_damage = SUB_Null;
+        self.think = turret_hk_missile_explode;
+        self.nextthink = time;
+        return;
+    }
+
+    if ((other == self.owner)||(other == self.owner.tur_head))
+        return;
+
+    //w_deathtypestring = "got hunted to extinction";
+    //vector	org2;
+    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+    org2 = findbetterlocation (self.origin, 16);
+
+    // LordHavoc: TE_TEI_BIGEXPLOSION
+    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+    WriteByte (MSG_BROADCAST, 78);
+    WriteCoord (MSG_BROADCAST, org2_x);
+    WriteCoord (MSG_BROADCAST, org2_y);
+    WriteCoord (MSG_BROADCAST, org2_z);
+
+    self.event_damage = SUB_Null;
+    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+
+#ifdef TURRET_DEBUG
+    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
+    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#endif
+
+    // Target dead, get another is still targeting the same.
+    if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
+        self.owner.enemy = world;
+
+    remove (self);
+}
+
+void turret_hk_postthink()
+{
+    if (cvar("g_turrets_reloadcvars"))
+    {
+        hk_maxspeed = cvar("g_turrets_unit_hk_std_shot_speed_max");
+        hk_minspeed = cvar("g_turrets_unit_hk_std_shot_speed");
+        hk_accel    = cvar("g_turrets_unit_hk_std_shot_speed_accel");
+        hk_accel2   = cvar("g_turrets_unit_hk_std_shot_speed_accel2");
+        hk_decel    = cvar("g_turrets_unit_hk_std_shot_speed_decel");
+    }
+
+    if (self.tur_head.frame != 0)
+        self.tur_head.frame = self.tur_head.frame + 1;
+
+    if (self.tur_head.frame > 5)
+        self.tur_head.frame = 0;
+
+}
+
+void turret_hk_dinit()
+{
+    if (self.netname == "")      self.netname  = "Hunter-killer turret";
+
+    hk_maxspeed = cvar("g_turrets_unit_hk_std_shot_speed_max");
+    hk_minspeed = cvar("g_turrets_unit_hk_std_shot_speed");
+    hk_accel    = cvar("g_turrets_unit_hk_std_shot_speed_accel");
+    hk_accel2   = cvar("g_turrets_unit_hk_std_shot_speed_accel2");
+    hk_decel    = cvar("g_turrets_unit_hk_std_shot_speed_decel");
+
+    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_RECIVETARGETS;
+
+    self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+
+    self.aim_flags = TFL_AIM_SIMPLE;
+
+    self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
+
+    self.firecheck_flags = TFL_FIRECHECK_WORLD | TFL_FIRECHECK_DEAD | TFL_FIRECHECK_TEAMCECK  | TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_AFF;
+
+    self.target_select_flags = TFL_TARGETSELECT_LOS | TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TRIGGERTARGET | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
+
+    self.shoot_flags = TFL_SHOOT_CLEARTARGET;
+
+    if (turret_stdproc_init("hk_std",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_TEAMCHECK;
+
+    setmodel(self,"models/turrets/base.md3");
+    setmodel(self.tur_head,"models/turrets/hk.md3");
+
+    if (!turret_tag_setup())
+        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+    // Our fire routine
+    self.turret_firefunc  = turret_hk_attack;
+
+    // re-color badge & handle recoil effect
+    self.turret_postthink = turret_hk_postthink;
+
+    // What to do when reciveing foreign target data
+    self.turret_addtarget = turret_hk_addtarget;
+}
+
+/*
+* Turret that fires Hunter-killer missiles.
+* Missiles seek their target and try to avoid obstacles. If target dies early, they
+* pick a new one on their own.
+*/
+
+/*QUAKED turret_hk (0 .5 .8) ?
+hunter-killer missiles.
+*/
+
+void spawnfunc_turret_hk()
+{
+    //precache_model ( "models/turrets/hunter2.md3");
+    precache_model ("models/turrets/base.md3");
+    precache_model ("models/turrets/hk.md3");
+
+    self.think = turret_hk_dinit;
+    self.nextthink = time + 0.5;
+}
+
+


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_hk.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_machinegun.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_machinegun.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_machinegun.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,81 +1,81 @@
-void spawnfunc_turret_machinegun();
-void turret_machinegun_std_init();
-void turret_machinegun_attack();
-
-//.float bulletcounter;
-void turret_machinegun_attack()
-{
-
-    entity flash;
-
-    sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);
-    fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant"));
-
-    //w_deathtypestring = "had an alergic reaction due to 10 kilos of led";
-    te_smallflash(self.tur_shotorg);
-    //  trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos);
-
-    // muzzle flash for 3rd person view
-    flash = spawn();
-    //setorigin(flash, '43 1 8');
-    setmodel(flash, "models/uziflash.md3"); // precision set below
-    setattachment(flash, self.tur_head, "tag_fire");
-    flash.think = W_Uzi_Flash_Go;
-    flash.nextthink = time + 0.02;
-    flash.frame = 2;
-    flash.angles_z = flash.v_angle_z + random() * 180;
-    flash.alpha = 1;
-    flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
-}
-
-
-void turret_machinegun_std_init()
-{
-    if (self.netname == "")      self.netname     = "Machinegun Turret";
-
-    self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-    self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL;// | TFL_TURRCAPS_MISSILEKILL;
-    self.aim_flags = TFL_AIM_LEAD;
-
-    if(cvar("g_antilag_bullets"))
-        self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
-    else
-        self.aim_flags      |= TFL_AIM_SHOTTIMECOMPENSATE;
-
-    if (turret_stdproc_init("machinegun_std",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    self.damage_flags |= TFL_DMG_HEADSHAKE;
-
-    setmodel(self,"models/turrets/base.md3");
-    setmodel(self.tur_head,"models/turrets/machinegun.md3");
-
-    if (!turret_tag_setup())
-        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
-    // Our fire routine
-    self.turret_firefunc  = turret_machinegun_attack;
-
-}
-
-
-
-/*
-* machinegun turret. does what you'd expect
-*/
-
-/*QUAKED turret_machinegun (0 .5 .8) ?
-*/
-void spawnfunc_turret_machinegun()
-{
-    precache_model ("models/turrets/machinegun.md3");
-    precache_model ("models/turrets/base.md3");
-    precache_sound ("weapons/uzi_fire.wav");
-
-    self.think = turret_machinegun_std_init;
-    self.nextthink = time + 0.5;
-}
-
+void spawnfunc_turret_machinegun();
+void turret_machinegun_std_init();
+void turret_machinegun_attack();
+
+//.float bulletcounter;
+void turret_machinegun_attack()
+{
+
+    entity flash;
+
+    sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);
+    fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant"));
+
+    //w_deathtypestring = "had an alergic reaction due to 10 kilos of led";
+    te_smallflash(self.tur_shotorg);
+    //  trailparticles(self,particleeffectnum("EF_MGTURRETTRAIL"),self.tur_shotorg_updated,trace_endpos);
+
+    // muzzle flash for 3rd person view
+    flash = spawn();
+    //setorigin(flash, '43 1 8');
+    setmodel(flash, "models/uziflash.md3"); // precision set below
+    setattachment(flash, self.tur_head, "tag_fire");
+    flash.think = W_Uzi_Flash_Go;
+    flash.nextthink = time + 0.02;
+    flash.frame = 2;
+    flash.angles_z = flash.v_angle_z + random() * 180;
+    flash.alpha = 1;
+    flash.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
+}
+
+
+void turret_machinegun_std_init()
+{
+    if (self.netname == "")      self.netname     = "Machinegun Turret";
+
+    self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+    self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL;// | TFL_TURRCAPS_MISSILEKILL;
+    self.aim_flags = TFL_AIM_LEAD;
+
+    if(cvar("g_antilag_bullets"))
+        self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
+    else
+        self.aim_flags      |= TFL_AIM_SHOTTIMECOMPENSATE;
+
+    if (turret_stdproc_init("machinegun_std",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    self.damage_flags |= TFL_DMG_HEADSHAKE;
+
+    setmodel(self,"models/turrets/base.md3");
+    setmodel(self.tur_head,"models/turrets/machinegun.md3");
+
+    if (!turret_tag_setup())
+        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+    // Our fire routine
+    self.turret_firefunc  = turret_machinegun_attack;
+
+}
+
+
+
+/*
+* machinegun turret. does what you'd expect
+*/
+
+/*QUAKED turret_machinegun (0 .5 .8) ?
+*/
+void spawnfunc_turret_machinegun()
+{
+    precache_model ("models/turrets/machinegun.md3");
+    precache_model ("models/turrets/base.md3");
+    precache_sound ("weapons/uzi_fire.wav");
+
+    self.think = turret_machinegun_std_init;
+    self.nextthink = time + 0.5;
+}
+


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_machinegun.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_mlrs.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_mlrs.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_mlrs.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,142 +1,142 @@
-void spawnfunc_turret_mlrs();
-void turret_mlrs_dinit();
-void turret_mlrs_attack();
-void turret_mlrs_rocket_explode();
-void turret_mlrs_rocket_touch();
-
-void turret_mlrs_postthink()
-{
-
-    // 0 = full, 6 = empty
-    self.tur_head.frame = rint(6 - (self.ammo / self.shot_dmg));
-}
-
-void turret_mlrs_attack()
-{
-    entity missile;
-
-    turret_tag_fire_update();
-
-    sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", VOL_BASE, ATTN_NORM);
-
-    missile                    = spawn ();
-    //setsize (missile, '0 0 0', '0 0 0'); // give it some size so it can be shot
-    setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-    setorigin(missile, self.tur_shotorg);
-    missile.classname          = "mlrs_missile";
-    missile.owner              = self;
-    missile.bot_dodge          = TRUE;
-    missile.bot_dodgerating    = self.shot_dmg;
-    missile.takedamage         = DAMAGE_NO;
-    missile.damageforcescale   = 4;
-    //missile.health             = 25;
-    missile.think              = turret_mlrs_rocket_explode;
-
-    missile.nextthink          = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
-    //missile.nextthink          = missile.nextthink + random() * self.shot_spread;
-
-    missile.solid              = SOLID_BBOX;
-    missile.movetype           = MOVETYPE_FLYMISSILE;
-    missile.velocity           = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
-    missile.angles             = vectoangles(missile.velocity);
-    missile.touch              = turret_mlrs_rocket_touch;
-    missile.flags              = FL_PROJECTILE;
-    missile.solid              = SOLID_BBOX;
-    missile.enemy              = self.enemy;
-
-	CSQCProjectile(missile, TRUE, PROJECTILE_ROCKET, FALSE); // no cull, fly sound
-
-    te_explosion (missile.origin);
-
-    //self.tur_head.frame = 7 - self.volly_counter;
-}
-
-void turret_mlrs_rocket_touch()
-{
-    if( (other == self.owner) || (other == self.owner.tur_head) )
-        return;
-
-    PROJECTILE_TOUCH;
-
-    turret_mlrs_rocket_explode();
-}
-
-void turret_mlrs_rocket_explode()
-{
-    vector org2;
-
-    if(self.event_damage != SUB_Null)
-    {
-        self.event_damage = SUB_Null;
-        self.think = turret_mlrs_rocket_explode;
-        self.nextthink = time;
-        return;
-    }
-
-
-    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
-    org2 = findbetterlocation (self.origin, 16);
-    pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
-    //w_deathtypestring = "dident escape the rocket barrage";
-#ifdef TURRET_DEBUG
-    float d;
-
-    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
-    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#else
-    RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg * 0.5, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-#endif
-
-    // Target dead, Tell turret.
-    if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
-        self.owner.enemy = world;
-
-    remove (self);
-}
-
-void turret_mlrs_dinit()
-{
-    if (self.netname == "")      self.netname  = "MLRS turret";
-
-    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
-    self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
-    self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_INFRONT;
-
-    if (turret_stdproc_init("mlrs_std",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    self.damage_flags |= TFL_DMG_HEADSHAKE;
-
-    self.shoot_flags |= TFL_SHOOT_VOLLYALWAYS;
-    self.volly_counter = self.shot_volly;
-
-    setmodel(self,"models/turrets/base.md3");
-    setmodel(self.tur_head,"models/turrets/mlrs.md3");
-
-    if (!turret_tag_setup())
-        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
-    // Our fire routine
-    self.turret_firefunc  = turret_mlrs_attack;
-    self.turret_postthink = turret_mlrs_postthink;
-
-}
-
-/*QUAKED turret_mlrs (0 .5 .8) ?
-*/
-
-void spawnfunc_turret_mlrs()
-{
-    //precache_model ( "models/turrets/rocket.md3");
-    precache_model ("models/turrets/mlrs.md3");
-    precache_model ("models/turrets/base.md3");
-
-    self.think = turret_mlrs_dinit;
-    self.nextthink = time + 0.5;
-}
-
-
+void spawnfunc_turret_mlrs();
+void turret_mlrs_dinit();
+void turret_mlrs_attack();
+void turret_mlrs_rocket_explode();
+void turret_mlrs_rocket_touch();
+
+void turret_mlrs_postthink()
+{
+
+    // 0 = full, 6 = empty
+    self.tur_head.frame = rint(6 - (self.ammo / self.shot_dmg));
+}
+
+void turret_mlrs_attack()
+{
+    entity missile;
+
+    turret_tag_fire_update();
+
+    sound (self, CHAN_WEAPON, "weapons/rocket_fire.wav", VOL_BASE, ATTN_NORM);
+
+    missile                    = spawn ();
+    //setsize (missile, '0 0 0', '0 0 0'); // give it some size so it can be shot
+    setsize (missile, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
+    setorigin(missile, self.tur_shotorg);
+    missile.classname          = "mlrs_missile";
+    missile.owner              = self;
+    missile.bot_dodge          = TRUE;
+    missile.bot_dodgerating    = self.shot_dmg;
+    missile.takedamage         = DAMAGE_NO;
+    missile.damageforcescale   = 4;
+    //missile.health             = 25;
+    missile.think              = turret_mlrs_rocket_explode;
+
+    missile.nextthink          = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
+    //missile.nextthink          = missile.nextthink + random() * self.shot_spread;
+
+    missile.solid              = SOLID_BBOX;
+    missile.movetype           = MOVETYPE_FLYMISSILE;
+    missile.velocity           = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+    missile.angles             = vectoangles(missile.velocity);
+    missile.touch              = turret_mlrs_rocket_touch;
+    missile.flags              = FL_PROJECTILE;
+    missile.solid              = SOLID_BBOX;
+    missile.enemy              = self.enemy;
+
+	CSQCProjectile(missile, TRUE, PROJECTILE_ROCKET, FALSE); // no cull, fly sound
+
+    te_explosion (missile.origin);
+
+    //self.tur_head.frame = 7 - self.volly_counter;
+}
+
+void turret_mlrs_rocket_touch()
+{
+    if( (other == self.owner) || (other == self.owner.tur_head) )
+        return;
+
+    PROJECTILE_TOUCH;
+
+    turret_mlrs_rocket_explode();
+}
+
+void turret_mlrs_rocket_explode()
+{
+    vector org2;
+
+    if(self.event_damage != SUB_Null)
+    {
+        self.event_damage = SUB_Null;
+        self.think = turret_mlrs_rocket_explode;
+        self.nextthink = time;
+        return;
+    }
+
+
+    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+    org2 = findbetterlocation (self.origin, 16);
+    pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
+    //w_deathtypestring = "dident escape the rocket barrage";
+#ifdef TURRET_DEBUG
+    float d;
+
+    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
+    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#else
+    RadiusDamage (self, self.owner, self.owner.shot_dmg, self.owner.shot_dmg * 0.5, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+#endif
+
+    // Target dead, Tell turret.
+    if ((self.enemy.deadflag != DEAD_NO) && (self.enemy == self.owner.enemy))
+        self.owner.enemy = world;
+
+    remove (self);
+}
+
+void turret_mlrs_dinit()
+{
+    if (self.netname == "")      self.netname  = "MLRS turret";
+
+    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
+    self.ammo_flags = TFL_AMMO_ROCKETS | TFL_AMMO_RECHARGE;
+    self.aim_flags = TFL_AIM_LEAD | TFL_AIM_ZEASE | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_INFRONT;
+
+    if (turret_stdproc_init("mlrs_std",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    self.damage_flags |= TFL_DMG_HEADSHAKE;
+
+    self.shoot_flags |= TFL_SHOOT_VOLLYALWAYS;
+    self.volly_counter = self.shot_volly;
+
+    setmodel(self,"models/turrets/base.md3");
+    setmodel(self.tur_head,"models/turrets/mlrs.md3");
+
+    if (!turret_tag_setup())
+        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+    // Our fire routine
+    self.turret_firefunc  = turret_mlrs_attack;
+    self.turret_postthink = turret_mlrs_postthink;
+
+}
+
+/*QUAKED turret_mlrs (0 .5 .8) ?
+*/
+
+void spawnfunc_turret_mlrs()
+{
+    //precache_model ( "models/turrets/rocket.md3");
+    precache_model ("models/turrets/mlrs.md3");
+    precache_model ("models/turrets/base.md3");
+
+    self.think = turret_mlrs_dinit;
+    self.nextthink = time + 0.5;
+}
+
+


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_mlrs.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,149 +1,149 @@
-void spawnfunc_turret_phaser();
-void turret_phaser_dinit();
-void turret_phaser_attack();
-
-.float fireflag;
-
-float turret_phaser_firecheck()
-{
-    if (self.fireflag != 0) return 0;
-    return turret_stdproc_firecheck();
-}
-
-void turret_phaser_postthink()
-{
-    if (self.tur_head.frame == 0)
-        return;
-
-    if (self.fireflag == 1)
-    {
-        if (self.tur_head.frame == 10)
-            self.tur_head.frame = 1;
-        else
-            self.tur_head.frame = self.tur_head.frame +1;
-    }
-    else if (self.fireflag == 2 )
-    {
-        self.tur_head.frame = self.tur_head.frame +1;
-        if (self.tur_head.frame == 15)
-        {
-            self.tur_head.frame = 0;
-            self.fireflag = 0;
-        }
-    }
-}
-
-void beam_think()
-{
-    if ((time > self.cnt) || (self.owner.deadflag != DEAD_NO))
-    {
-        self.owner.attack_finished_single = time + self.owner.shot_refire;
-        self.owner.fireflag = 2;
-        self.owner.tur_head.frame = 10;
-        sound (self, CHAN_PROJECTILE, "", VOL_BASE, ATTN_NORM);
-        remove(self);
-        return;
-    }
-
-    turret_do_updates(self.owner);
-
-    if (time - self.shot_spread > 0)
-    {
-        self.shot_spread = time + 2;
-        sound (self, CHAN_VOICE, "turrets/phaser.wav", VOL_BASE, ATTN_NORM);
-    }
-
-
-    self.nextthink = time + self.ticrate;
-
-    self.owner.attack_finished_single = time + frametime;
-    entity oldself;
-    oldself = self;
-    self = self.owner;
-    //w_deathtypestring = "was phased out of existence";
-    FireImoBeam (   self.tur_shotorg,
-                    self.tur_shotorg + self.tur_shotdir_updated * self.target_range,
-                    '-1 -1 -1' * self.shot_radius,
-                    '1 1 1' * self.shot_radius,
-                    self.shot_force,
-                    oldself.shot_dmg,
-                    0.75,
-                    DEATH_TURRET);
-    self = oldself;
-    self.scale = vlen(self.owner.tur_shotorg - trace_endpos) / 256;
-
-}
-
-void turret_phaser_attack()
-{
-    entity beam;
-
-    beam = spawn();
-    beam.ticrate = 0.1; //cvar("sys_ticrate");
-    setmodel(beam,"models/turrets/phaser_beam.md3");
-    beam.effects = EF_LOWPRECISION;
-    beam.solid = SOLID_NOT;
-    beam.think = beam_think;
-    beam.cnt = time + self.shot_speed;
-    beam.shot_spread = time + 2;
-    beam.nextthink = time;
-    beam.owner = self;
-    beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate);
-    beam.scale = self.target_range / 256;
-    beam.movetype = MOVETYPE_NONE;
-    beam.enemy = self.enemy;
-    beam.bot_dodge = TRUE;
-    beam.bot_dodgerating = beam.shot_dmg;
-    sound (beam, CHAN_PROJECTILE, "turrets/phaser.wav", VOL_BASE, ATTN_NORM);
-    self.fireflag = 1;
-
-    beam.attack_finished_single = self.attack_finished_single;
-    self.attack_finished_single = time; // + cvar("sys_ticrate");
-
-    setattachment(beam,self.tur_head,"tag_fire");
-
-    soundat (self, trace_endpos, CHAN_PROJECTILE, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
-
-    if (self.tur_head.frame == 0)
-        self.tur_head.frame = 1;
-}
-
-void turret_phaser_dinit()
-{
-    if (self.netname == "")      self.netname  = "Phaser Cannon";
-
-    self.turrcaps_flags = TFL_TURRCAPS_SNIPER|TFL_TURRCAPS_HITSCAN|TFL_TURRCAPS_PLAYERKILL;
-    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-    self.aim_flags = TFL_AIM_ZEASE | TFL_AIM_LEAD;
-
-    if (turret_stdproc_init("phaser_std",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    setmodel(self,"models/turrets/base.md3");
-    setmodel(self.tur_head,"models/turrets/phaser.md3");
-
-    if (!turret_tag_setup())
-        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
-    self.turret_firecheckfunc = turret_phaser_firecheck;
-    self.turret_firefunc  = turret_phaser_attack;
-    self.turret_postthink = turret_phaser_postthink;
-
-}
-
-/*QUAKED turret_phaser(0 .5 .8) ?
-*/
-void spawnfunc_turret_phaser()
-{
-    precache_sound ("turrets/phaser.wav");
-    precache_model ("models/turrets/phaser.md3");
-    precache_model ("models/turrets/phaser_beam.md3");
-    precache_model ("models/turrets/base.md3");
-
-    self.think = turret_phaser_dinit;
-    self.nextthink = time + 0.5;
-}
-
+void spawnfunc_turret_phaser();
+void turret_phaser_dinit();
+void turret_phaser_attack();
+
+.float fireflag;
+
+float turret_phaser_firecheck()
+{
+    if (self.fireflag != 0) return 0;
+    return turret_stdproc_firecheck();
+}
+
+void turret_phaser_postthink()
+{
+    if (self.tur_head.frame == 0)
+        return;
+
+    if (self.fireflag == 1)
+    {
+        if (self.tur_head.frame == 10)
+            self.tur_head.frame = 1;
+        else
+            self.tur_head.frame = self.tur_head.frame +1;
+    }
+    else if (self.fireflag == 2 )
+    {
+        self.tur_head.frame = self.tur_head.frame +1;
+        if (self.tur_head.frame == 15)
+        {
+            self.tur_head.frame = 0;
+            self.fireflag = 0;
+        }
+    }
+}
+
+void beam_think()
+{
+    if ((time > self.cnt) || (self.owner.deadflag != DEAD_NO))
+    {
+        self.owner.attack_finished_single = time + self.owner.shot_refire;
+        self.owner.fireflag = 2;
+        self.owner.tur_head.frame = 10;
+        sound (self, CHAN_PROJECTILE, "", VOL_BASE, ATTN_NORM);
+        remove(self);
+        return;
+    }
+
+    turret_do_updates(self.owner);
+
+    if (time - self.shot_spread > 0)
+    {
+        self.shot_spread = time + 2;
+        sound (self, CHAN_VOICE, "turrets/phaser.wav", VOL_BASE, ATTN_NORM);
+    }
+
+
+    self.nextthink = time + self.ticrate;
+
+    self.owner.attack_finished_single = time + frametime;
+    entity oldself;
+    oldself = self;
+    self = self.owner;
+    //w_deathtypestring = "was phased out of existence";
+    FireImoBeam (   self.tur_shotorg,
+                    self.tur_shotorg + self.tur_shotdir_updated * self.target_range,
+                    '-1 -1 -1' * self.shot_radius,
+                    '1 1 1' * self.shot_radius,
+                    self.shot_force,
+                    oldself.shot_dmg,
+                    0.75,
+                    DEATH_TURRET);
+    self = oldself;
+    self.scale = vlen(self.owner.tur_shotorg - trace_endpos) / 256;
+
+}
+
+void turret_phaser_attack()
+{
+    entity beam;
+
+    beam = spawn();
+    beam.ticrate = 0.1; //cvar("sys_ticrate");
+    setmodel(beam,"models/turrets/phaser_beam.md3");
+    beam.effects = EF_LOWPRECISION;
+    beam.solid = SOLID_NOT;
+    beam.think = beam_think;
+    beam.cnt = time + self.shot_speed;
+    beam.shot_spread = time + 2;
+    beam.nextthink = time;
+    beam.owner = self;
+    beam.shot_dmg = self.shot_dmg / (self.shot_speed / beam.ticrate);
+    beam.scale = self.target_range / 256;
+    beam.movetype = MOVETYPE_NONE;
+    beam.enemy = self.enemy;
+    beam.bot_dodge = TRUE;
+    beam.bot_dodgerating = beam.shot_dmg;
+    sound (beam, CHAN_PROJECTILE, "turrets/phaser.wav", VOL_BASE, ATTN_NORM);
+    self.fireflag = 1;
+
+    beam.attack_finished_single = self.attack_finished_single;
+    self.attack_finished_single = time; // + cvar("sys_ticrate");
+
+    setattachment(beam,self.tur_head,"tag_fire");
+
+    soundat (self, trace_endpos, CHAN_PROJECTILE, "weapons/neximpact.wav", VOL_BASE, ATTN_NORM);
+
+    if (self.tur_head.frame == 0)
+        self.tur_head.frame = 1;
+}
+
+void turret_phaser_dinit()
+{
+    if (self.netname == "")      self.netname  = "Phaser Cannon";
+
+    self.turrcaps_flags = TFL_TURRCAPS_SNIPER|TFL_TURRCAPS_HITSCAN|TFL_TURRCAPS_PLAYERKILL;
+    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+    self.aim_flags = TFL_AIM_ZEASE | TFL_AIM_LEAD;
+
+    if (turret_stdproc_init("phaser_std",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    setmodel(self,"models/turrets/base.md3");
+    setmodel(self.tur_head,"models/turrets/phaser.md3");
+
+    if (!turret_tag_setup())
+        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+    self.turret_firecheckfunc = turret_phaser_firecheck;
+    self.turret_firefunc  = turret_phaser_attack;
+    self.turret_postthink = turret_phaser_postthink;
+
+}
+
+/*QUAKED turret_phaser(0 .5 .8) ?
+*/
+void spawnfunc_turret_phaser()
+{
+    precache_sound ("turrets/phaser.wav");
+    precache_model ("models/turrets/phaser.md3");
+    precache_model ("models/turrets/phaser_beam.md3");
+    precache_model ("models/turrets/base.md3");
+
+    self.think = turret_phaser_dinit;
+    self.nextthink = time + 0.5;
+}
+


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_phaser.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_plasma.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_plasma.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_plasma.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,225 +1,225 @@
-void spawnfunc_turret_plasma();
-void spawnfunc_turret_plasma_dual();
-
-void turret_plasma_std_init();
-void turret_plasma_dual_init();
-
-void turret_plasma_attack();
-void turret_plasma_projectile_explode();
-
-void turret_plasma_postthink()
-{
-    if (self.tur_head.frame != 0)
-        self.tur_head.frame = self.tur_head.frame + 1;
-
-    if (self.tur_head.frame > 5)
-        self.tur_head.frame = 0;
-}
-
-void turret_plasma_dual_postthink()
-{
-    if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3))
-        self.tur_head.frame = self.tur_head.frame + 1;
-
-    if (self.tur_head.frame > 6)
-        self.tur_head.frame = 0;
-}
-
-void turret_plasma_attack()
-{
-    entity proj;
-
-    sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
-    pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
-
-    proj                    = spawn ();
-    setorigin(proj, self.tur_shotorg);
-    setsize(proj, '-1 -1 -1', '1 1 1');
-    proj.classname       = "plasmabomb";
-    proj.owner           = self;
-    proj.bot_dodge       = TRUE;
-    proj.bot_dodgerating = self.shot_dmg;
-    proj.think           = turret_plasma_projectile_explode;
-    proj.nextthink       = time + 9;
-    proj.solid           = SOLID_BBOX;
-    proj.movetype        = MOVETYPE_FLYMISSILE;
-    proj.velocity        = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
-    //proj.velocity        = self.tur_shotdir_updated  * self.shot_speed;
-    proj.touch           = turret_plasma_projectile_explode;
-    proj.flags           = FL_PROJECTILE;
-    proj.enemy           = self.enemy;
-    proj.flags           = FL_PROJECTILE | FL_NOTARGET;
-
-    CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO_BEAM, TRUE);
-
-    if (self.tur_head.frame == 0)
-        self.tur_head.frame = 1;
-}
-
-void turret_plasma_dual_attack()
-{
-    entity proj;
-
-    sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
-    proj                    = spawn ();
-    setorigin(proj, self.tur_shotorg);
-    setsize(proj, '0 0 0', '0 0 0');
-    proj.classname       = "plasmabomb";
-    proj.owner           = self;
-    proj.bot_dodge       = TRUE;
-    proj.bot_dodgerating = self.shot_dmg;
-    proj.think           = turret_plasma_projectile_explode;
-    proj.nextthink       = time + 9;
-    proj.solid           = SOLID_BBOX;
-    proj.movetype        = MOVETYPE_FLYMISSILE;
-    proj.velocity        = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
-    //proj.velocity        = self.tur_shotdir_updated  * self.shot_speed;
-    proj.touch           = turret_plasma_projectile_explode;
-    proj.flags           = FL_PROJECTILE;
-    proj.enemy           = self.enemy;
-    proj.flags           = FL_PROJECTILE | FL_NOTARGET;
-
-    self.tur_head.frame += 1;
-
-    CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO_BEAM, TRUE);
-}
-
-void turret_plasma_projectile_explode()
-{
-    vector org2;
-
-    org2 = findbetterlocation (self.origin, 8);
-    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
-    WriteByte (MSG_BROADCAST, 79);
-    WriteCoord (MSG_BROADCAST, org2_x);
-    WriteCoord (MSG_BROADCAST, org2_y);
-    WriteCoord (MSG_BROADCAST, org2_z);
-    WriteCoord (MSG_BROADCAST, 0);		// SeienAbunae: groan... Useless clutter
-    WriteCoord (MSG_BROADCAST, 0);
-    WriteCoord (MSG_BROADCAST, 0);
-    WriteByte (MSG_BROADCAST, 155);
-
-    self.event_damage = SUB_Null;
-    //w_deathtypestring = "ate to much plasma";
-#ifdef TURRET_DEBUG
-    float d;
-
-    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
-    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
-#else
-    RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
-#endif
-    sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
-
-    remove (self);
-}
-
-void turret_plasma_std_init()
-{
-    if (self.netname == "")      self.netname     = "Plasma Cannon";
-
-    // What ammo to use
-    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-
-    // How to aim
-    //self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZPREDICT | TFL_AIM_GROUND2;
-    self.aim_flags      = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_GROUND2;
-    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
-
-    if (turret_stdproc_init("plasma_std",FALSE) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    self.damage_flags    |= TFL_DMG_HEADSHAKE;
-
-    //self.firecheck_flags |= (TFL_FIRECHECK_AFF | TFL_FIRECHECK_VERIFIED);
-    self.firecheck_flags |= TFL_FIRECHECK_AFF;
-
-    //self.target_select_flags |= TFL_TARGETSELECT_FOV;
-    //self.target_select_fov    = 45;
-
-    setmodel(self,"models/turrets/base.md3");
-    setmodel(self.tur_head,"models/turrets/plasma.md3");
-    // self.tur_head.alpha = -1;
-
-    if (!turret_tag_setup())
-        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
-    // Our fireing routine
-    self.turret_firefunc  = turret_plasma_attack;
-
-    // Custom per turret frame stuff. usualy animation.
-    self.turret_postthink = turret_plasma_postthink;
-    turret_do_updates(self);
-}
-
-
-void turret_plasma_dual_init()
-{
-    if (self.netname == "")      self.netname     = "Dual Plasma Cannon";
-
-    // What ammo to use
-    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-
-    // How to aim at targets
-    self.aim_flags      = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE  | TFL_AIM_GROUND2 ;
-    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
-
-    if (turret_stdproc_init("plasma_dual",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    self.damage_flags    |= TFL_DMG_HEADSHAKE;
-    //self.firecheck_flags |= (TFL_FIRECHECK_AFF | TFL_FIRECHECK_VERIFIED);
-    //self.firecheck_flags |= TFL_FIRECHECK_AFF;
-
-    setmodel(self,"models/turrets/base.md3");
-    setmodel(self.tur_head,"models/turrets/plasmad.md3");
-
-
-    if (!turret_tag_setup())
-        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
-    // Our fireing routine
-    self.turret_firefunc  = turret_plasma_dual_attack;
-
-    // Custom per turret frame stuff. usualy animation.
-    self.turret_postthink = turret_plasma_dual_postthink;
-}
-
-
-/*
-* Basic moderate (std) or fast (dual) fireing, short-mid range energy cannon.
-* Not too mutch of a therat on its own, but can be rather dangerous in groups.
-* Regenerates ammo slowly, support with a fusionreactor(s) to do some real damage.
-*/
-
-/*QUAKED turret_plasma (0 .5 .8) ?
-*/
-void spawnfunc_turret_plasma()
-{
-    g_turrets_common_precash();
-    precache_model ("models/turrets/plasma.md3");
-    precache_model ("models/turrets/base.md3");
-
-    self.think = turret_plasma_std_init;
-    self.nextthink = time + 0.5;
-}
-
-/*QUAKED turret_plasma_dual (0 .5 .8) ?
-*/
-void spawnfunc_turret_plasma_dual()
-{
-
-    precache_model ("models/turrets/plasmad.md3");
-    precache_model ("models/turrets/base.md3");
-
-    self.think = turret_plasma_dual_init;
-    self.nextthink = time + 0.5;
-}
-
+void spawnfunc_turret_plasma();
+void spawnfunc_turret_plasma_dual();
+
+void turret_plasma_std_init();
+void turret_plasma_dual_init();
+
+void turret_plasma_attack();
+void turret_plasma_projectile_explode();
+
+void turret_plasma_postthink()
+{
+    if (self.tur_head.frame != 0)
+        self.tur_head.frame = self.tur_head.frame + 1;
+
+    if (self.tur_head.frame > 5)
+        self.tur_head.frame = 0;
+}
+
+void turret_plasma_dual_postthink()
+{
+    if ((self.tur_head.frame != 0) && (self.tur_head.frame != 3))
+        self.tur_head.frame = self.tur_head.frame + 1;
+
+    if (self.tur_head.frame > 6)
+        self.tur_head.frame = 0;
+}
+
+void turret_plasma_attack()
+{
+    entity proj;
+
+    sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
+    pointparticles(particleeffectnum("laser_muzzleflash"), self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
+
+    proj                    = spawn ();
+    setorigin(proj, self.tur_shotorg);
+    setsize(proj, '-1 -1 -1', '1 1 1');
+    proj.classname       = "plasmabomb";
+    proj.owner           = self;
+    proj.bot_dodge       = TRUE;
+    proj.bot_dodgerating = self.shot_dmg;
+    proj.think           = turret_plasma_projectile_explode;
+    proj.nextthink       = time + 9;
+    proj.solid           = SOLID_BBOX;
+    proj.movetype        = MOVETYPE_FLYMISSILE;
+    proj.velocity        = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+    //proj.velocity        = self.tur_shotdir_updated  * self.shot_speed;
+    proj.touch           = turret_plasma_projectile_explode;
+    proj.flags           = FL_PROJECTILE;
+    proj.enemy           = self.enemy;
+    proj.flags           = FL_PROJECTILE | FL_NOTARGET;
+
+    CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO_BEAM, TRUE);
+
+    if (self.tur_head.frame == 0)
+        self.tur_head.frame = 1;
+}
+
+void turret_plasma_dual_attack()
+{
+    entity proj;
+
+    sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
+    proj                    = spawn ();
+    setorigin(proj, self.tur_shotorg);
+    setsize(proj, '0 0 0', '0 0 0');
+    proj.classname       = "plasmabomb";
+    proj.owner           = self;
+    proj.bot_dodge       = TRUE;
+    proj.bot_dodgerating = self.shot_dmg;
+    proj.think           = turret_plasma_projectile_explode;
+    proj.nextthink       = time + 9;
+    proj.solid           = SOLID_BBOX;
+    proj.movetype        = MOVETYPE_FLYMISSILE;
+    proj.velocity        = normalize(self.tur_shotdir_updated + randomvec() * self.shot_spread) * self.shot_speed;
+    //proj.velocity        = self.tur_shotdir_updated  * self.shot_speed;
+    proj.touch           = turret_plasma_projectile_explode;
+    proj.flags           = FL_PROJECTILE;
+    proj.enemy           = self.enemy;
+    proj.flags           = FL_PROJECTILE | FL_NOTARGET;
+
+    self.tur_head.frame += 1;
+
+    CSQCProjectile(proj, TRUE, PROJECTILE_ELECTRO_BEAM, TRUE);
+}
+
+void turret_plasma_projectile_explode()
+{
+    vector org2;
+
+    org2 = findbetterlocation (self.origin, 8);
+    WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
+    WriteByte (MSG_BROADCAST, 79);
+    WriteCoord (MSG_BROADCAST, org2_x);
+    WriteCoord (MSG_BROADCAST, org2_y);
+    WriteCoord (MSG_BROADCAST, org2_z);
+    WriteCoord (MSG_BROADCAST, 0);		// SeienAbunae: groan... Useless clutter
+    WriteCoord (MSG_BROADCAST, 0);
+    WriteCoord (MSG_BROADCAST, 0);
+    WriteByte (MSG_BROADCAST, 155);
+
+    self.event_damage = SUB_Null;
+    //w_deathtypestring = "ate to much plasma";
+#ifdef TURRET_DEBUG
+    float d;
+
+    d = RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+    self.owner.tur_dbg_dmg_t_h = self.owner.tur_dbg_dmg_t_h + d; //self.owner.shot_dmg;
+    self.owner.tur_dbg_dmg_t_f = self.owner.tur_dbg_dmg_t_f + self.owner.shot_dmg;
+#else
+    RadiusDamage (self, self.owner, self.owner.shot_dmg, 0, self.owner.shot_radius, world, self.owner.shot_force, DEATH_TURRET, world);
+#endif
+    sound (self, CHAN_PROJECTILE, "weapons/electro_impact.wav", VOL_BASE, ATTN_NORM);
+
+    remove (self);
+}
+
+void turret_plasma_std_init()
+{
+    if (self.netname == "")      self.netname     = "Plasma Cannon";
+
+    // What ammo to use
+    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+
+    // How to aim
+    //self.aim_flags = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_ZPREDICT | TFL_AIM_GROUND2;
+    self.aim_flags      = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE | TFL_AIM_GROUND2;
+    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
+
+    if (turret_stdproc_init("plasma_std",FALSE) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    self.damage_flags    |= TFL_DMG_HEADSHAKE;
+
+    //self.firecheck_flags |= (TFL_FIRECHECK_AFF | TFL_FIRECHECK_VERIFIED);
+    self.firecheck_flags |= TFL_FIRECHECK_AFF;
+
+    //self.target_select_flags |= TFL_TARGETSELECT_FOV;
+    //self.target_select_fov    = 45;
+
+    setmodel(self,"models/turrets/base.md3");
+    setmodel(self.tur_head,"models/turrets/plasma.md3");
+    // self.tur_head.alpha = -1;
+
+    if (!turret_tag_setup())
+        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+    // Our fireing routine
+    self.turret_firefunc  = turret_plasma_attack;
+
+    // Custom per turret frame stuff. usualy animation.
+    self.turret_postthink = turret_plasma_postthink;
+    turret_do_updates(self);
+}
+
+
+void turret_plasma_dual_init()
+{
+    if (self.netname == "")      self.netname     = "Dual Plasma Cannon";
+
+    // What ammo to use
+    self.ammo_flags = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+
+    // How to aim at targets
+    self.aim_flags      = TFL_AIM_LEAD | TFL_AIM_SHOTTIMECOMPENSATE  | TFL_AIM_GROUND2 ;
+    self.turrcaps_flags = TFL_TURRCAPS_RADIUSDMG | TFL_TURRCAPS_MEDPROJ | TFL_TURRCAPS_PLAYERKILL;
+
+    if (turret_stdproc_init("plasma_dual",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    self.damage_flags    |= TFL_DMG_HEADSHAKE;
+    //self.firecheck_flags |= (TFL_FIRECHECK_AFF | TFL_FIRECHECK_VERIFIED);
+    //self.firecheck_flags |= TFL_FIRECHECK_AFF;
+
+    setmodel(self,"models/turrets/base.md3");
+    setmodel(self.tur_head,"models/turrets/plasmad.md3");
+
+
+    if (!turret_tag_setup())
+        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+    // Our fireing routine
+    self.turret_firefunc  = turret_plasma_dual_attack;
+
+    // Custom per turret frame stuff. usualy animation.
+    self.turret_postthink = turret_plasma_dual_postthink;
+}
+
+
+/*
+* Basic moderate (std) or fast (dual) fireing, short-mid range energy cannon.
+* Not too mutch of a therat on its own, but can be rather dangerous in groups.
+* Regenerates ammo slowly, support with a fusionreactor(s) to do some real damage.
+*/
+
+/*QUAKED turret_plasma (0 .5 .8) ?
+*/
+void spawnfunc_turret_plasma()
+{
+    g_turrets_common_precash();
+    precache_model ("models/turrets/plasma.md3");
+    precache_model ("models/turrets/base.md3");
+
+    self.think = turret_plasma_std_init;
+    self.nextthink = time + 0.5;
+}
+
+/*QUAKED turret_plasma_dual (0 .5 .8) ?
+*/
+void spawnfunc_turret_plasma_dual()
+{
+
+    precache_model ("models/turrets/plasmad.md3");
+    precache_model ("models/turrets/base.md3");
+
+    self.think = turret_plasma_dual_init;
+    self.nextthink = time + 0.5;
+}
+


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_plasma.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_targettrigger.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_targettrigger.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_targettrigger.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,42 +1,42 @@
-void spawnfunc_turret_targettrigger();
-void turret_targettrigger_touch();
-
-void turret_targettrigger_touch()
-{
-    entity e;
-    if (self.cnt > time) return;
-    entity oldself;
-    oldself = self;
-
-    e = find(world, targetname, self.target);
-    while (e)
-    {
-        if (e.turrcaps_flags & TFL_TURRCAPS_RECIVETARGETS)
-        {
-            self = e;
-            if(e.turret_addtarget)
-                e.turret_addtarget(other,oldself);
-        }
-
-        e = find(e, targetname, oldself.target);
-    }
-
-    oldself.cnt = time + 0.5;
-
-    self = oldself;
-}
-
-/*QUAKED turret_targettrigger (.5 .5 .5) ?
-*/
-void spawnfunc_turret_targettrigger()
-{
-    if (!cvar("g_turrets"))
-    {
-        remove(self);
-        return;
-    }
-
-    InitTrigger ();
-
-    self.touch = turret_targettrigger_touch;
-}
+void spawnfunc_turret_targettrigger();
+void turret_targettrigger_touch();
+
+void turret_targettrigger_touch()
+{
+    entity e;
+    if (self.cnt > time) return;
+    entity oldself;
+    oldself = self;
+
+    e = find(world, targetname, self.target);
+    while (e)
+    {
+        if (e.turrcaps_flags & TFL_TURRCAPS_RECIVETARGETS)
+        {
+            self = e;
+            if(e.turret_addtarget)
+                e.turret_addtarget(other,oldself);
+        }
+
+        e = find(e, targetname, oldself.target);
+    }
+
+    oldself.cnt = time + 0.5;
+
+    self = oldself;
+}
+
+/*QUAKED turret_targettrigger (.5 .5 .5) ?
+*/
+void spawnfunc_turret_targettrigger()
+{
+    if (!cvar("g_turrets"))
+    {
+        remove(self);
+        return;
+    }
+
+    InitTrigger ();
+
+    self.touch = turret_targettrigger_touch;
+}


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_targettrigger.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_tessla.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_tessla.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_tessla.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,178 +1,178 @@
-void spawnfunc_turret_tesla();
-void turret_tesla_dinit();
-void turret_tesla_fire();
-
-.float toasted;
-entity toast(entity from, float range, float damage)
-{
-    entity e;
-    entity etarget;
-    float d,dd;
-
-    dd = range + 1;
-
-    e = findradius(from.origin,range);
-    while (e)
-    {
-        if ((e.toasted != 1) && (e != from))
-            if (turret_validate_target(self,e,self.target_validate_flags) > 0)
-            {
-                traceline(from.origin,e.origin,MOVE_WORLDONLY,from);
-                if (trace_fraction == 1.0)
-                {
-                    d = vlen(e.origin - from.origin);
-                    if (d < dd)
-                    {
-                        dd = d;
-                        etarget = e;
-                    }
-                }
-            }
-        e = e.chain;
-    }
-
-    if (etarget)
-    {
-        te_smallflash(etarget.origin);
-        te_csqc_lightningarc(from.origin,etarget.origin);
-        Damage(etarget,self,self,damage,DEATH_TURRET,etarget.origin,'0 0 0');
-        etarget.toasted = 1;
-    }
-
-    return etarget;
-}
-
-float turret_tesla_firecheck()
-{
-    if not (turret_stdproc_firecheck())
-        return 0;
-
-    self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                                 TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
-
-    self.enemy = turret_select_target();
-
-    if(self.enemy)
-        return 1;
-
-    return 0;
-
-}
-
-void turret_tesla_fire()
-{
-    entity e,t;
-    float d,r,i;
-
-    //w_deathtypestring = "discoverd how a tesla coil works";
-
-    d = self.shot_dmg;
-    r = self.target_range;
-    e = spawn();
-    setorigin(e,self.tur_shotorg);
-
-
-    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                                 TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
-
-    t = toast(e,r,d);
-    remove(e);
-
-    if (t == world) return;
-
-    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                                 TFL_TARGETSELECT_TEAMCHECK;
-
-    self.attack_finished_single = time + self.shot_refire;
-    for (i = 0; i < 10; ++i)
-    {
-        d *= 0.5;
-        r *= 0.85;
-        t = toast(t,r,d);
-        if (t == world) break;
-    }
-
-    e = findchainfloat(toasted, 1);
-    while (e)
-    {
-        e.toasted = 0;
-        e = e.chain;
-    }
-}
-
-void turret_tesla_postthink()
-{
-    if not (self.tur_active)
-    {
-        self.tur_head.avelocity = '0 0 0';
-        return;
-    }
-
-    if(self.ammo < self.shot_dmg)
-    {
-        self.tur_head.avelocity = '0 9 0' * (self.ammo / self.shot_dmg);
-    }
-    else
-    {
-        self.tur_head.avelocity = '0 90 0' * (self.ammo / self.shot_dmg);
-
-        if(self.attack_finished_single > time)
-            return;
-
-        float f;
-        f = (self.ammo / self.ammo_max);
-        f = f*f;
-        if(f > random())
-            if(random() < 0.1)
-                te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350));
-    }
-}
-
-
-void turret_tesla_dinit()
-{
-    if (self.netname == "")      self.netname     = "Tesla Coil";
-
-    self.turrcaps_flags      = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
-
-    self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                               TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
-
-    self.firecheck_flags     = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_OWM_AMMO;
-    self.shoot_flags         = TFL_SHOOT_CUSTOM;
-    self.ammo_flags          = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-    self.aim_flags           = TFL_AIM_NO;
-    self.track_flags         = TFL_TRACK_NO;
-
-    if (turret_stdproc_init("tesla_std",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    setmodel(self,"models/turrets/tesla_base.md3");
-    setmodel(self.tur_head,"models/turrets/tesla_head.md3");
-
-    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
-                                 TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
-
-    if (!turret_tag_setup())
-        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
-
-    self.turret_firefunc      = turret_tesla_fire;
-    self.turret_postthink     = turret_tesla_postthink;
-    self.turret_firecheckfunc = turret_tesla_firecheck;
-}
-
-/*QUAKED turret_tesla (0 .5 .8) ?
-*/
-void spawnfunc_turret_tesla()
-{
-    precache_model ("models/turrets/tesla_head.md3");
-    precache_model ("models/turrets/tesla_base.md3");
-
-
-    self.think = turret_tesla_dinit;
-    self.nextthink = time + 0.5;
-}
-
+void spawnfunc_turret_tesla();
+void turret_tesla_dinit();
+void turret_tesla_fire();
+
+.float toasted;
+entity toast(entity from, float range, float damage)
+{
+    entity e;
+    entity etarget;
+    float d,dd;
+
+    dd = range + 1;
+
+    e = findradius(from.origin,range);
+    while (e)
+    {
+        if ((e.toasted != 1) && (e != from))
+            if (turret_validate_target(self,e,self.target_validate_flags) > 0)
+            {
+                traceline(from.origin,e.origin,MOVE_WORLDONLY,from);
+                if (trace_fraction == 1.0)
+                {
+                    d = vlen(e.origin - from.origin);
+                    if (d < dd)
+                    {
+                        dd = d;
+                        etarget = e;
+                    }
+                }
+            }
+        e = e.chain;
+    }
+
+    if (etarget)
+    {
+        te_smallflash(etarget.origin);
+        te_csqc_lightningarc(from.origin,etarget.origin);
+        Damage(etarget,self,self,damage,DEATH_TURRET,etarget.origin,'0 0 0');
+        etarget.toasted = 1;
+    }
+
+    return etarget;
+}
+
+float turret_tesla_firecheck()
+{
+    if not (turret_stdproc_firecheck())
+        return 0;
+
+    self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+                                 TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
+
+    self.enemy = turret_select_target();
+
+    if(self.enemy)
+        return 1;
+
+    return 0;
+
+}
+
+void turret_tesla_fire()
+{
+    entity e,t;
+    float d,r,i;
+
+    //w_deathtypestring = "discoverd how a tesla coil works";
+
+    d = self.shot_dmg;
+    r = self.target_range;
+    e = spawn();
+    setorigin(e,self.tur_shotorg);
+
+
+    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+                                 TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
+
+    t = toast(e,r,d);
+    remove(e);
+
+    if (t == world) return;
+
+    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+                                 TFL_TARGETSELECT_TEAMCHECK;
+
+    self.attack_finished_single = time + self.shot_refire;
+    for (i = 0; i < 10; ++i)
+    {
+        d *= 0.5;
+        r *= 0.85;
+        t = toast(t,r,d);
+        if (t == world) break;
+    }
+
+    e = findchainfloat(toasted, 1);
+    while (e)
+    {
+        e.toasted = 0;
+        e = e.chain;
+    }
+}
+
+void turret_tesla_postthink()
+{
+    if not (self.tur_active)
+    {
+        self.tur_head.avelocity = '0 0 0';
+        return;
+    }
+
+    if(self.ammo < self.shot_dmg)
+    {
+        self.tur_head.avelocity = '0 9 0' * (self.ammo / self.shot_dmg);
+    }
+    else
+    {
+        self.tur_head.avelocity = '0 90 0' * (self.ammo / self.shot_dmg);
+
+        if(self.attack_finished_single > time)
+            return;
+
+        float f;
+        f = (self.ammo / self.ammo_max);
+        f = f*f;
+        if(f > random())
+            if(random() < 0.1)
+                te_csqc_lightningarc(self.tur_shotorg,self.tur_shotorg + (randomvec() * 350));
+    }
+}
+
+
+void turret_tesla_dinit()
+{
+    if (self.netname == "")      self.netname     = "Tesla Coil";
+
+    self.turrcaps_flags      = TFL_TURRCAPS_HITSCAN | TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MISSILEKILL;
+
+    self.target_select_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+                               TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
+
+    self.firecheck_flags     = TFL_FIRECHECK_REFIRE | TFL_FIRECHECK_OWM_AMMO;
+    self.shoot_flags         = TFL_SHOOT_CUSTOM;
+    self.ammo_flags          = TFL_AMMO_ENERGY | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+    self.aim_flags           = TFL_AIM_NO;
+    self.track_flags         = TFL_TRACK_NO;
+
+    if (turret_stdproc_init("tesla_std",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    setmodel(self,"models/turrets/tesla_base.md3");
+    setmodel(self.tur_head,"models/turrets/tesla_head.md3");
+
+    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_MISSILES |
+                                 TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK;
+
+    if (!turret_tag_setup())
+        dprint("Warning: Turret ",self.classname, " faild to initialize md3 tags\n");
+
+    self.turret_firefunc      = turret_tesla_fire;
+    self.turret_postthink     = turret_tesla_postthink;
+    self.turret_firecheckfunc = turret_tesla_firecheck;
+}
+
+/*QUAKED turret_tesla (0 .5 .8) ?
+*/
+void spawnfunc_turret_tesla()
+{
+    precache_model ("models/turrets/tesla_head.md3");
+    precache_model ("models/turrets/tesla_base.md3");
+
+
+    self.think = turret_tesla_dinit;
+    self.nextthink = time + 0.5;
+}
+


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_tessla.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/tturrets/units/unit_walker.qc
===================================================================
--- trunk/data/qcsrc/server/tturrets/units/unit_walker.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/tturrets/units/unit_walker.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,1022 +1,1022 @@
-#define ANIM_NO         0
-#define ANIM_REVERSE    1
-#define ANIM_WALK       2
-#define ANIM_RUN        3
-#define ANIM_STRAFE_L   4
-#define ANIM_STRAFE_R   5
-#define ANIM_TURN       6
-#define ANIM_JUMP       7
-#define ANIM_LAND       8
-#define ANIM_PAIN       9
-#define ANIM_MEELE      10
-#define ANIM_SWIM       11
-#define ANIM_ROAM       12
-
-#define WVM_IDLE_UP 25
-#define WVM_IDLE    50
-
-#define WVM_PATH  1000
-#define WVM_ENEMY 2000
-#define WVM_STOP  3000
-#define WVM_DODGE 4000
-#define  WVM_PANIC 10000
-#define walker_verbs_move verbs_move
-
-#define WVA_MINIGUN 100
-#define WVA_ROCKET  500
-#define WVA_MEELE   1000
-#define walker_verbs_attack verbs_attack
-
-#define WVI_IDLE 1
-#define WVI_ROAM 10
-#define walker_verbs_idle verbs_idle
-
-.float animflag;
-.entity wkr_spawn;
-
-#define WALKER_MIN '-70 -70 5'
-#define WALKER_MAX '70 70 70'
-
-#define WALKER_PATH(s,e) pathlib_astar(s,e)
-
-float walker_firecheck()
-{
-    if (self.animflag == ANIM_MEELE)
-        return 0;
-
-    return turret_stdproc_firecheck();
-}
-
-void walker_meele_do_dmg()
-{
-    vector where;
-    entity e;
-    makevectors(self.angles);
-    where = self.origin + v_forward * 128;
-
-    //w_deathtypestring = "tried to hug the cute spider thingy.";
-    e = findradius(where,64);
-    while (e)
-    {
-        if (turret_validate_target(self,e,self.target_validate_flags))
-            if (e != self && e.owner != self)
-                Damage(e,self,self,cvar("g_turrets_unit_walker_std_meele_dmg"),DEATH_TURRET,'0 0 0', v_forward * cvar("g_turrets_unit_walker_std_meele_force") );
-
-        e = e.chain;
-    }
-}
-
-void walker_animate()
-{
-    vector real_angle;
-    float  vz;
-
-    real_angle = vectoangles(self.steerto) - self.angles;
-    vz         = self.velocity_z;
-
-    if (self.tur_head.frame != 0)
-        self.tur_head.frame = self.tur_head.frame +1;
-
-    if (self.tur_head.frame > 12)
-        self.tur_head.frame = 0;
-
-    switch (self.animflag)
-    {
-
-    case ANIM_NO:
-        if (self.frame != 0)
-            self.frame = 0;
-
-        movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));
-
-        break;
-
-    case ANIM_REVERSE:
-        if ((self.frame < 5) || (self.frame > 25))
-            self.frame = 25;
-
-        self.frame = self.frame -1;
-        movelib_move_simple(v_forward * -1 ,cvar("g_turrets_unit_walker_speed_walk"),0.6);
-
-        if (self.frame < 5)
-            self.frame = 25;
-
-        break;
-
-    case ANIM_TURN:
-
-        if ((self.frame < 30) || (self.frame > 55))
-            self.frame = 30;
-
-        self.frame = self.frame + 1;
-
-        self.angles_y += bound(-15,shortangle_f(real_angle_y,self.angles_y),15);
-
-        movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));
-
-        if (self.frame > 55)
-            self.frame = 35;
-
-        break;
-
-    case ANIM_WALK:
-        if ((self.frame < 5) || (self.frame > 25))
-            self.frame = 5;
-
-        self.frame = self.frame +1;
-        self.angles_y += bound(-10,shortangle_f(real_angle_y,self.angles_y),10);
-        movelib_move_simple(v_forward ,cvar("g_turrets_unit_walker_speed_walk"),0.6);
-
-        if (self.frame > 25)
-            self.frame = 5;
-
-        break;
-
-    case ANIM_ROAM:
-        if ((self.frame < 5) || (self.frame > 25))
-            self.frame = 5;
-
-        self.frame = self.frame +1;
-
-        self.angles_y += bound(-5,shortangle_f(real_angle_y,self.angles_y),5);
-
-        movelib_move_simple(v_forward ,cvar("g_turrets_unit_walker_speed_roam"),0.5);
-
-        if (self.frame > 25)
-            self.frame = 5;
-
-        break;
-
-    case ANIM_SWIM:
-        if ((self.frame < 142) || (self.frame > 151))
-            self.frame = 142;
-
-        self.frame = self.frame +1;
-
-        self.angles_y += bound(-10,shortangle_f(real_angle_y,self.angles_y),10);
-        self.angles_x += bound(-10,shortangle_f(real_angle_x,self.angles_x),10);
-
-        movelib_move_simple(v_forward, cvar("g_turrets_unit_walker_speed_swim"),0.3);
-        vz = self.velocity_z + sin(time * 4) * 8;
-
-        if (self.frame > 151)
-            self.frame = 146;
-
-        break;
-
-    case ANIM_RUN:
-
-        if ((self.frame < 5) || (self.frame > 25))
-            self.frame = 5;
-
-        self.angles_y += bound(-5,shortangle_f(real_angle_y,self.angles_y),5);
-        movelib_move_simple(v_forward, cvar("g_turrets_unit_walker_speed_run"),0.6);
-
-        if (self.frame > 25)
-            self.frame = 5;
-
-        break;
-
-    case ANIM_STRAFE_L:
-        if ((self.frame < 30) || (self.frame > 55))
-            self.frame = 30;
-
-        self.frame = self.frame + 1;
-        self.angles_y += bound(-2.5,shortangle_f(real_angle_y,self.angles_y),2.5);
-        movelib_move_simple(v_right * -1, cvar("g_turrets_unit_walker_speed_walk"),0.8);
-
-        if (self.frame > 55)
-            self.frame = 35;
-        break;
-
-    case ANIM_STRAFE_R:
-        if ((self.frame < 60) || (self.frame > 65))
-            self.frame = 60;
-
-        self.frame = self.frame + 1;
-        self.angles_y += bound(-2.5,shortangle_f(real_angle_y,self.angles_y),2.5);
-        movelib_move_simple(v_right, cvar("g_turrets_unit_walker_speed_walk"),0.8);
-
-        if (self.frame > 85)
-            self.frame = 65;
-
-        break;
-
-    case ANIM_JUMP:
-        if ((self.frame < 95) || (self.frame > 100))
-            self.frame = 95;
-
-        self.velocity += '0 0 1' * cvar("g_turrets_unit_walker_speed_jump");
-
-        if (self.frame > 100)
-            self.frame = self.frame + 1;
-
-        break;
-
-    case ANIM_LAND:
-        if ((self.frame < 100) || (self.frame > 107))
-            self.frame = 100;
-
-        self.frame = self.frame + 1;
-
-        if (self.frame > 107)
-            self.animflag = ANIM_NO;
-
-        break;
-
-    case ANIM_PAIN:
-        if ((self.frame < 60) || (self.frame > 95))
-            self.frame = 90;
-
-        self.frame = self.frame + 1;
-
-        if (self.frame > 95)
-            self.animflag = ANIM_NO;
-
-        break;
-
-    case ANIM_MEELE:
-        if ((self.frame < 123) || (self.frame > 140))
-            self.frame = 123;
-
-        movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));
-
-        self.frame = self.frame + 2;
-
-        if (self.frame == 133)
-            walker_meele_do_dmg();
-
-        if (self.frame > 140)
-        {
-            self.animflag = ANIM_NO;
-            self.frame = 0;
-        }
-    }
-
-    self.velocity_z = vz;
-
-    if (self.flags & FL_ONGROUND)
-        movelib_groundalign4point(300,100,0.25);
-
-}
-
-
-void walker_rocket_explode()
-{
-    vector org2;
-
-    if (self.event_damage != SUB_Null)
-    {
-        self.event_damage = SUB_Null;
-        self.think = walker_rocket_explode;
-        self.nextthink = time;
-        return;
-    }
-
-    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
-    org2 = findbetterlocation (self.origin, 16);
-
-    pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
-    //w_deathtypestring = "got blasted to oblivion";
-    RadiusDamage (self, self.owner, cvar("g_turrets_unit_walker_std_rocket_dmg"), 0, cvar("g_turrets_unit_walker_std_rocket_radius"), world, cvar("g_turrets_unit_walker_std_rocket_force"), DEATH_TURRET, world);
-
-    remove (self);
-}
-
-void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
-{
-    self.health = self.health - damage;
-    self.velocity = self.velocity + vforce;
-    if (self.health <= 0)
-        walker_rocket_explode();
-}
-
-#define WALKER_ROCKET_MOVE movelib_move_simple(newdir,cvar("g_turrets_unit_walker_std_rocket_speed"),cvar("g_turrets_unit_walker_std_rocket_tunrate")); UpdateCSQCProjectile(self)
-void walker_rocket_loop();
-void walker_rocket_think()
-{
-    vector newdir;
-    float edist;
-    float itime;
-    float m_speed;
-
-    self.nextthink = time;
-
-    edist = vlen(self.enemy.origin - self.origin);
-
-    // Simulate crude guidance
-    if (self.cnt < time)
-    {
-        if (edist < 1000)
-            self.tur_shotorg = randomvec() * min(edist,64);
-        else
-            self.tur_shotorg = randomvec() * min(edist,256);
-
-        self.cnt = time + 0.5;
-    }
-
-    if (edist < 256)
-        self.tur_shotorg = '0 0 0';
-
-
-    if (self.tur_health < time)
-    {
-        self.think = walker_rocket_explode;
-        self.nextthink = time;
-        return;
-    }
-
-    if (self.shot_dmg != 1337)
-        if (random() < 0.01)
-        {
-            walker_rocket_loop();
-            return;
-        }
-
-    m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
-
-    // Enemy dead? just keep on the current heading then.
-    if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
-    {
-        // Make sure we dont return to tracking a respawned player
-        self.enemy = world;
-    }
-
-    if (self.enemy)
-    {
-        itime = max(edist / m_speed,1);
-        newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);
-    }
-    else
-    {
-        newdir  = normalize(self.velocity);
-    }
-
-    WALKER_ROCKET_MOVE;
-}
-
-void walker_rocket_loop3()
-{
-    vector newdir;
-    self.nextthink = time;
-
-    if (self.tur_health < time)
-    {
-        self.think = walker_rocket_explode;
-        return;
-    }
-
-    if (vlen(self.origin - self.tur_shotorg) < 128 )
-    {
-        self.think = walker_rocket_think;
-        return;
-    }
-
-    newdir = steerlib_pull(self.tur_shotorg);
-    WALKER_ROCKET_MOVE;
-
-    self.angles = vectoangles(self.velocity);
-}
-
-void walker_rocket_loop2()
-{
-    vector newdir;
-
-    self.nextthink = time;
-
-    if (self.tur_health < time)
-    {
-        self.think = walker_rocket_explode;
-        return;
-    }
-
-    if (vlen(self.origin - self.tur_shotorg) < 128 )
-    {
-        self.tur_shotorg = self.origin - '0 0 200';
-        self.think = walker_rocket_loop3;
-        return;
-    }
-
-    newdir = steerlib_pull(self.tur_shotorg);
-    WALKER_ROCKET_MOVE;
-}
-
-void walker_rocket_loop()
-{
-    self.nextthink = time;
-    self.tur_shotorg = self.origin + '0 0 400';
-    self.think = walker_rocket_loop2;
-    self.shot_dmg = 1337;
-}
-
-void walker_fire_rocket(vector org)
-{
-
-    entity rocket;
-
-
-    self.angles_x *= -1;
-    makevectors(self.angles);
-    self.angles_x *= -1;
-
-    te_explosion (org);
-
-    rocket = spawn ();
-    setorigin(rocket, org);
-
-    sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
-    setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
-
-    rocket.classname          = "walker_rocket";
-    rocket.owner              = self;
-
-    rocket.bot_dodge          = TRUE;
-    rocket.bot_dodgerating    = 50;
-
-    rocket.takedamage         = DAMAGE_YES;
-
-    rocket.damageforcescale   = 2;
-    rocket.health             = 25;
-    rocket.tur_shotorg        = randomvec() * 512;
-    rocket.cnt                = time + 1;
-    rocket.enemy              = self.enemy;
-
-    if (random() < 0.01)
-        rocket.think          = walker_rocket_loop;
-    else
-        rocket.think          = walker_rocket_think;
-
-    rocket.event_damage       = walker_rocket_damage;
-
-    rocket.nextthink          = time;// + 0.25;
-    rocket.movetype           = MOVETYPE_FLY;
-    rocket.velocity           = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * cvar("g_turrets_unit_walker_std_rocket_speed");
-    rocket.angles             = vectoangles(rocket.velocity);
-    rocket.touch              = walker_rocket_explode;
-    rocket.flags              = FL_PROJECTILE;
-    rocket.solid              = SOLID_BBOX;
-    rocket.tur_health         = time + 9;
-
-    CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
-}
-
-void rv_think()
-{
-    float f;
-    vector org;
-    entity oldself;
-
-    if (self.owner.deadflag != DEAD_NO)
-    {
-        remove(self);
-        return;
-    }
-
-    self.cnt = self.cnt -1;
-
-    if (self.cnt < 0)
-    {
-        remove(self);
-        return;
-    }
-
-    if (self.cnt > 1)
-        f = gettagindex(self.owner,"tag_rocket01");
-    else
-        f = gettagindex(self.owner,"tag_rocket02");
-
-    org = gettaginfo(self.owner,f);
-
-    self.nextthink = time + 0.2;
-    oldself = self;
-    self = self.owner;
-    walker_fire_rocket(org);
-    self = oldself;
-}
-
-float walker_moveverb_path(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-
-        if (self.animflag == ANIM_MEELE)
-            return VS_CALL_NO;
-
-        if (self.pathcurrent)
-            return verb.verb_static_value;
-
-        return VS_CALL_NO;
-
-    case VCM_DO:
-        // Do we have a path?
-        if not(self.pathcurrent)
-        {
-            return VS_CALL_NO;
-        }
-        else
-        {
-            // Are we close enougth to a path node to switch to the next?
-            if (vlen(self.origin  - self.pathcurrent.origin) < 64)
-                if (self.pathcurrent.path_next == world)
-                {
-                    // Path endpoint reached
-                    pathlib_deletepath(self.pathcurrent.owner);
-                    self.pathcurrent = world;
-
-                    if (self.pathgoal)
-                    {
-                        if (self.pathgoal.use)
-                            self.pathgoal.use();
-
-                        if (self.pathgoal.enemy)
-                        {
-                            self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);
-                            self.pathgoal = self.pathgoal.enemy;
-                        }
-                    }
-                    else
-                        self.pathgoal = world;
-                }
-                else
-                    self.pathcurrent = self.pathcurrent.path_next;
-        }
-
-
-        if (self.pathcurrent)
-        {
-            switch (self.waterlevel)
-            {
-            case 0:
-                self.animflag = ANIM_WALK;
-            case 1:
-            case 2:
-                if (self.animflag == ANIM_WALK)
-                    self.animflag = ANIM_WALK;
-                else
-                    self.animflag = ANIM_SWIM;
-                break;
-            case 3:
-                self.animflag = ANIM_SWIM;
-            }
-
-            self.moveto = self.pathcurrent.origin;
-            self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
-
-            return VS_CALL_YES_DOING;
-        }
-        else
-            return VS_CALL_YES_DONE;
-
-    case VCM_REMOVE:
-
-        if (self.pathcurrent)
-            pathlib_deletepath(self.pathcurrent.owner);
-
-        self.pathcurrent = world;
-
-        return VS_CALL_YES_DONE;
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-float walker_moveverb_enemy(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-
-        if (self.enemy)
-            if (self.spawnflags & TSF_NO_PATHBREAK)
-                if (self.pathcurrent)
-                    return VS_CALL_NO;
-
-        if (self.animflag == ANIM_MEELE)
-            return VS_CALL_NO;
-
-        if (self.enemy == world)
-            return VS_CALL_NO;
-
-        //if (tracewalk(self.enemy, self.origin, self.mins, self.maxs, self.enemy.origin, MOVE_NORMAL))
-        return verb.verb_static_value;
-
-        //return VS_CALL_NO;
-
-    case VCM_DO:
-        switch (self.waterlevel)
-        {
-        case 0:
-            if (self.tur_dist_enemy > 500)
-                self.animflag = ANIM_RUN;
-            else
-                self.animflag = ANIM_WALK;
-        case 1:
-        case 2:
-            if (self.animflag != ANIM_SWIM)
-                self.animflag = ANIM_WALK;
-            else
-                self.animflag = ANIM_SWIM;
-            break;
-        case 3:
-            self.animflag = ANIM_SWIM;
-        }
-
-        self.moveto = self.enemy.origin;
-        self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
-
-        return VS_CALL_YES_DOING;
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-float walker_moveverb_idle_pause(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-
-        if (self.animflag == ANIM_MEELE)
-            return VS_CALL_NO;
-
-        return verb.verb_static_value;
-
-    case VCM_DO:
-
-        self.moveto   = self.origin;
-        self.steerto  = v_forward;
-        self.animflag = ANIM_NO;
-
-        return VS_CALL_YES_DOING;
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-float walker_moveverb_idle_roam(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-
-        if (self.animflag == ANIM_MEELE)
-            return VS_CALL_NO;
-
-        return verb.verb_static_value;
-
-    case VCM_DO:
-        if(verb.wait < time)
-        {
-            trace_fraction = 0;
-            while(trace_fraction != 1.0)
-            {
-                self.moveto = self.origin + (v_forward * 256);
-                self.moveto += v_right * (random() * 256);
-                self.moveto -= v_right * (random() * 256);
-
-                tracebox(self.origin+'0 0 64',self.mins,self.maxs,self.moveto + '0 0 64',MOVE_NORMAL,self);
-            }
-            verb.wait = time + 10;
-        }
-        else
-        {
-            if(verb.wait - time < 9)
-                if(vlen(self.moveto - self.origin) < 32)
-                {
-                    verbstack_push(self.walker_verbs_move, walker_moveverb_idle_pause,   WVM_IDLE + WVM_IDLE_UP, random() * (verb.wait - time), self);
-                    self.animflag = ANIM_NO;
-                    return VS_CALL_REMOVE;
-                }
-        }
-
-        self.steerto = steerlib_attract(self.moveto,256);
-        te_lightning1(self,self.origin + '0 0 64',self.moveto + '0 0 64');
-
-
-
-        switch (self.waterlevel)
-        {
-        case 0:
-            self.animflag = ANIM_ROAM;
-        case 1:
-        case 2:
-            if (self.animflag != ANIM_SWIM)
-                self.animflag = ANIM_ROAM;
-
-            break;
-        case 3:
-            self.animflag = ANIM_SWIM;
-        }
-
-        return VS_CALL_YES_DOING;
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-float walker_moveverb_idle(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-
-        if (self.animflag == ANIM_MEELE)
-            return VS_CALL_NO;
-
-        return verb.verb_static_value;
-
-    case VCM_DO:
-
-        //if (random() < 0.5)
-            verbstack_push(self.walker_verbs_move, walker_moveverb_idle_pause,   WVM_IDLE + WVM_IDLE_UP, random() * 5, self);
-        //else
-        //    verbstack_push(self.walker_verbs_move, walker_moveverb_idle_roam,   WVM_IDLE + WVM_IDLE_UP,  random() * 15);
-
-        return VS_CALL_YES_DOING;
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-float walker_attackverb_meele(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-
-        vector wish_angle;
-
-        if (cvar("g_turrets_nofire"))
-            return VS_CALL_NO;
-
-        if (self.animflag == ANIM_SWIM || self.animflag == ANIM_MEELE)
-            return VS_CALL_NO;
-
-        if (!self.enemy)
-            return VS_CALL_NO;
-
-        wish_angle = angleofs(self,self.enemy);
-
-        if (self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_meele_range"))
-            if (fabs(wish_angle_y) < 15)
-                return verb.verb_static_value;
-
-        return VS_CALL_NO;
-
-    case VCM_DO:
-
-        self.moveto   = self.enemy.origin;
-        self.steerto  = steerlib_attract2(self.moveto,0.5,500,0.95);
-        self.animflag = ANIM_MEELE;
-
-        return VS_CALL_YES_DOING;
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-float walker_attackverb_rockets(float eval)
-{
-    switch (eval)
-    {
-    case VCM_EVAL:
-        if (self.tur_head.attack_finished_single > time)
-            return VS_CALL_NO;
-
-        if not(self.enemy)
-            return VS_CALL_NO;
-
-        if (cvar("g_turrets_nofire"))
-            return VS_CALL_NO;
-
-        if (self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_rockets_range_min"))
-            return VS_CALL_NO;
-
-        if (self.tur_dist_enemy > cvar("g_turrets_unit_walker_std_rockets_range"))
-            return VS_CALL_NO;
-
-        return verb.verb_static_value;
-
-    case VCM_DO:
-
-        entity rv;
-
-        rv           = spawn();
-        rv.think     = rv_think;
-        rv.nextthink = time;
-        rv.cnt       = 4;
-        rv.owner     = self;
-
-        self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire");
-
-        return VS_CALL_YES_DONE;
-    }
-
-    return VS_CALL_YES_DONE;
-}
-
-void walker_postthink()
-{
-
-    self.angles_x *= -1;
-    makevectors(self.angles);
-    self.angles_x *= -1;
-
-    verbstack_pop(self.walker_verbs_attack);
-    verbstack_pop(self.walker_verbs_move);
-
-    walker_animate();
-}
-
-void walker_attack()
-{
-    entity flash;
-
-    //w_deathtypestring = "was miniguned";
-    sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);
-    fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant"));
-    if (self.uzi_bulletcounter == 2)
-    {
-
-        flash = spawn();
-
-        setmodel(flash, "models/uziflash.md3");
-        setattachment(flash, self.tur_head, "tag_fire");
-
-        flash.scale     = 3;
-        flash.think     = W_Uzi_Flash_Go;
-        flash.nextthink = time + 0.02;
-        flash.frame     = 2;
-        flash.angles_z  = flash.v_angle_z + random() * 180;
-        flash.alpha     = 1;
-        flash.effects   = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
-
-        self.uzi_bulletcounter = self.uzi_bulletcounter = 0;
-    }
-
-    self.uzi_bulletcounter = self.uzi_bulletcounter + 1;
-    self.tur_head.frame    = self.tur_head.frame + 1;
-}
-
-
-void walker_respawnhook()
-{
-    vector vtmp;
-    entity e;
-
-    self.origin = self.wkr_spawn.origin;
-    //self.wkr_props.solid = SOLID_BBOX;
-    //self.wkr_props.alpha = 1;
-
-    self.angles = self.wkr_spawn.angles;
-    vtmp = self.wkr_spawn.origin;
-    vtmp_z += self.wkr_spawn.maxs_z;
-    setorigin(self,vtmp);
-
-    if (self.target != "")
-    {
-        e = find(world,targetname,self.target);
-        if (!e)
-        {
-            dprint("Warning! initital waypoint for Walker does NOT exsist!\n");
-            self.target = "";
-        }
-
-        if (e.classname != "turret_checkpoint")
-            dprint("Warning: not a turrret path\n");
-        else
-        {
-            self.pathcurrent = WALKER_PATH(self.origin,e.origin);
-            self.pathgoal = e;
-        }
-    }
-}
-void walker_diehook()
-{
-    turret_trowgib2(self.origin,self.velocity + v_up * 200,'-0.6 -0.2 -02',self,time + random() * 1);
-    turret_trowgib2(self.origin + '0 0 64',self.velocity + v_forward * 150 + v_up * 150,'-0.2 -0.2 -02',self.tur_head,time + random() * 2 + 3);
-
-    if (self.pathcurrent)
-        pathlib_deletepath(self.pathcurrent.owner);
-
-    self.pathcurrent = world;
-
-    if (self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
-    {
-        remove(self.wkr_spawn);
-
-        verbstack_flush(self.walker_verbs_move);
-        verbstack_flush(self.walker_verbs_attack);
-        verbstack_flush(self.walker_verbs_idle);
-
-        remove(self.walker_verbs_move);
-        remove(self.walker_verbs_attack);
-        remove(self.walker_verbs_idle);
-    }
-
-}
-
-void turret_walker_dinit()
-{
-
-    entity e;
-
-    if (self.netname == "")      self.netname     = "Walker Turret";
-    self.wkr_spawn = spawn();
-
-    self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
-    self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_HEADATTACHED;
-    self.aim_flags = TFL_AIM_LEAD;
-
-    if (cvar("g_antilag_bullets"))
-        self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
-    else
-        self.aim_flags      |= TFL_AIM_SHOTTIMECOMPENSATE;
-
-
-    self.turret_respawnhook = walker_respawnhook;
-    self.turret_diehook = walker_diehook;
-
-    self.ticrate = 0.05;
-    if (turret_stdproc_init("walker_std",0) == 0)
-    {
-        remove(self);
-        return;
-    }
-
-    self.walker_verbs_move   = spawn();
-    self.walker_verbs_attack = spawn();
-    self.walker_verbs_idle   = spawn();
-
-    verbstack_push(self.walker_verbs_move, walker_moveverb_idle,   WVM_IDLE,  0, self);
-    verbstack_push(self.walker_verbs_move, walker_moveverb_enemy,  WVM_ENEMY, 0, self);
-    verbstack_push(self.walker_verbs_move, walker_moveverb_path,   WVM_PATH,  0, self);
-
-    verbstack_push(self.walker_verbs_attack, walker_attackverb_meele,   WVA_MEELE,  0, self);
-    verbstack_push(self.walker_verbs_attack, walker_attackverb_rockets, WVA_ROCKET, 0, self);
-
-    self.damage_flags |= TFL_DMG_DEATH_NOGIBS;
-
-    self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
-
-    self.iscreature = TRUE;
-    self.movetype   = MOVETYPE_WALK;
-    self.solid      = SOLID_SLIDEBOX;
-    self.takedamage = DAMAGE_AIM;
-
-    setmodel(self,"models/turrets/walker_body.md3");
-    setmodel(self.tur_head,"models/turrets/walker_head_minigun.md3");
-    setmodel(self.wkr_spawn,"models/turrets/walker_spawn.md3");
-
-    setattachment(self.tur_head,self,"tag_head");
-
-    self.wkr_spawn.angles   = self.angles;
-    self.wkr_spawn.solid    = SOLID_NOT;
-
-    traceline(self.origin + '0 0 16', self.origin - '0 0 10000', MOVE_WORLDONLY, self);
-    setorigin(self.wkr_spawn,trace_endpos + '0 0 4');
-    setorigin(self,self.wkr_spawn.origin);
-
-    setsize(self,WALKER_MIN,WALKER_MAX);
-
-    self.idle_aim = '0 0 0';
-    self.turret_firecheckfunc = walker_firecheck;
-    self.turret_firefunc      = walker_attack;
-    self.turret_postthink     = walker_postthink;
-
-    if (self.target != "")
-    {
-        e = find(world,targetname,self.target);
-        if (!e)
-        {
-            dprint("Initital waypoint for walker does NOT exsist, fix your map!\n");
-            self.target = "";
-        }
-
-        if (e.classname != "turret_checkpoint")
-            dprint("Warning: not a turrret path\n");
-        else
-        {
-            self.pathcurrent = WALKER_PATH(self.origin,e.origin);
-            self.pathgoal = e;
-        }
-    }
-}
-
-
-void spawnfunc_turret_walker()
-{
-    g_turrets_common_precash();
-
-    precache_model ("models/turrets/walker_head_minigun.md3");
-    precache_model ("models/turrets/walker_body.md3");
-    precache_model ("models/turrets/walker_props.md3");
-    precache_model ("models/turrets/walker_spawn.md3");
-    precache_model ( "models/turrets/rocket.md3");
-    precache_sound ( "weapons/rocket_impact.wav" );
-
-    self.think = turret_walker_dinit;
-    self.nextthink = time + 0.5;
-}
+#define ANIM_NO         0
+#define ANIM_REVERSE    1
+#define ANIM_WALK       2
+#define ANIM_RUN        3
+#define ANIM_STRAFE_L   4
+#define ANIM_STRAFE_R   5
+#define ANIM_TURN       6
+#define ANIM_JUMP       7
+#define ANIM_LAND       8
+#define ANIM_PAIN       9
+#define ANIM_MEELE      10
+#define ANIM_SWIM       11
+#define ANIM_ROAM       12
+
+#define WVM_IDLE_UP 25
+#define WVM_IDLE    50
+
+#define WVM_PATH  1000
+#define WVM_ENEMY 2000
+#define WVM_STOP  3000
+#define WVM_DODGE 4000
+#define  WVM_PANIC 10000
+#define walker_verbs_move verbs_move
+
+#define WVA_MINIGUN 100
+#define WVA_ROCKET  500
+#define WVA_MEELE   1000
+#define walker_verbs_attack verbs_attack
+
+#define WVI_IDLE 1
+#define WVI_ROAM 10
+#define walker_verbs_idle verbs_idle
+
+.float animflag;
+.entity wkr_spawn;
+
+#define WALKER_MIN '-70 -70 5'
+#define WALKER_MAX '70 70 70'
+
+#define WALKER_PATH(s,e) pathlib_astar(s,e)
+
+float walker_firecheck()
+{
+    if (self.animflag == ANIM_MEELE)
+        return 0;
+
+    return turret_stdproc_firecheck();
+}
+
+void walker_meele_do_dmg()
+{
+    vector where;
+    entity e;
+    makevectors(self.angles);
+    where = self.origin + v_forward * 128;
+
+    //w_deathtypestring = "tried to hug the cute spider thingy.";
+    e = findradius(where,64);
+    while (e)
+    {
+        if (turret_validate_target(self,e,self.target_validate_flags))
+            if (e != self && e.owner != self)
+                Damage(e,self,self,cvar("g_turrets_unit_walker_std_meele_dmg"),DEATH_TURRET,'0 0 0', v_forward * cvar("g_turrets_unit_walker_std_meele_force") );
+
+        e = e.chain;
+    }
+}
+
+void walker_animate()
+{
+    vector real_angle;
+    float  vz;
+
+    real_angle = vectoangles(self.steerto) - self.angles;
+    vz         = self.velocity_z;
+
+    if (self.tur_head.frame != 0)
+        self.tur_head.frame = self.tur_head.frame +1;
+
+    if (self.tur_head.frame > 12)
+        self.tur_head.frame = 0;
+
+    switch (self.animflag)
+    {
+
+    case ANIM_NO:
+        if (self.frame != 0)
+            self.frame = 0;
+
+        movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));
+
+        break;
+
+    case ANIM_REVERSE:
+        if ((self.frame < 5) || (self.frame > 25))
+            self.frame = 25;
+
+        self.frame = self.frame -1;
+        movelib_move_simple(v_forward * -1 ,cvar("g_turrets_unit_walker_speed_walk"),0.6);
+
+        if (self.frame < 5)
+            self.frame = 25;
+
+        break;
+
+    case ANIM_TURN:
+
+        if ((self.frame < 30) || (self.frame > 55))
+            self.frame = 30;
+
+        self.frame = self.frame + 1;
+
+        self.angles_y += bound(-15,shortangle_f(real_angle_y,self.angles_y),15);
+
+        movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));
+
+        if (self.frame > 55)
+            self.frame = 35;
+
+        break;
+
+    case ANIM_WALK:
+        if ((self.frame < 5) || (self.frame > 25))
+            self.frame = 5;
+
+        self.frame = self.frame +1;
+        self.angles_y += bound(-10,shortangle_f(real_angle_y,self.angles_y),10);
+        movelib_move_simple(v_forward ,cvar("g_turrets_unit_walker_speed_walk"),0.6);
+
+        if (self.frame > 25)
+            self.frame = 5;
+
+        break;
+
+    case ANIM_ROAM:
+        if ((self.frame < 5) || (self.frame > 25))
+            self.frame = 5;
+
+        self.frame = self.frame +1;
+
+        self.angles_y += bound(-5,shortangle_f(real_angle_y,self.angles_y),5);
+
+        movelib_move_simple(v_forward ,cvar("g_turrets_unit_walker_speed_roam"),0.5);
+
+        if (self.frame > 25)
+            self.frame = 5;
+
+        break;
+
+    case ANIM_SWIM:
+        if ((self.frame < 142) || (self.frame > 151))
+            self.frame = 142;
+
+        self.frame = self.frame +1;
+
+        self.angles_y += bound(-10,shortangle_f(real_angle_y,self.angles_y),10);
+        self.angles_x += bound(-10,shortangle_f(real_angle_x,self.angles_x),10);
+
+        movelib_move_simple(v_forward, cvar("g_turrets_unit_walker_speed_swim"),0.3);
+        vz = self.velocity_z + sin(time * 4) * 8;
+
+        if (self.frame > 151)
+            self.frame = 146;
+
+        break;
+
+    case ANIM_RUN:
+
+        if ((self.frame < 5) || (self.frame > 25))
+            self.frame = 5;
+
+        self.angles_y += bound(-5,shortangle_f(real_angle_y,self.angles_y),5);
+        movelib_move_simple(v_forward, cvar("g_turrets_unit_walker_speed_run"),0.6);
+
+        if (self.frame > 25)
+            self.frame = 5;
+
+        break;
+
+    case ANIM_STRAFE_L:
+        if ((self.frame < 30) || (self.frame > 55))
+            self.frame = 30;
+
+        self.frame = self.frame + 1;
+        self.angles_y += bound(-2.5,shortangle_f(real_angle_y,self.angles_y),2.5);
+        movelib_move_simple(v_right * -1, cvar("g_turrets_unit_walker_speed_walk"),0.8);
+
+        if (self.frame > 55)
+            self.frame = 35;
+        break;
+
+    case ANIM_STRAFE_R:
+        if ((self.frame < 60) || (self.frame > 65))
+            self.frame = 60;
+
+        self.frame = self.frame + 1;
+        self.angles_y += bound(-2.5,shortangle_f(real_angle_y,self.angles_y),2.5);
+        movelib_move_simple(v_right, cvar("g_turrets_unit_walker_speed_walk"),0.8);
+
+        if (self.frame > 85)
+            self.frame = 65;
+
+        break;
+
+    case ANIM_JUMP:
+        if ((self.frame < 95) || (self.frame > 100))
+            self.frame = 95;
+
+        self.velocity += '0 0 1' * cvar("g_turrets_unit_walker_speed_jump");
+
+        if (self.frame > 100)
+            self.frame = self.frame + 1;
+
+        break;
+
+    case ANIM_LAND:
+        if ((self.frame < 100) || (self.frame > 107))
+            self.frame = 100;
+
+        self.frame = self.frame + 1;
+
+        if (self.frame > 107)
+            self.animflag = ANIM_NO;
+
+        break;
+
+    case ANIM_PAIN:
+        if ((self.frame < 60) || (self.frame > 95))
+            self.frame = 90;
+
+        self.frame = self.frame + 1;
+
+        if (self.frame > 95)
+            self.animflag = ANIM_NO;
+
+        break;
+
+    case ANIM_MEELE:
+        if ((self.frame < 123) || (self.frame > 140))
+            self.frame = 123;
+
+        movelib_beak_simple(cvar("g_turrets_unit_walker_speed_stop"));
+
+        self.frame = self.frame + 2;
+
+        if (self.frame == 133)
+            walker_meele_do_dmg();
+
+        if (self.frame > 140)
+        {
+            self.animflag = ANIM_NO;
+            self.frame = 0;
+        }
+    }
+
+    self.velocity_z = vz;
+
+    if (self.flags & FL_ONGROUND)
+        movelib_groundalign4point(300,100,0.25);
+
+}
+
+
+void walker_rocket_explode()
+{
+    vector org2;
+
+    if (self.event_damage != SUB_Null)
+    {
+        self.event_damage = SUB_Null;
+        self.think = walker_rocket_explode;
+        self.nextthink = time;
+        return;
+    }
+
+    sound (self, CHAN_PROJECTILE, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
+    org2 = findbetterlocation (self.origin, 16);
+
+    pointparticles(particleeffectnum("rocket_explode"), org2, '0 0 0', 1);
+    //w_deathtypestring = "got blasted to oblivion";
+    RadiusDamage (self, self.owner, cvar("g_turrets_unit_walker_std_rocket_dmg"), 0, cvar("g_turrets_unit_walker_std_rocket_radius"), world, cvar("g_turrets_unit_walker_std_rocket_force"), DEATH_TURRET, world);
+
+    remove (self);
+}
+
+void walker_rocket_damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector vforce)
+{
+    self.health = self.health - damage;
+    self.velocity = self.velocity + vforce;
+    if (self.health <= 0)
+        walker_rocket_explode();
+}
+
+#define WALKER_ROCKET_MOVE movelib_move_simple(newdir,cvar("g_turrets_unit_walker_std_rocket_speed"),cvar("g_turrets_unit_walker_std_rocket_tunrate")); UpdateCSQCProjectile(self)
+void walker_rocket_loop();
+void walker_rocket_think()
+{
+    vector newdir;
+    float edist;
+    float itime;
+    float m_speed;
+
+    self.nextthink = time;
+
+    edist = vlen(self.enemy.origin - self.origin);
+
+    // Simulate crude guidance
+    if (self.cnt < time)
+    {
+        if (edist < 1000)
+            self.tur_shotorg = randomvec() * min(edist,64);
+        else
+            self.tur_shotorg = randomvec() * min(edist,256);
+
+        self.cnt = time + 0.5;
+    }
+
+    if (edist < 256)
+        self.tur_shotorg = '0 0 0';
+
+
+    if (self.tur_health < time)
+    {
+        self.think = walker_rocket_explode;
+        self.nextthink = time;
+        return;
+    }
+
+    if (self.shot_dmg != 1337)
+        if (random() < 0.01)
+        {
+            walker_rocket_loop();
+            return;
+        }
+
+    m_speed = vlen(self.velocity) + cvar("g_turrets_unit_walker_std_rocket_speed_add");
+
+    // Enemy dead? just keep on the current heading then.
+    if ((self.enemy == world) || (self.enemy.deadflag != DEAD_NO))
+    {
+        // Make sure we dont return to tracking a respawned player
+        self.enemy = world;
+    }
+
+    if (self.enemy)
+    {
+        itime = max(edist / m_speed,1);
+        newdir = steerlib_pull(self.enemy.origin + self.tur_shotorg);
+    }
+    else
+    {
+        newdir  = normalize(self.velocity);
+    }
+
+    WALKER_ROCKET_MOVE;
+}
+
+void walker_rocket_loop3()
+{
+    vector newdir;
+    self.nextthink = time;
+
+    if (self.tur_health < time)
+    {
+        self.think = walker_rocket_explode;
+        return;
+    }
+
+    if (vlen(self.origin - self.tur_shotorg) < 128 )
+    {
+        self.think = walker_rocket_think;
+        return;
+    }
+
+    newdir = steerlib_pull(self.tur_shotorg);
+    WALKER_ROCKET_MOVE;
+
+    self.angles = vectoangles(self.velocity);
+}
+
+void walker_rocket_loop2()
+{
+    vector newdir;
+
+    self.nextthink = time;
+
+    if (self.tur_health < time)
+    {
+        self.think = walker_rocket_explode;
+        return;
+    }
+
+    if (vlen(self.origin - self.tur_shotorg) < 128 )
+    {
+        self.tur_shotorg = self.origin - '0 0 200';
+        self.think = walker_rocket_loop3;
+        return;
+    }
+
+    newdir = steerlib_pull(self.tur_shotorg);
+    WALKER_ROCKET_MOVE;
+}
+
+void walker_rocket_loop()
+{
+    self.nextthink = time;
+    self.tur_shotorg = self.origin + '0 0 400';
+    self.think = walker_rocket_loop2;
+    self.shot_dmg = 1337;
+}
+
+void walker_fire_rocket(vector org)
+{
+
+    entity rocket;
+
+
+    self.angles_x *= -1;
+    makevectors(self.angles);
+    self.angles_x *= -1;
+
+    te_explosion (org);
+
+    rocket = spawn ();
+    setorigin(rocket, org);
+
+    sound (self, CHAN_WEAPON, "weapons/hagar_fire.wav", VOL_BASE, ATTN_NORM);
+    setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
+
+    rocket.classname          = "walker_rocket";
+    rocket.owner              = self;
+
+    rocket.bot_dodge          = TRUE;
+    rocket.bot_dodgerating    = 50;
+
+    rocket.takedamage         = DAMAGE_YES;
+
+    rocket.damageforcescale   = 2;
+    rocket.health             = 25;
+    rocket.tur_shotorg        = randomvec() * 512;
+    rocket.cnt                = time + 1;
+    rocket.enemy              = self.enemy;
+
+    if (random() < 0.01)
+        rocket.think          = walker_rocket_loop;
+    else
+        rocket.think          = walker_rocket_think;
+
+    rocket.event_damage       = walker_rocket_damage;
+
+    rocket.nextthink          = time;// + 0.25;
+    rocket.movetype           = MOVETYPE_FLY;
+    rocket.velocity           = normalize((v_forward + v_up * 0.5) + (randomvec() * 0.2)) * cvar("g_turrets_unit_walker_std_rocket_speed");
+    rocket.angles             = vectoangles(rocket.velocity);
+    rocket.touch              = walker_rocket_explode;
+    rocket.flags              = FL_PROJECTILE;
+    rocket.solid              = SOLID_BBOX;
+    rocket.tur_health         = time + 9;
+
+    CSQCProjectile(rocket, FALSE, PROJECTILE_ROCKET, FALSE); // no culling, has fly sound
+}
+
+void rv_think()
+{
+    float f;
+    vector org;
+    entity oldself;
+
+    if (self.owner.deadflag != DEAD_NO)
+    {
+        remove(self);
+        return;
+    }
+
+    self.cnt = self.cnt -1;
+
+    if (self.cnt < 0)
+    {
+        remove(self);
+        return;
+    }
+
+    if (self.cnt > 1)
+        f = gettagindex(self.owner,"tag_rocket01");
+    else
+        f = gettagindex(self.owner,"tag_rocket02");
+
+    org = gettaginfo(self.owner,f);
+
+    self.nextthink = time + 0.2;
+    oldself = self;
+    self = self.owner;
+    walker_fire_rocket(org);
+    self = oldself;
+}
+
+float walker_moveverb_path(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+
+        if (self.animflag == ANIM_MEELE)
+            return VS_CALL_NO;
+
+        if (self.pathcurrent)
+            return verb.verb_static_value;
+
+        return VS_CALL_NO;
+
+    case VCM_DO:
+        // Do we have a path?
+        if not(self.pathcurrent)
+        {
+            return VS_CALL_NO;
+        }
+        else
+        {
+            // Are we close enougth to a path node to switch to the next?
+            if (vlen(self.origin  - self.pathcurrent.origin) < 64)
+                if (self.pathcurrent.path_next == world)
+                {
+                    // Path endpoint reached
+                    pathlib_deletepath(self.pathcurrent.owner);
+                    self.pathcurrent = world;
+
+                    if (self.pathgoal)
+                    {
+                        if (self.pathgoal.use)
+                            self.pathgoal.use();
+
+                        if (self.pathgoal.enemy)
+                        {
+                            self.pathcurrent = WALKER_PATH(self.pathgoal.origin,self.pathgoal.enemy.origin);
+                            self.pathgoal = self.pathgoal.enemy;
+                        }
+                    }
+                    else
+                        self.pathgoal = world;
+                }
+                else
+                    self.pathcurrent = self.pathcurrent.path_next;
+        }
+
+
+        if (self.pathcurrent)
+        {
+            switch (self.waterlevel)
+            {
+            case 0:
+                self.animflag = ANIM_WALK;
+            case 1:
+            case 2:
+                if (self.animflag == ANIM_WALK)
+                    self.animflag = ANIM_WALK;
+                else
+                    self.animflag = ANIM_SWIM;
+                break;
+            case 3:
+                self.animflag = ANIM_SWIM;
+            }
+
+            self.moveto = self.pathcurrent.origin;
+            self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
+
+            return VS_CALL_YES_DOING;
+        }
+        else
+            return VS_CALL_YES_DONE;
+
+    case VCM_REMOVE:
+
+        if (self.pathcurrent)
+            pathlib_deletepath(self.pathcurrent.owner);
+
+        self.pathcurrent = world;
+
+        return VS_CALL_YES_DONE;
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+float walker_moveverb_enemy(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+
+        if (self.enemy)
+            if (self.spawnflags & TSF_NO_PATHBREAK)
+                if (self.pathcurrent)
+                    return VS_CALL_NO;
+
+        if (self.animflag == ANIM_MEELE)
+            return VS_CALL_NO;
+
+        if (self.enemy == world)
+            return VS_CALL_NO;
+
+        //if (tracewalk(self.enemy, self.origin, self.mins, self.maxs, self.enemy.origin, MOVE_NORMAL))
+        return verb.verb_static_value;
+
+        //return VS_CALL_NO;
+
+    case VCM_DO:
+        switch (self.waterlevel)
+        {
+        case 0:
+            if (self.tur_dist_enemy > 500)
+                self.animflag = ANIM_RUN;
+            else
+                self.animflag = ANIM_WALK;
+        case 1:
+        case 2:
+            if (self.animflag != ANIM_SWIM)
+                self.animflag = ANIM_WALK;
+            else
+                self.animflag = ANIM_SWIM;
+            break;
+        case 3:
+            self.animflag = ANIM_SWIM;
+        }
+
+        self.moveto = self.enemy.origin;
+        self.steerto = steerlib_attract2(self.moveto,0.5,500,0.95);
+
+        return VS_CALL_YES_DOING;
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+float walker_moveverb_idle_pause(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+
+        if (self.animflag == ANIM_MEELE)
+            return VS_CALL_NO;
+
+        return verb.verb_static_value;
+
+    case VCM_DO:
+
+        self.moveto   = self.origin;
+        self.steerto  = v_forward;
+        self.animflag = ANIM_NO;
+
+        return VS_CALL_YES_DOING;
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+float walker_moveverb_idle_roam(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+
+        if (self.animflag == ANIM_MEELE)
+            return VS_CALL_NO;
+
+        return verb.verb_static_value;
+
+    case VCM_DO:
+        if(verb.wait < time)
+        {
+            trace_fraction = 0;
+            while(trace_fraction != 1.0)
+            {
+                self.moveto = self.origin + (v_forward * 256);
+                self.moveto += v_right * (random() * 256);
+                self.moveto -= v_right * (random() * 256);
+
+                tracebox(self.origin+'0 0 64',self.mins,self.maxs,self.moveto + '0 0 64',MOVE_NORMAL,self);
+            }
+            verb.wait = time + 10;
+        }
+        else
+        {
+            if(verb.wait - time < 9)
+                if(vlen(self.moveto - self.origin) < 32)
+                {
+                    verbstack_push(self.walker_verbs_move, walker_moveverb_idle_pause,   WVM_IDLE + WVM_IDLE_UP, random() * (verb.wait - time), self);
+                    self.animflag = ANIM_NO;
+                    return VS_CALL_REMOVE;
+                }
+        }
+
+        self.steerto = steerlib_attract(self.moveto,256);
+        te_lightning1(self,self.origin + '0 0 64',self.moveto + '0 0 64');
+
+
+
+        switch (self.waterlevel)
+        {
+        case 0:
+            self.animflag = ANIM_ROAM;
+        case 1:
+        case 2:
+            if (self.animflag != ANIM_SWIM)
+                self.animflag = ANIM_ROAM;
+
+            break;
+        case 3:
+            self.animflag = ANIM_SWIM;
+        }
+
+        return VS_CALL_YES_DOING;
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+float walker_moveverb_idle(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+
+        if (self.animflag == ANIM_MEELE)
+            return VS_CALL_NO;
+
+        return verb.verb_static_value;
+
+    case VCM_DO:
+
+        //if (random() < 0.5)
+            verbstack_push(self.walker_verbs_move, walker_moveverb_idle_pause,   WVM_IDLE + WVM_IDLE_UP, random() * 5, self);
+        //else
+        //    verbstack_push(self.walker_verbs_move, walker_moveverb_idle_roam,   WVM_IDLE + WVM_IDLE_UP,  random() * 15);
+
+        return VS_CALL_YES_DOING;
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+float walker_attackverb_meele(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+
+        vector wish_angle;
+
+        if (cvar("g_turrets_nofire"))
+            return VS_CALL_NO;
+
+        if (self.animflag == ANIM_SWIM || self.animflag == ANIM_MEELE)
+            return VS_CALL_NO;
+
+        if (!self.enemy)
+            return VS_CALL_NO;
+
+        wish_angle = angleofs(self,self.enemy);
+
+        if (self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_meele_range"))
+            if (fabs(wish_angle_y) < 15)
+                return verb.verb_static_value;
+
+        return VS_CALL_NO;
+
+    case VCM_DO:
+
+        self.moveto   = self.enemy.origin;
+        self.steerto  = steerlib_attract2(self.moveto,0.5,500,0.95);
+        self.animflag = ANIM_MEELE;
+
+        return VS_CALL_YES_DOING;
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+float walker_attackverb_rockets(float eval)
+{
+    switch (eval)
+    {
+    case VCM_EVAL:
+        if (self.tur_head.attack_finished_single > time)
+            return VS_CALL_NO;
+
+        if not(self.enemy)
+            return VS_CALL_NO;
+
+        if (cvar("g_turrets_nofire"))
+            return VS_CALL_NO;
+
+        if (self.tur_dist_enemy < cvar("g_turrets_unit_walker_std_rockets_range_min"))
+            return VS_CALL_NO;
+
+        if (self.tur_dist_enemy > cvar("g_turrets_unit_walker_std_rockets_range"))
+            return VS_CALL_NO;
+
+        return verb.verb_static_value;
+
+    case VCM_DO:
+
+        entity rv;
+
+        rv           = spawn();
+        rv.think     = rv_think;
+        rv.nextthink = time;
+        rv.cnt       = 4;
+        rv.owner     = self;
+
+        self.tur_head.attack_finished_single = time + cvar("g_turrets_unit_walker_std_rocket_refire");
+
+        return VS_CALL_YES_DONE;
+    }
+
+    return VS_CALL_YES_DONE;
+}
+
+void walker_postthink()
+{
+
+    self.angles_x *= -1;
+    makevectors(self.angles);
+    self.angles_x *= -1;
+
+    verbstack_pop(self.walker_verbs_attack);
+    verbstack_pop(self.walker_verbs_move);
+
+    walker_animate();
+}
+
+void walker_attack()
+{
+    entity flash;
+
+    //w_deathtypestring = "was miniguned";
+    sound (self, CHAN_WEAPON, "weapons/uzi_fire.wav", VOL_BASE, ATTN_NORM);
+    fireBallisticBullet (self.tur_shotorg, self.tur_shotdir_updated,self.shot_spread, self.shot_speed, 5, self.shot_dmg, 0, self.shot_force, DEATH_TURRET, 0, 1, cvar("g_balance_uzi_bulletconstant"));
+    if (self.uzi_bulletcounter == 2)
+    {
+
+        flash = spawn();
+
+        setmodel(flash, "models/uziflash.md3");
+        setattachment(flash, self.tur_head, "tag_fire");
+
+        flash.scale     = 3;
+        flash.think     = W_Uzi_Flash_Go;
+        flash.nextthink = time + 0.02;
+        flash.frame     = 2;
+        flash.angles_z  = flash.v_angle_z + random() * 180;
+        flash.alpha     = 1;
+        flash.effects   = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
+
+        self.uzi_bulletcounter = self.uzi_bulletcounter = 0;
+    }
+
+    self.uzi_bulletcounter = self.uzi_bulletcounter + 1;
+    self.tur_head.frame    = self.tur_head.frame + 1;
+}
+
+
+void walker_respawnhook()
+{
+    vector vtmp;
+    entity e;
+
+    self.origin = self.wkr_spawn.origin;
+    //self.wkr_props.solid = SOLID_BBOX;
+    //self.wkr_props.alpha = 1;
+
+    self.angles = self.wkr_spawn.angles;
+    vtmp = self.wkr_spawn.origin;
+    vtmp_z += self.wkr_spawn.maxs_z;
+    setorigin(self,vtmp);
+
+    if (self.target != "")
+    {
+        e = find(world,targetname,self.target);
+        if (!e)
+        {
+            dprint("Warning! initital waypoint for Walker does NOT exsist!\n");
+            self.target = "";
+        }
+
+        if (e.classname != "turret_checkpoint")
+            dprint("Warning: not a turrret path\n");
+        else
+        {
+            self.pathcurrent = WALKER_PATH(self.origin,e.origin);
+            self.pathgoal = e;
+        }
+    }
+}
+void walker_diehook()
+{
+    turret_trowgib2(self.origin,self.velocity + v_up * 200,'-0.6 -0.2 -02',self,time + random() * 1);
+    turret_trowgib2(self.origin + '0 0 64',self.velocity + v_forward * 150 + v_up * 150,'-0.2 -0.2 -02',self.tur_head,time + random() * 2 + 3);
+
+    if (self.pathcurrent)
+        pathlib_deletepath(self.pathcurrent.owner);
+
+    self.pathcurrent = world;
+
+    if (self.damage_flags & TFL_DMG_DEATH_NORESPAWN)
+    {
+        remove(self.wkr_spawn);
+
+        verbstack_flush(self.walker_verbs_move);
+        verbstack_flush(self.walker_verbs_attack);
+        verbstack_flush(self.walker_verbs_idle);
+
+        remove(self.walker_verbs_move);
+        remove(self.walker_verbs_attack);
+        remove(self.walker_verbs_idle);
+    }
+
+}
+
+void turret_walker_dinit()
+{
+
+    entity e;
+
+    if (self.netname == "")      self.netname     = "Walker Turret";
+    self.wkr_spawn = spawn();
+
+    self.ammo_flags = TFL_AMMO_BULLETS | TFL_AMMO_RECHARGE | TFL_AMMO_RECIVE;
+    self.turrcaps_flags = TFL_TURRCAPS_PLAYERKILL | TFL_TURRCAPS_MOVE | TFL_TURRCAPS_HEADATTACHED;
+    self.aim_flags = TFL_AIM_LEAD;
+
+    if (cvar("g_antilag_bullets"))
+        self.turrcaps_flags |= TFL_TURRCAPS_HITSCAN;
+    else
+        self.aim_flags      |= TFL_AIM_SHOTTIMECOMPENSATE;
+
+
+    self.turret_respawnhook = walker_respawnhook;
+    self.turret_diehook = walker_diehook;
+
+    self.ticrate = 0.05;
+    if (turret_stdproc_init("walker_std",0) == 0)
+    {
+        remove(self);
+        return;
+    }
+
+    self.walker_verbs_move   = spawn();
+    self.walker_verbs_attack = spawn();
+    self.walker_verbs_idle   = spawn();
+
+    verbstack_push(self.walker_verbs_move, walker_moveverb_idle,   WVM_IDLE,  0, self);
+    verbstack_push(self.walker_verbs_move, walker_moveverb_enemy,  WVM_ENEMY, 0, self);
+    verbstack_push(self.walker_verbs_move, walker_moveverb_path,   WVM_PATH,  0, self);
+
+    verbstack_push(self.walker_verbs_attack, walker_attackverb_meele,   WVA_MEELE,  0, self);
+    verbstack_push(self.walker_verbs_attack, walker_attackverb_rockets, WVA_ROCKET, 0, self);
+
+    self.damage_flags |= TFL_DMG_DEATH_NOGIBS;
+
+    self.target_select_flags   = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
+    self.target_validate_flags = TFL_TARGETSELECT_PLAYERS | TFL_TARGETSELECT_RANGELIMTS | TFL_TARGETSELECT_TEAMCHECK | TFL_TARGETSELECT_LOS;
+
+    self.iscreature = TRUE;
+    self.movetype   = MOVETYPE_WALK;
+    self.solid      = SOLID_SLIDEBOX;
+    self.takedamage = DAMAGE_AIM;
+
+    setmodel(self,"models/turrets/walker_body.md3");
+    setmodel(self.tur_head,"models/turrets/walker_head_minigun.md3");
+    setmodel(self.wkr_spawn,"models/turrets/walker_spawn.md3");
+
+    setattachment(self.tur_head,self,"tag_head");
+
+    self.wkr_spawn.angles   = self.angles;
+    self.wkr_spawn.solid    = SOLID_NOT;
+
+    traceline(self.origin + '0 0 16', self.origin - '0 0 10000', MOVE_WORLDONLY, self);
+    setorigin(self.wkr_spawn,trace_endpos + '0 0 4');
+    setorigin(self,self.wkr_spawn.origin);
+
+    setsize(self,WALKER_MIN,WALKER_MAX);
+
+    self.idle_aim = '0 0 0';
+    self.turret_firecheckfunc = walker_firecheck;
+    self.turret_firefunc      = walker_attack;
+    self.turret_postthink     = walker_postthink;
+
+    if (self.target != "")
+    {
+        e = find(world,targetname,self.target);
+        if (!e)
+        {
+            dprint("Initital waypoint for walker does NOT exsist, fix your map!\n");
+            self.target = "";
+        }
+
+        if (e.classname != "turret_checkpoint")
+            dprint("Warning: not a turrret path\n");
+        else
+        {
+            self.pathcurrent = WALKER_PATH(self.origin,e.origin);
+            self.pathgoal = e;
+        }
+    }
+}
+
+
+void spawnfunc_turret_walker()
+{
+    g_turrets_common_precash();
+
+    precache_model ("models/turrets/walker_head_minigun.md3");
+    precache_model ("models/turrets/walker_body.md3");
+    precache_model ("models/turrets/walker_props.md3");
+    precache_model ("models/turrets/walker_spawn.md3");
+    precache_model ( "models/turrets/rocket.md3");
+    precache_sound ( "weapons/rocket_impact.wav" );
+
+    self.think = turret_walker_dinit;
+    self.nextthink = time + 0.5;
+}


Property changes on: trunk/data/qcsrc/server/tturrets/units/unit_walker.qc
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/vehicles/vehicles.qh
===================================================================
--- trunk/data/qcsrc/server/vehicles/vehicles.qh	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/vehicles/vehicles.qh	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,52 +1,52 @@
-//#define VEHICLES_ENABLED
-#ifdef VEHICLES_ENABLED
-
-#message "with tZork vehicles (experimental)"
-
-float SVC_SETVIEWPORT = 5;    // Net.Protocol 0x05
-float SVC_SETVIEWANGLES = 10; // Net.Protocol 0x0A
-float SVC_UPDATEENTITY = 128; // Net.Protocol 0x80
-
-#define CCVAR(part) cvar(strcat(self.cvar_basename,part))
-//.string cvar_basename;
-
-.float vehicle_flags;
-#define VHF_HASSHIELD 2
-#define VHF_SHIELDREGEN 4
-#define VHF_HEALTHREGEN 8
-
-.float hud;
-.float rockets;
-.float rockets_reload;
-.entity gun1;
-.entity gun2;
-
-.float vehicle_health;
-.float vehicle_shield;
-.float vehicle_heat;
-
-.entity vehicle;
-.entity vehicle_viewport;
-.entity vehicle_hudmodel;
-
-.float anim_start;
-.float anim_end;
-
-.float dmg_time;
-
-float server_fps;
-
-#define VHEF_NORMAL 0
-#define VHEF_EJECT 1
-
-.void(float exit_flags) vehicle_exit;
-.void() vehicle_enter;
-.void() vehicle_die;
-.void() vehicle_spawn;
-.float(float message) vehicle_message;
-
-#include "vehicles.qc"
-#include "spiderbot.qc"
-#include "racer.qc"
-
-#endif
+//#define VEHICLES_ENABLED
+#ifdef VEHICLES_ENABLED
+
+#message "with tZork vehicles (experimental)"
+
+float SVC_SETVIEWPORT = 5;    // Net.Protocol 0x05
+float SVC_SETVIEWANGLES = 10; // Net.Protocol 0x0A
+float SVC_UPDATEENTITY = 128; // Net.Protocol 0x80
+
+#define CCVAR(part) cvar(strcat(self.cvar_basename,part))
+//.string cvar_basename;
+
+.float vehicle_flags;
+#define VHF_HASSHIELD 2
+#define VHF_SHIELDREGEN 4
+#define VHF_HEALTHREGEN 8
+
+.float hud;
+.float rockets;
+.float rockets_reload;
+.entity gun1;
+.entity gun2;
+
+.float vehicle_health;
+.float vehicle_shield;
+.float vehicle_heat;
+
+.entity vehicle;
+.entity vehicle_viewport;
+.entity vehicle_hudmodel;
+
+.float anim_start;
+.float anim_end;
+
+.float dmg_time;
+
+float server_fps;
+
+#define VHEF_NORMAL 0
+#define VHEF_EJECT 1
+
+.void(float exit_flags) vehicle_exit;
+.void() vehicle_enter;
+.void() vehicle_die;
+.void() vehicle_spawn;
+.float(float message) vehicle_message;
+
+#include "vehicles.qc"
+#include "spiderbot.qc"
+#include "racer.qc"
+
+#endif


Property changes on: trunk/data/qcsrc/server/vehicles/vehicles.qh
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: trunk/data/qcsrc/server/verbstack.qc
===================================================================
--- trunk/data/qcsrc/server/verbstack.qc	2009-06-30 13:36:51 UTC (rev 7130)
+++ trunk/data/qcsrc/server/verbstack.qc	2009-06-30 14:36:36 UTC (rev 7131)
@@ -1,200 +1,200 @@
-/// Some default stacks.
-.entity verbs_idle;
-.entity verbs_attack;
-.entity verbs_move;
-
-/// This global gets set to the verb in question each time the stack manager calls verb_call
-entity verb;
-
-/// Execure this verb
-#define VCM_DO     0
-/// Return the value of this verb. Return VS_CALL_REMOVE to delete it.
-#define VCM_EVAL   1
-/// This verb is beeing removed NOW (not sent when verb_call returns VS_CALL_REMOVE)
-#define VCM_REMOVE 2
-
-/// Verb callback
-.float(float message) verb_call;
-
-/// Points to this verb's stack.
-.entity  verbstack;
-
-/// Static value of this verb
-.float verb_static_value;
-
-/// verb_call returns this when a verb in not doable
-#define VS_CALL_NO        0
-/// verb_call(VCM_DO) returns this when a verb is executing
-#define VS_CALL_YES_DOING -1
-/// verb_call(VCM_DO) returns this when a verb did execure and is done
-#define VS_CALL_YES_DONE  -2
-/// verb_call(VCM_DO) returns this when a verb should be deleted by the stack manager
-#define VS_CALL_REMOVE    -3
-
-/**
-    Push a new verb onto the specified stack. Set vrb_life to make it time-limited.
-**/
-entity verbstack_push(entity stack, float(float eval) vrb_call, float val_static, float vrb_life,entity verb_owner)
-{
-    entity vrb;
-
-    if not(stack)
-        return world;
-
-    if not(vrb_call)
-        return world;
-
-    vrb                   = spawn();
-    vrb.owner             = verb_owner;
-    vrb.verbstack         = stack;
-    vrb.verb_call         = vrb_call;
-    vrb.verb_static_value = val_static;
-
-    if(vrb_life)
-    {
-        vrb.think     = SUB_Remove;
-        vrb.nextthink = time + vrb_life;
-    }
-
-    return vrb;
-}
-
-/**
-    Find the best verb in this stack and execurte it.
-    ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL or VCM_DO
-**/
-float verbstack_pop(entity stack)
-{
-    entity vrb, bestverb, oldself;
-    float  value, bestvalue;
-
-    oldself = self;
-
-    vrb = findchainentity(verbstack,stack);
-    while(vrb)
-    {
-        verb  = vrb;
-        vrb   = vrb.chain;
-        self  = verb.owner;
-        value = verb.verb_call(VCM_EVAL);
-
-        if(value < 0)
-        {
-            if(value == VS_CALL_REMOVE)
-                remove(verb);
-        }
-        else
-        {
-            if(value > bestvalue)
-            {
-                bestverb  = verb;
-                bestvalue = value;
-            }
-        }
-    }
-
-    if(bestverb)
-    {
-        verb  = bestverb;
-        self  = verb.owner;
-        value = verb.verb_call(VCM_DO);
-
-        if(value == VS_CALL_REMOVE)
-            remove(bestverb);
-    }
-
-    self = oldself;
-
-    return value;
-}
-
-float verbstack_popfifo(entity stack)
-{
-    entity oldself;
-    float ret;
-
-    oldself = self;
-    verb = findentity(stack,verbstack,stack);
-    if not (verb)
-        ret = 0;
-    else
-    {
-        self = verb.owner;
-        ret = verb.verb_call(VCM_DO);
-
-        if(ret == VS_CALL_REMOVE)
-            remove(verb);
-    }
-
-    self = oldself;
-    return ret;
-}
-
-/**
-    Find the best verb in this stack and return it.
-    ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL.
-**/
-entity verbstack_pull(entity stack)
-{
-    entity vrb;
-    entity bestverb, oldself;
-    float  value, bestvalue;
-
-    oldself = self;
-
-    vrb = findchainentity(verbstack,stack);
-    while(vrb)
-    {
-        self = vrb.owner;
-
-        verb  = vrb;
-        vrb   = vrb.chain;
-        value = verb.verb_call(VCM_EVAL);
-
-        if(value > 0)
-        {
-            if(value == VS_CALL_REMOVE)
-                remove(verb);
-        }
-        else
-        {
-            if(value > bestvalue)
-            {
-                bestverb = verb;
-                bestvalue = value;
-            }
-        }
-    }
-
-    self = oldself;
-
-    return bestverb;
-}
-
-entity verbstack_pullfifo(entity stack)
-{
-    return findentity(stack,verbstack,stack);
-}
-
-/**
-    Delete every verb on this stack, signaling them with VCM_REMOVE first.
-**/
-void verbstack_flush(entity stack)
-{
-    entity vrb, oldself;
-
-    oldself = self;
-
-    vrb = findchainentity(verbstack,stack);
-    while(vrb)
-    {
-        self = vrb.owner;
-
-        verb = vrb;
-        vrb  = vrb.chain;
-        verb.verb_call(VCM_REMOVE);
-        remove(verb);
-    }
-
-    self = oldself;
-}
+/// Some default stacks.
+.entity verbs_idle;
+.entity verbs_attack;
+.entity verbs_move;
+
+/// This global gets set to the verb in question each time the stack manager calls verb_call
+entity verb;
+
+/// Execure this verb
+#define VCM_DO     0
+/// Return the value of this verb. Return VS_CALL_REMOVE to delete it.
+#define VCM_EVAL   1
+/// This verb is beeing removed NOW (not sent when verb_call returns VS_CALL_REMOVE)
+#define VCM_REMOVE 2
+
+/// Verb callback
+.float(float message) verb_call;
+
+/// Points to this verb's stack.
+.entity  verbstack;
+
+/// Static value of this verb
+.float verb_static_value;
+
+/// verb_call returns this when a verb in not doable
+#define VS_CALL_NO        0
+/// verb_call(VCM_DO) returns this when a verb is executing
+#define VS_CALL_YES_DOING -1
+/// verb_call(VCM_DO) returns this when a verb did execure and is done
+#define VS_CALL_YES_DONE  -2
+/// verb_call(VCM_DO) returns this when a verb should be deleted by the stack manager
+#define VS_CALL_REMOVE    -3
+
+/**
+    Push a new verb onto the specified stack. Set vrb_life to make it time-limited.
+**/
+entity verbstack_push(entity stack, float(float eval) vrb_call, float val_static, float vrb_life,entity verb_owner)
+{
+    entity vrb;
+
+    if not(stack)
+        return world;
+
+    if not(vrb_call)
+        return world;
+
+    vrb                   = spawn();
+    vrb.owner             = verb_owner;
+    vrb.verbstack         = stack;
+    vrb.verb_call         = vrb_call;
+    vrb.verb_static_value = val_static;
+
+    if(vrb_life)
+    {
+        vrb.think     = SUB_Remove;
+        vrb.nextthink = time + vrb_life;
+    }
+
+    return vrb;
+}
+
+/**
+    Find the best verb in this stack and execurte it.
+    ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL or VCM_DO
+**/
+float verbstack_pop(entity stack)
+{
+    entity vrb, bestverb, oldself;
+    float  value, bestvalue;
+
+    oldself = self;
+
+    vrb = findchainentity(verbstack,stack);
+    while(vrb)
+    {
+        verb  = vrb;
+        vrb   = vrb.chain;
+        self  = verb.owner;
+        value = verb.verb_call(VCM_EVAL);
+
+        if(value < 0)
+        {
+            if(value == VS_CALL_REMOVE)
+                remove(verb);
+        }
+        else
+        {
+            if(value > bestvalue)
+            {
+                bestverb  = verb;
+                bestvalue = value;
+            }
+        }
+    }
+
+    if(bestverb)
+    {
+        verb  = bestverb;
+        self  = verb.owner;
+        value = verb.verb_call(VCM_DO);
+
+        if(value == VS_CALL_REMOVE)
+            remove(bestverb);
+    }
+
+    self = oldself;
+
+    return value;
+}
+
+float verbstack_popfifo(entity stack)
+{
+    entity oldself;
+    float ret;
+
+    oldself = self;
+    verb = findentity(stack,verbstack,stack);
+    if not (verb)
+        ret = 0;
+    else
+    {
+        self = verb.owner;
+        ret = verb.verb_call(VCM_DO);
+
+        if(ret == VS_CALL_REMOVE)
+            remove(verb);
+    }
+
+    self = oldself;
+    return ret;
+}
+
+/**
+    Find the best verb in this stack and return it.
+    ALso remove any verbs returning VS_CALL_REMOVE on VCM_EVAL.
+**/
+entity verbstack_pull(entity stack)
+{
+    entity vrb;
+    entity bestverb, oldself;
+    float  value, bestvalue;
+
+    oldself = self;
+
+    vrb = findchainentity(verbstack,stack);
+    while(vrb)
+    {
+        self = vrb.owner;
+
+        verb  = vrb;
+        vrb   = vrb.chain;
+        value = verb.verb_call(VCM_EVAL);
+
+        if(value > 0)
+        {
+            if(value == VS_CALL_REMOVE)
+                remove(verb);
+        }
+        else
+        {
+            if(value > bestvalue)
+            {
+                bestverb = verb;
+                bestvalue = value;
+            }
+        }
+    }
+
+    self = oldself;
+
+    return bestverb;
+}
+
+entity verbstack_pullfifo(entity stack)
+{
+    return findentity(stack,verbstack,stack);
+}
+
+/**
+    Delete every verb on this stack, signaling them with VCM_REMOVE first.
+**/
+void verbstack_flush(entity stack)
+{
+    entity vrb, oldself;
+
+    oldself = self;
+
+    vrb = findchainentity(verbstack,stack);
+    while(vrb)
+    {
+        self = vrb.owner;
+
+        verb = vrb;
+        vrb  = vrb.chain;
+        verb.verb_call(VCM_REMOVE);
+        remove(verb);
+    }
+
+    self = oldself;
+}


Property changes on: trunk/data/qcsrc/server/verbstack.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/vote.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/vote.qh
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/w_campingrifle.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/w_hlac.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/w_hook.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/w_minstanex.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/w_porto.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/w_seeker.qc
___________________________________________________________________
Name: svn:eol-style
   + native


Property changes on: trunk/data/qcsrc/server/w_tuba.qc
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the nexuiz-commits mailing list