r3868 - in branches/nexuiz-2.0: . Docs data data/gfx data/maps data/models data/qcsrc/client data/qcsrc/common data/qcsrc/menu data/qcsrc/menu/nexuiz data/qcsrc/server data/scripts data/sound data/textures/evil1_floors data/textures/evil3_misc data/textures/evil4_d_techwalls data/textures/evil4_lights data/textures/evil4_metals data/textures/evil4_techfloors data/textures/evil4_techtrims data/textures/evil4_techwalls data/textures/evil8_floor data/textures/evil8_lights

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Mon Jul 21 10:44:05 EDT 2008


Author: div0
Date: 2008-07-21 10:44:04 -0400 (Mon, 21 Jul 2008)
New Revision: 3868

Added:
   branches/nexuiz-2.0/data/gfx/ons-frame-team.tga
   branches/nexuiz-2.0/data/gfx/ons-frame.tga
   branches/nexuiz-2.0/data/gfx/ons-reborn_mini.tga
   branches/nexuiz-2.0/data/gfx/sb_key_carrying_outline.tga
   branches/nexuiz-2.0/data/gfx/sb_kh_full.tga
   branches/nexuiz-2.0/data/gfx/sb_kh_outline.tga
   branches/nexuiz-2.0/data/maps/ons-reborn.info
   branches/nexuiz-2.0/data/models/turrets/
   branches/nexuiz-2.0/data/qcsrc/client/ctf.qc
   branches/nexuiz-2.0/data/qcsrc/client/main.qh
   branches/nexuiz-2.0/data/qcsrc/client/mapvoting.qc
   branches/nexuiz-2.0/data/qcsrc/client/miscfunctions.qc
   branches/nexuiz-2.0/data/qcsrc/client/ons.qc
   branches/nexuiz-2.0/data/qcsrc/client/pre.qh
   branches/nexuiz-2.0/data/qcsrc/client/sbar.qc
   branches/nexuiz-2.0/data/qcsrc/client/sortlist.qc
   branches/nexuiz-2.0/data/qcsrc/client/teamplay.qc
   branches/nexuiz-2.0/data/qcsrc/server/ent_cs.qc
   branches/nexuiz-2.0/data/qcsrc/server/server.cbp
   branches/nexuiz-2.0/data/qcsrc/server/tturrets/
   branches/nexuiz-2.0/data/scripts/turrets.def
   branches/nexuiz-2.0/data/scripts/turrets.shader
   branches/nexuiz-2.0/data/sound/turrets/
   branches/nexuiz-2.0/data/textures/evil1_floors/floortile1bbrown.jpg
   branches/nexuiz-2.0/data/textures/evil1_floors/floortile1bbrown_bump.jpg
   branches/nexuiz-2.0/data/textures/evil3_misc/b_rock.jpg
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanel_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelb_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelc_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrn_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrnb2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrnb_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrnbgrt_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_lightboard_glow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_lightboard_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_mpanel_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_mpanelgrt_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtlsupport_alpha_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtlsupport_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_lighttechdoor_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_shinymtlsupport_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_b_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_cutl_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_cutr_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_seam2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_seam_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwll_pnltek_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2_fx_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2_glow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2g_glow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2g_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2gb_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw_grate_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_2g_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_2gsign_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_light_glow.jpg
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_light_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_sign_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dws_grate_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwteky_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall2_huge_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_dlight_glow.jpg
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_dlight_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_drkm2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_drkm_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_drkmpanel_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_grll_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_window.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_window_gloss.tga
   branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_window_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/drkmtlsupport_light_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/dwtrim_llight_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/l_light_b_glow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/l_light_b_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/l_light_g_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/l_light_r_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/l_light_w_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/llight_s_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/mtl_l1_fx_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/mtl_l1_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/mtl_lightsmll_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/s_bluelight_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/s_light_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/steplight_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/t_mtllight_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_lights/trimtl_grlbtm_light_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/defaultmetal_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/drkmtl_default_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/drkmtl_grlpltmech_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/eshinytin_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/flrgrate_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/hexametal_drk_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/hexametal_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mediummtl_default_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtl2grt_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlb_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlbrushed_env_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlbrushed_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtldoor_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlflrslots_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtloverlaprwll_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_d_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_ow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_wrnstripe_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_wrnstripe_ow2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_wrnstripe_ow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanelsmll_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanelsmll_ow2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanelsmll_ow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlslots_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlslots_ow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlslotsrivts_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlslotsrivts_ow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlsportal_fx3_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlsportal_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtltechwall_128_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtltechwall_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtltekfloor_fx2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtltekfloor_fx_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtltekfloor_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlwrndoor2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/mtlwrndoor_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/step_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/stepgrl_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti2_0000_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti2_wrn_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_lights_blend_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrn2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrn2hfx_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrn_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrnb_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrnlights2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrnlights_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/trim_wrnrivets_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/trimtl_grlbtm_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/whitemtl_default_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_metals/wrnjumppad_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor2b_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor3_huge_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor3_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor4_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor4plain_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor_rndholes_drty_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor_rndholes_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloorhex_big_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloorhex_smll_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techfloors/tflooroddtile_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/cleantrimmulti_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/drkmtl_oddtrim_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/drttrimmulti_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/dw_combo_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_bevel_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_bevelslite_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_fade2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_fade_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_grill_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_grt_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_panel2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_panel_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/medmtl_oddtrim_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techtrims/misc_grill_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanel_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanel_ow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelb_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelc_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelwrn_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelwrnb2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelwrnb_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelwrnbgrt_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_lightboard_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_mpanel_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_mpanelgrt_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtlsupport_alpha_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtlsupport_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/lighttechdoor_drty_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/lighttechdoor_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/mechanical_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/mechanical_old_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/mechanicalx128_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/mechanicalx128_old_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/shinymtlsupport_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_b_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_cutl_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_cutr_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_seam2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_seam_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwll_pnltek_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dw2_fx_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dw2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dw2g_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dw2gb_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dw_grate_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwb_2g_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwb_2gsign_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwb_light_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwb_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwb_sign_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dws_grate_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwteky_glow_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwteky_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall2_huge_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_dlight_glow.jpg
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_dlight_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_drkm2_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_drkm_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_drkmpanel_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_grll_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_window.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_window_norm.tga
   branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_windowmask_norm.tga
   branches/nexuiz-2.0/data/textures/evil8_floor/e8clangfloor04warn2red.jpg
   branches/nexuiz-2.0/data/textures/evil8_lights/e8_rlighty.jpg
   branches/nexuiz-2.0/data/textures/evil8_lights/e8_rlighty_glow.jpg
   branches/nexuiz-2.0/data/turrets.cfg
   branches/nexuiz-2.0/data/unit_flac.cfg
   branches/nexuiz-2.0/data/unit_fusreac.cfg
   branches/nexuiz-2.0/data/unit_hellion.cfg
   branches/nexuiz-2.0/data/unit_hk.cfg
   branches/nexuiz-2.0/data/unit_machinegun.cfg
   branches/nexuiz-2.0/data/unit_minigun.cfg
   branches/nexuiz-2.0/data/unit_mlrs.cfg
   branches/nexuiz-2.0/data/unit_phaser.cfg
   branches/nexuiz-2.0/data/unit_plasma.cfg
   branches/nexuiz-2.0/data/unit_plasma2.cfg
   branches/nexuiz-2.0/data/unit_tesla.cfg
Removed:
   branches/nexuiz-2.0/data/assault.def
Modified:
   branches/nexuiz-2.0/.patchsets
   branches/nexuiz-2.0/Docs/mapping.txt
   branches/nexuiz-2.0/data/Makefile
   branches/nexuiz-2.0/data/defaultNexuiz.cfg
   branches/nexuiz-2.0/data/qcsrc/client/Defs.qc
   branches/nexuiz-2.0/data/qcsrc/client/Main.qc
   branches/nexuiz-2.0/data/qcsrc/client/View.qc
   branches/nexuiz-2.0/data/qcsrc/client/csqc_builtins.qc
   branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.qc
   branches/nexuiz-2.0/data/qcsrc/client/progs.src
   branches/nexuiz-2.0/data/qcsrc/common/campaign_file.qc
   branches/nexuiz-2.0/data/qcsrc/common/constants.qh
   branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc
   branches/nexuiz-2.0/data/qcsrc/common/util.qc
   branches/nexuiz-2.0/data/qcsrc/common/util.qh
   branches/nexuiz-2.0/data/qcsrc/menu/item.c
   branches/nexuiz-2.0/data/qcsrc/menu/menu.qc
   branches/nexuiz-2.0/data/qcsrc/menu/msys.qh
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/credits.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_create_mapinfo.c
   branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c
   branches/nexuiz-2.0/data/qcsrc/server/assault.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc
   branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
   branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
   branches/nexuiz-2.0/data/qcsrc/server/constants.qh
   branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
   branches/nexuiz-2.0/data/qcsrc/server/defs.qh
   branches/nexuiz-2.0/data/qcsrc/server/extensions.qh
   branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
   branches/nexuiz-2.0/data/qcsrc/server/g_decors.qc
   branches/nexuiz-2.0/data/qcsrc/server/g_triggers.qc
   branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
   branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc
   branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh
   branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
   branches/nexuiz-2.0/data/qcsrc/server/progs.src
   branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc
   branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc
   branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
   branches/nexuiz-2.0/data/qcsrc/server/vote.qc
   branches/nexuiz-2.0/data/scripts/entities.def
Log:
CSQC stuff, map voting; menu; new CTF scoring option; impulse 911; trigger_impulse extension


Modified: branches/nexuiz-2.0/.patchsets
===================================================================
--- branches/nexuiz-2.0/.patchsets	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/.patchsets	2008-07-21 14:44:04 UTC (rev 3868)
@@ -1,2 +1,2 @@
 master = svn://svn.icculus.org/nexuiz/trunk
-revisions_applied = 1-3760,3762-3773,3777-3778,3787-3788,3790-3790,3796-3804,3807-3808,3817-3817,3822-3825,3828-3835,3837-3839
+revisions_applied = 1-3866

Modified: branches/nexuiz-2.0/Docs/mapping.txt
===================================================================
--- branches/nexuiz-2.0/Docs/mapping.txt	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/Docs/mapping.txt	2008-07-21 14:44:04 UTC (rev 3868)
@@ -108,7 +108,11 @@
 
 There's much more power in a mapinfo file. See Appendix A for more details.
 
+By the way: the Domination and Keyhunt types allow a third number to specify
+the number of teams; the CTF type allows a third number to specify a capture
+limit (if g_ctf_win_mode is 0 or 1).
 
+
 -------------
 -mapname.cfg-
 -------------

Modified: branches/nexuiz-2.0/data/Makefile
===================================================================
--- branches/nexuiz-2.0/data/Makefile	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/Makefile	2008-07-21 14:44:04 UTC (rev 3868)
@@ -3,10 +3,17 @@
 PK3NAME ?= `date +../data%Y%m%d.pk3`
 ZIP ?= 7za a -tzip -mx=9
 
+# NOTE: use -DUSE_FTE instead of -TFTE here!
+# It will automagically add an engine check with -TID and then change back to -TFTE
+QCFLAGS_CSQC ?= 
+
+# to be enabled when possible
+# QCFLAGS_SVQC ?= -TFTE
+
 all: qc
 
 .PHONY: qc
-qc: menu.dat progs.dat
+qc: menu.dat progs.dat csprogs.dat
 
 .PHONY: skin
 skin: gfx/menu/default/skinvalues.txt
@@ -19,10 +26,10 @@
 	rm -f progs.dat menu.dat csprogs.dat
 
 csprogs.dat: qcsrc/client/*.* qcsrc/common/*.*
-	( cd qcsrc/client; $(FTEQCC) )
+	( cd qcsrc/client; $(FTEQCC) $(QCFLAGS_CSQC) )
 
 progs.dat: qcsrc/server/*.* qcsrc/common/*.*
-	( cd qcsrc/server; $(FTEQCC) )
+	( cd qcsrc/server; $(FTEQCC) $(QCFLAGS_SVQC) )
 
 menu.dat: qcsrc/menu/*.* qcsrc/menu/*/*.* qcsrc/common/*.*
 	( cd qcsrc/menu; $(FTEQCC) )

Deleted: branches/nexuiz-2.0/data/assault.def
===================================================================
--- branches/nexuiz-2.0/data/assault.def	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/assault.def	2008-07-21 14:44:04 UTC (rev 3868)
@@ -1,39 +0,0 @@
-/*QUAKED info_player_attacker (1 0 0) (-16 -16 -24) (16 16 45) INITIAL
-Normal attacker spawning location for Nexuiz Asssault
--------- KEYS --------
-angle : direction in which player will look when spawning in the game. Does not apply to bots.
-target : this should point to a target_objective to decide when this spawning point is active.
-nobots : when set to 1, bots will never use this spawn point to respawn in the game.
-nohumans : when set to 1, human players will never use this spawn point to respawn in the game.
-notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
-notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
-notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
--------- SPAWNFLAGS --------
-INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
-//=============================================================================
-
-/*QUAKED info_player_defender (0 1 0) (-16 -16 -24) (16 16 45) INITIAL
-Normal defender spawning location for Nexuiz Asssault
--------- KEYS --------
-angle : direction in which player will look when spawning in the game. Does not apply to bots.
-target : this should point to a target_objective to decide when this spawning point is active.
-nobots : when set to 1, bots will never use this spawn point to respawn in the game.
-nohumans : when set to 1, human players will never use this spawn point to respawn in the game.
-notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
-notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
-notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
--------- SPAWNFLAGS --------
-INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
-//=============================================================================
-
-/*QUAKED target_objective (0 .5 0) (-8 -8 -8) (8 8 8)
-Objective controller for Nexuiz Assault. When active it has 100 health. If it falls below 0 then
-it'll trigger the next targeted entity (usually the next objective or target_assault_roundend etc.)
-//=============================================================================
-
-/*QUAKED target_objective_decrease (0 .5 0) (-8 -8 -8) (8 8 8)
-When triggered decreases health of the targeted target_objective.*/
-
-/*QUAKED func_assault_destructible (0 .5 0) (-8 -8 -8) (8 8 8)
-
-

Modified: branches/nexuiz-2.0/data/defaultNexuiz.cfg
===================================================================
--- branches/nexuiz-2.0/data/defaultNexuiz.cfg	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/defaultNexuiz.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -157,6 +157,9 @@
 // use default physics
 exec physicsQBR.cfg
 
+set sv_pogostick 0 // don't require releasing the space bar for jumping again
+set sv_doublejump 0 // allow Quake 2-style double jumps
+
 seta sv_precacheplayermodels 1
 seta sv_precacheweapons 0
 seta sv_precacheitems 0
@@ -316,11 +319,14 @@
 // this means that timelimit can be overidden globally and fraglimit can be overidden for each game mode: DM/TDM, Domination, CTF, and Runematch.
 seta timelimit_override -1
 seta fraglimit_override -1
-seta g_ctf_capture_limit -1
+seta capturelimit_override -1 // actual captures, if g_ctf_win_mode 0 or 1
+seta g_ctf_capture_limit -1   // points, if g_ctf_win_mode 2
 seta g_domination_point_limit -1
 seta g_runematch_point_limit -1
 seta g_keyhunt_point_limit -1
 
+seta g_ctf_win_mode 2 // 0: captures only, 1: captures, points if equal captures, 2: points
+
 // 50% of the spawns shall be far away from any players
 set g_spawn_furthest 0.5
 // respawn delay
@@ -808,6 +814,8 @@
 seta g_maplist_votable_suggestions_override_mostrecent 0
 seta g_maplist_votable_nodetail 0 // nodetail only shows total count instead of all vote counts per map, so votes don't influence others that much
 seta g_maplist_votable_abstain 0 // when 1, you can abstain from your vote
+seta g_maplist_votable_screenshot_dir "maps" // where to look for map screenshots
+seta g_maplist_textonly 0 // use old style centerprint
 alias suggestmap "cmd suggestmap $1"
 
 set g_chat_flood_spl 0                   // seconds between lines to not count as flooding
@@ -1042,6 +1050,14 @@
 // when sv_maxidle is not 0, assume spectators are idle too
 set sv_maxidle_spectatorsareidle 0
 
+// CTF capture limit placeholder cvar
+set capturelimit 0
+
+// sbar: font size
+set sbar_fontsize 11
+alias sbar_font "loadfont user1 $*; sbar_columns_set"
+sbar_font gfx/vera-sans
+
 // these entities are not referenced by anything directly, they just represent
 // teams and are found by find() when needed
 prvm_leaktest_ignore_classnames "ctf_team dom_team tdm_team"

Copied: branches/nexuiz-2.0/data/gfx/ons-frame-team.tga (from rev 3761, trunk/data/gfx/ons-frame-team.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/gfx/ons-frame.tga (from rev 3761, trunk/data/gfx/ons-frame.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/gfx/ons-reborn_mini.tga (from rev 3761, trunk/data/gfx/ons-reborn_mini.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/gfx/sb_key_carrying_outline.tga (from rev 3776, trunk/data/gfx/sb_key_carrying_outline.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/gfx/sb_kh_full.tga (from rev 3786, trunk/data/gfx/sb_kh_full.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/gfx/sb_kh_outline.tga (from rev 3786, trunk/data/gfx/sb_kh_outline.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/maps/ons-reborn.info (from rev 3761, trunk/data/maps/ons-reborn.info)
===================================================================
--- branches/nexuiz-2.0/data/maps/ons-reborn.info	                        (rev 0)
+++ branches/nexuiz-2.0/data/maps/ons-reborn.info	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,8 @@
+// This file is necessary if world.mins/maxs is wrong.
+// It happens when q3map2 fucks up, or you put entities far outside the map,
+// like ons-reborn the trains.
+// Every unrecognized line in this file will be printed to the console
+// unless it begins with double slashes
+// This is a sample file =)
+mins -8224.0 -8224.0 -96.0
+maxs 8224.0 8224.0 6496.0

Copied: branches/nexuiz-2.0/data/models/turrets (from rev 3866, trunk/data/models/turrets)

Modified: branches/nexuiz-2.0/data/qcsrc/client/Defs.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/Defs.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/client/Defs.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -10,7 +10,6 @@
 
 
 
-#define CSQC 1
 
 /*
 ==============================================================================
@@ -168,4 +167,6 @@
 // Basic variables
 .float enttype; // entity type sent from server
 .float sv_entnum; // entity number sent from server
-float vid_conwidth, vid_conheight;
\ No newline at end of file
+float vid_conwidth, vid_conheight;
+float caps_team1, caps_team2;
+float configdb;

Modified: branches/nexuiz-2.0/data/qcsrc/client/Main.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/Main.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/client/Main.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -1,40 +1,168 @@
 // --------------------------------------------------------------------------
 // BEGIN REQUIRED CSQC FUNCTIONS
+//include "main.qh"
 
+void() menu_show_error =
+{
+	drawstring('0 200', "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 =
+{
+};
+
+// let's make this a general data buffer...
+float using_gps;
+
+#ifdef USE_FTE
+float __engine_check;
+#endif
+
+string config_get(string key, string defaultvalue)
+{
+	string s;
+	s = db_get(configdb, strcat("/s/", key));
+	if(s == "")
+		return defaultvalue;
+	else
+		return db_get(configdb, strcat("/v/", key));
+}
+
 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
+	
+	float i;
+	CSQC_CheckEngine();
+
+	configdb = db_create();
+
+	drawfont = 0;
+	menu_visible = FALSE;
+	menu_show = menu_show_error;
+	menu_action = menu_sub_null;
+	using_gps = false;
+	//ctf_temp_1 = "";
+	localcmd("alias order \"cmd order $*\"");
+	//registercmd("ctf_menu");
+	registercmd("ons_map");
+	//registercmd("menu_action");
+	registercmd("sbar_columns_set");
+	registercmd("sbar_columns_help");
+
+	registercvar("sbar_usecsqc", "1");
+	registercvar("sbar_columns", "ping name | caps returns frags deaths", CVAR_SAVE);
+
+	gametype = 0;
+
+	gps_start = world;
+
+	// sbar_fields uses strunzone on the titles!
+	for(i = 0; i < MAX_SBAR_FIELDS; ++i)
+		sbar_title[i] = strzone("(null)");
+
+	postinit = false;
+
+	Sbar_Init();
 }
+
 // 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
+	db_close(configdb);
+	buf_del(databuf);
 }
+
+void PostInit(void)
+{
+	float i;
+
+	print(strcat("PostInit\n    maxclients = ", ftos(maxclients), "\n"));
+	databuf = buf_create();
+	for(i = 0; i < maxclients; ++i)
+	{
+		bufstr_set(databuf, DATABUF_PING + i, "N/A");
+		bufstr_set(databuf, DATABUF_DEATHS + i, "0");
+		bufstr_set(databuf, DATABUF_CAPTURES + i, "0");
+		bufstr_set(databuf, DATABUF_RETURNS + i, "0");
+	}
+	
+	localcmd(strcat("\nsbar_columns_set ", cvar_string("sbar_columns"), ";\n"));
+
+	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.
+void Cmd_Sbar_SetFields(float);
+void Cmd_Sbar_Help(float);
 float CSQC_ConsoleCommand(string strMessage)
 {
-	local float nReturn;
-	local string s;
-	local vector v;
-		nReturn = FALSE;
-		
+	float argc;
 	// Tokenize String
-	tokenize(strMessage);
+	argc = tokenize(strMessage);
 	
 	// Acquire Command
 	local string strCmd;
-		strCmd = argv(0);
+	strCmd = argv(0);
 
-	/*
-	if (strCmd == "+forward")
-	{
-		// blah
-		nReturn = TRUE;
+	/*if(strCmd == "ctf_menu") {
+		ctf_menu_show();
+		nReturn = true;
+		} else*/
+	if(strCmd == "ons_map") {
+		Cmd_ons_map();
+		return true;
+	} else if(strCmd == "sbar_columns_set") {
+		Cmd_Sbar_SetFields(argc);
+		return true;
+	} else if(strCmd == "sbar_columns_help") {
+		Cmd_Sbar_Help(argc);
+		return true;
+	} else if(strCmd == "+showscores") {
+		sb_showscores = true;
+		return true;
+	} else if(strCmd == "-showscores") {
+		sb_showscores = false;
+		return true;
 	}
-	*/
-	return nReturn;
+	
+	return false;
 }
+
+float GameCommand(string msg)
+{
+	float argc;
+	argc = tokenize(msg);
+	string cmd;
+	cmd = argv(0);
+	if(cmd == "mv_download") {
+		Cmd_MapVote_MapDownload(argc);
+		return true;
+	}
+	
+	return false;
+}
+
 // 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.
@@ -44,7 +172,16 @@
 float CSQC_InputEvent(float bInputType, float nPrimary, float nSecondary)
 {
 	local float bSkipKey;
-		bSkipKey = false;
+	bSkipKey = false;
+
+	if(chr2str(nSecondary) == "-") {
+		print(strcat("inputtype: ", ftos(bInputType), "\n"));
+		return true;
+	}
+
+	if(menu_visible)
+		if(menu_action(bInputType, nPrimary, nSecondary))
+			return TRUE;
 	return bSkipKey;
 }
 
@@ -53,45 +190,159 @@
 
 // --------------------------------------------------------------------------
 // BEGIN OPTIONAL CSQC FUNCTIONS
+void ReadONS()
+{
+	entity gps;
+	using_gps = true;
 
+	self.origin_x = ReadCoord();
+	self.origin_y = ReadCoord();
+	self.angles_y = ReadCoord();
+	self.origin_z = self.angles_x = self.angles_z = 0;
+
+	for(gps = gps_start; gps; gps = gps.chain)
+	{
+		if(gps == self)
+			break;
+	}
+	if(!gps)
+	{
+		self.chain = gps_start;
+		gps_start = self;
+	}
+}
+
+void RemoveONS()
+{
+	if(gps_start == self)
+		gps_start = self.chain;
+	else
+	{
+		local entity ent;
+		ent = gps_start;
+			
+		while(ent.chain != self && ent.chain != world)
+			ent = ent.chain;
+		if(ent.chain == self)
+			ent.chain = self.chain;
+	}
+}
+
 // 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(float bIsNewEntity) CSQC_Ent_Update =
 {
+	float msg;
 	self.enttype = ReadByte();
-	/*
-	if (self.enttype == ENT_CLIENT)
+	if(self.enttype == ENT_CLIENT_ENTCS)
 	{
-		setmodelindex(self, ReadShort());
-		self.origin_x = ReadCoord();
-		self.origin_y = ReadCoord();
-		self.origin_z = ReadCoord();
-		self.angles_x = ReadCoord();
-		self.angles_y = ReadCoord();
-		self.angles_z = ReadCoord();
-		self.sv_entnum = ReadShort();
-		setorigin(self, self.origin); // relink
-		if (bIsNewEntity)
+		self.sv_entnum = ReadByte()-1;
+
+		for(msg = ReadByte(); msg != ENTCS_MSG_END; msg = ReadByte())
 		{
-			setsize(self, '0 0 0', '0 0 0');
-			self.drawmask = MASK_NORMAL;
-			self.think = Client_Think;
-			self.nextthink = time;
+			switch(msg)
+			{
+			case ENTCS_MSG_ONS_GPS: ReadONS(); break;
+			case ENTCS_MSG_ONS_REMOVE: RemoveONS(); break;
+			default:
+				error("unknown ENTCS_MSG type\n");
+			}
 		}
 	}
 	else
 		error("unknown entity type in CSQC_Ent_Update\n");
-	*/
+	
 };
 // 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_CLIENT_ENTCS)
+	{
+		if(using_gps) //gametype == GAME_ONSLAUGHT)
+		{
+			if(gps_start == self)
+				gps_start = self.chain;
+			else
+			{
+				local entity ent;
+				ent = gps_start;
+			
+				while(ent.chain != self && ent.chain != world)
+					ent = ent.chain;
+				if(ent.chain == self)
+					ent.chain = self.chain;
+			}
+		}
+	}
 	remove(self);
 }
+
+void Gamemode_Init()
+{
+	local string mapinfo, infoline;
+	local float len;
+	local float file;
+	local vector mi_min, mi_max;
+
+	gametype = cvar("gametype");
+	if(gametype == GAME_ONSLAUGHT) {
+		if(!strcasecmp(substring(mapname, 0, 5), "maps/"))
+			minimapname = substring(mapname, 5, 999);
+		else
+			minimapname = mapname;
+		len = strlen(minimapname);
+		if(!strcasecmp(substring(minimapname, len-4, 4), ".bsp"))
+			minimapname = substring(minimapname, 0, len-4);
+		
+		mapinfo = strcat("maps/", minimapname, ".info");
+		minimapname = strzone(strcat("gfx/", minimapname, "_mini.tga"));
+
+		mi_min = world.mins;
+		mi_max = world.maxs;
+		
+		file = fopen(mapinfo, FILE_READ);
+		if(file >= 0) {
+			while((infoline = fgets(file))) {
+				if(!strncasecmp(infoline, "mins", 4)) {
+					mi_min = stov(substring(infoline, 5, 999));
+				} else if(!strncasecmp(infoline, "maxs", 4)) {
+					mi_max = stov(substring(infoline, 5, 999));
+				} else if(strncasecmp(infoline, "//", 2)) { // don't print comment-style lines
+					print(strcat("mapinfo: ", infoline, "\n"));
+				}
+			}
+		} else {
+			print(strcat("Map has no .info file (", mapinfo, ").\n"));
+		}
+		fclose(file);
+
+		print(strcat("Mins: ", vtos(mi_min), "    Maxs: ", vtos(mi_max), "\n"));
+		
+		mi_center = (mi_min + mi_max) * 0.5;
+		mi_scale = mi_max - mi_min;
+		
+		
+		print(strcat("Using ", minimapname, " as minimap.\n"));
+		precache_pic(minimapname);
+		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);
+	// watch for gametype changes!
+	if(gametype != cvar("gametype"))
+	{
+		Gamemode_Init();
+	}
 }
 // 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)
@@ -103,6 +354,80 @@
 {
 	cprint(strMessage);
 }
+
+void CSQC_CheckRevision();
+
+void Net_ReadInit()
+{
+	csqc_revision = ReadShort();
+	maxclients = ReadByte();
+
+	CSQC_CheckRevision();
+}
+
+void Net_ReadPings()
+{
+	float plnum, ping;
+	for(plnum = ReadByte(); plnum != 0; plnum = ReadByte())
+	{
+		ping = ReadShort();
+		bufstr_set(databuf, DATABUF_PING + plnum-1, ftos(ping));
+	}
+}
+
+void Net_ReadCaptures()
+{
+	float plnum, caps, mode;
+	mode = ReadByte();
+	caps_team1 = ReadByte();
+	caps_team2 = ReadByte();
+	for(plnum = ReadByte(); plnum != 0; plnum = ReadByte())
+	{
+		caps = ReadByte();
+		bufstr_set(databuf, DATABUF_CAPTURES + plnum-1, ftos(caps));
+	}
+}
+
+void Net_ReadDatabuf(float ofs)
+{
+	float plnum, data;
+	for(plnum = ReadByte(); plnum != 0; plnum = ReadByte())
+	{
+		data = ReadByte();
+		bufstr_set(databuf, ofs + plnum-1, ftos(data));
+	}
+}
+
+string Net_ReadPicture()
+{
+	string img;
+	if(csqc_flags & CSQC_FLAG_READPICTURE)
+	{
+		img = ReadPicture();
+		print(strcat("Got Picture: ", img, "\n"));
+	} else {
+		img = ReadString();
+		print(strcat("^3Warning: ^7Couldn't download ", img, ". This is probably because your engine build is outdated.\n"));
+		float psize, i;
+		psize = ReadShort();
+		// Can I be sure that ReadShort is 2 bytes and ReadLong is 4 bytes?
+		// Because then this could be optimized to first get all 4-byte-groups,
+		// then the remaining 2, then the remaining 1
+		for(i = 0; i < psize; ++i)
+			ReadByte();
+	}
+	return img;
+}
+
+void Net_Config()
+{
+	string key, value;
+	key = ReadString();
+	value = ReadString();
+	db_put(configdb, strcat("/v/", key), value);
+	db_put(configdb, strcat("/s/", key), "1");
+}
+
 // 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.
@@ -113,17 +438,70 @@
 	// Acquire TE ID
 	local float nTEID;
 		nTEID = ReadByte();
-		
+
+		// NOTE: Could just do return instead of break...
 	switch(nTEID)
 	{
-		//case TE_GUNSHOT:
-		//	Do something cool with TE_GUNSHOT!
-		//	break;
+		case TE_CSQC_INIT:
+			Net_ReadInit();
+			bHandled = true;
+			break;
+		case TE_CSQC_PING:
+			Net_ReadPings();
+			bHandled = true;
+			break;
+		case TE_CSQC_CAPTURES:
+			Net_ReadCaptures();
+			bHandled = true;
+			break;
+		case TE_CSQC_RETURNS:
+			Net_ReadDatabuf(DATABUF_RETURNS);
+			bHandled = true;
+			break;
+		case TE_CSQC_DEATHS:
+			Net_ReadDatabuf(DATABUF_DEATHS);
+			bHandled = true;
+			break;
+		case TE_CSQC_MAPVOTE:
+			Net_Mapvote();
+			bHandled = true;
+			break;
+		case TE_CSQC_CONFIG:
+			Net_Config();
+			bHandled = true;
+			break;
 		default:
 			// No special logic for this temporary entity; return 0 so the engine can handle it
 			bHandled = false;
 			break;
 	}
+	
+	if(!postinit)
+		PostInit();
 		
 	return bHandled;
-}
\ No newline at end of file
+}
+
+// COMMIT-TODO: Update if necessare, before committing
+float csqc_svn_map[CSQC_REVISION] =
+{
+	3812, // 3795,
+	3820 // mapvote protocol changed from there
+};
+
+// COMMIT-TODO: Update if necessare, before committing
+void CSQC_CheckRevision()
+{
+	if(csqc_revision == CSQC_REVISION)
+	{
+		print("^2SVQC and CSQC revisions are compatible.\n");
+	} else if(csqc_revision < CSQC_REVISION) {
+		print("^1Your csprogs.dat (CSQC) version is newer than the one on the server.\n");
+		print("^1The last known svn revision for the server's CSQC is: ^7");
+		print(ftos(csqc_svn_map[csqc_revision])); // don't use strcat, fteqcc loves screwing up arrays...
+		print("\n");
+	} else if(csqc_revision > CSQC_REVISION) {
+		print("^1Your csprogs.dat (CSQC) is too old for this server.\n");
+		print("^1Please update to a newer version.\n");
+	}
+}

Modified: branches/nexuiz-2.0/data/qcsrc/client/View.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/View.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/client/View.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -1,16 +1,38 @@
-// CSQC_UpdateView - Called every rendered frame on the client.  Useful for HUD drawing operations.
+//include "main.qh"
+
+void CSQC_common_hud(void);
+
+void CSQC_kh_hud(void);
+void CSQC_ctf_hud(void);
+void PostInit(void);
 void CSQC_UpdateView(void)
 {
+	if(!postinit)
+		PostInit();
+	
+	sbar_alpha_fg = cvar("sbar_alpha_fg" );
+	sbar_hudselector = cvar("sbar_hudselector");
+	activeweapon = getstati(STAT_ACTIVEWEAPON);
+	teamplay = cvar("teamplay");
+
+	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);
+	
 	// Draw the Crosshair
 	R_SetView(VF_DRAWCROSSHAIR, 1);
+	
 	// Draw the Engine Status Bar (the default Quake HUD)
-	R_SetView(VF_DRAWENGINESBAR, 1);
+	draw_enginesbar = !cvar("sbar_usecsqc");
+	R_SetView(VF_DRAWENGINESBAR, draw_enginesbar);
 
 	// Set the console size vars
 	vid_conwidth = cvar("vid_conwidth");
@@ -23,20 +45,135 @@
 	mousepos = mousepos*0.5 + getmousepos();
 	*/
 
-	// Update the camera
-	/*
-	UpdateCamera();
-	R_SetView(VF_ORIGIN, self.origin);
-	R_SetView(VF_ANGLES, self.angles);
-	*/
+	R_AddEntities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);
 
-	// Setup Entities to be Rendered (include all base types; normal, engine and viewmodels)
-	R_AddEntities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);
-	
 	// Render the Scene
 	R_RenderScene();
 
 	// Draw the mouse cursor
 	// NOTE: drawpic must happen after R_RenderScene for some reason
-	//drawpic(mousepos, "gfx/cursor.tga", '11 14 0', '1 1 1', 1, 0);
-}
\ No newline at end of file
+	//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 */
+	if(!draw_enginesbar)
+	{
+		CSQC_common_hud();
+	}
+	
+	if(gametype == GAME_ONSLAUGHT)
+	{
+		//drawstring('0 0', minimapname, '8 8 0', '1 1 1', 1, 0);
+		//drawsetcliparea(0,0,800,600);
+		ons_view();
+		//drawresetcliparea();
+	}
+}
+
+void Sbar_Draw();
+void CSQC_common_hud(void)
+{
+	// Sbar_SortFrags(); done in Sbar_Draw
+	Sbar_Draw();
+}
+
+// KeyHunt HUD by victim
+void CSQC_kh_hud(void)
+{
+	// HUD 0 has the weapons on the right hand side - temporarily shown when needed
+	// HUD 1 has the weapons on the bottom - permanently
+
+	// use the following two binds to check the icons move correctly
+	// bind g "toggle sbar_flagstatus_right; echo Menu right $sbar_flagstatus_right"  // move the icons
+	// bind h "toggle sbar_hudselector; echo HUD $sbar_hudselector"  // change the HUD
+
+	float kh_keys, kh_keys_status, kh_teams_set;
+	float kh_margin_x, kh_margin_y, kh_key_box;
+	string kh_carrying, kh_outline;
+	vector red_pos, blue_pos, yellow_pos, pink_pos, kh_size;
+	vector red, blue, yellow, pink;
+
+	kh_keys = getstati(STAT_KH_KEYS);
+	kh_keys_status = kh_keys / 256;
+	kh_teams_set = cvar("_teams_available");  // set in keyhunt.qc
+
+	kh_margin_y = 8;
+	kh_margin_x = (cvar("sbar_flagstatus_right") * sbar_hudselector * (vid_conwidth - 67)) + 10;
+//	sbar_flagstatus_right 0/1; sbar_hudselector 0/1; screen width - key width + margin
+
+	red_pos_x = blue_pos_x = yellow_pos_x = pink_pos_x = kh_margin_x;
+
+	kh_key_box = 120;
+
+	pink_pos_y = kh_margin_y + 0;  // top
+	yellow_pos_y = kh_margin_y + kh_key_box;
+	blue_pos_y = kh_margin_y + kh_key_box * 2;
+	red_pos_y = kh_margin_y + kh_key_box * 3;  //bottom
+
+	red = '1 0 0';
+	blue = '0 0 1';
+	yellow = '1 1 0';
+	pink = '1 0 1';
+
+	kh_size = '0 0';  // don't resize the image
+
+	kh_carrying = "gfx/sb_kh_full";
+	kh_outline = "gfx/sb_kh_outline";
+
+// 	drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
+// 	vector position = '0 0';  // 'x y' 0 0 (the origin) is the top left. X 0 - 799, Y 0 - 599
+
+// 	vector size = '0 0';  // 'x y' changes the x & y dimensions. '0 0' gives the default pic size
+// 	vector rgb = '0 0 0';  // 'r g b' range 0 - 1
+
+	if (kh_keys_status & 1)  // red
+		drawpic (red_pos, kh_carrying, kh_size, red, 0.2, 0);  // show 20% alpha key
+	else
+		drawpic (red_pos, kh_outline, kh_size, red, 0.4, 0);  // show key outline 40% alpha
+
+	if (kh_keys & 1)
+		drawpic (red_pos, kh_carrying, kh_size, red, 1.0, 0);  // show solid key 100% alpha
+
+
+	if (kh_keys_status & 2)  // blue
+		drawpic (blue_pos, kh_carrying, kh_size, blue, 0.2, 0);
+	else
+		drawpic (blue_pos, kh_outline, kh_size, blue, 0.4, 0);
+
+	if (kh_keys & 2)
+		drawpic (blue_pos, kh_carrying, kh_size, blue, 1.0, 0);
+
+
+	if (kh_teams_set & 4)  // yellow
+	{
+		if (kh_keys_status & 4)
+			drawpic (yellow_pos, kh_carrying, kh_size, yellow, 0.2, 0);
+		else
+			drawpic (yellow_pos, kh_outline, kh_size, yellow, 0.4, 0);
+
+		if (kh_keys & 4)
+			drawpic (yellow_pos, kh_carrying, kh_size, yellow, 1.0, 0);
+	}
+
+
+	if (kh_teams_set & 8)  // pink
+	{
+		if (kh_keys_status & 8)
+			drawpic (pink_pos, kh_carrying, kh_size, pink, 0.2, 0);
+		else
+			drawpic (pink_pos, kh_outline, kh_size, pink, 0.4, 0);
+
+		if (kh_keys & 8)
+			drawpic (pink_pos, kh_carrying, kh_size, pink, 1.0, 0);
+	}
+
+}

Modified: branches/nexuiz-2.0/data/qcsrc/client/csqc_builtins.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/csqc_builtins.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/client/csqc_builtins.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -20,7 +20,7 @@
 string (string s)							precache_sound = #19;
 string (string s)							precache_model = #20;
 
-void (string s)								dprint = #25;
+//void (string s)								dprint = #25;
 string (float f)							ftos = #26;
 string (vector v)							vtos = #27;
 void ()									coredump = #28;
@@ -56,7 +56,7 @@
 
 
 void (vector v1, vector min, vector max, vector v2, float nomonsters, entity forent)	tracebox = #90;
-float (string name, string value)					registercvar = #93;
+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;
@@ -97,6 +97,8 @@
 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_engine(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;
@@ -257,3 +259,12 @@
 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;

Modified: branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/client/csqc_constants.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -59,6 +59,8 @@
 const float		STAT_ITEMS						= 15;
 const float		STAT_VIEWHEIGHT					= 16;
 
+const float		STAT_TIMELIMIT					= 236;
+
 // Sound Constants
 const float		CHAN_AUTO						= 0;
 const float		CHAN_WEAPON						= 1;
@@ -159,3 +161,28 @@
 const float BUTTON_14 = 65536;
 const float BUTTON_15 = 131072;
 const float BUTTON_16 = 262144;
+
+
+const float NEX_IT_UZI              = 1;
+const float NEX_IT_SHOTGUN          = 2;
+const float NEX_IT_GRENADE_LAUNCHER = 4;
+const float NEX_IT_ELECTRO          = 8;
+const float NEX_IT_CRYLINK          = 16;
+const float NEX_IT_NEX              = 32;
+const float NEX_IT_HAGAR            = 64;
+const float NEX_IT_ROCKET_LAUNCHER  = 128;
+const float NEX_IT_SHELLS           = 256;
+const float NEX_IT_BULLETS          = 512;
+const float NEX_IT_ROCKETS          = 1024;
+const float NEX_IT_CELLS            = 2048;
+const float NEX_IT_LASER            = 4094;
+const float NEX_IT_STRENGTH         = 8192;
+const float NEX_IT_INVINCIBLE       = 16384;
+const float NEX_IT_SPEED            = 32768;
+const float NEX_IT_SLOWMO           = 65536;
+
+const float DRAWFLAG_NORMAL = 0;
+const float DRAWFLAG_ADDITIVE = 1;
+const float DRAWFLAG_MODULATE = 2;
+const float DRAWFLAG_2XMODULATE = 3;
+const float DRAWFLAG_NUMFLAGS = 4;

Copied: branches/nexuiz-2.0/data/qcsrc/client/ctf.qc (from rev 3761, trunk/data/qcsrc/client/ctf.qc)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/ctf.qc	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/client/ctf.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,216 @@
+//include "main.qh"
+// NOTE: This file contains lots of debugging stuff
+// it is not really used... can be seen as another sample...
+
+string STR_PLAYER = "player";
+#define FOR_EACH_PLAYER(v) for(v = world; (v = find(v, classname, STR_PLAYER)) != world; )
+
+string ctf_temp_1;
+float order_page;
+
+void() menu_close =
+{
+	menu_visible = false;
+	menu_show = menu_show_error;
+	menu_action = menu_sub_null;
+	
+	/*if(ctf_temp_1)
+	  strunzone(ctf_temp_1);*/
+	
+	localcmd("\nin_bindmap 0 0;");
+};
+
+void() order_menu_render =
+{
+	local vector ps, po;
+	local float i, p, n;
+	local string frags, color;
+	ps = '0 200';
+	po = '0 8';
+
+	color = getplayerkey(player_localentnum-1, "topcolor");
+	
+	if(getstati(STAT_CTF_STATE) == CTF_STATE_COMMANDER) {
+		drawstring(ps, "\x1D\x1E\x1E\x1E\x1E Order Menu \x1E\x1E\x1E\x1E\x1F", '8 8 0', '1 1 0', 1, 0); ps += po;
+		drawstring(ps, strcat("Order: ", ctf_temp_1), '8 8 0', '1 1 0', 1, 0); ps += po;
+		drawcolorcodedstring(ps, "1) ^3previous page", '8 8 0', 1, 0); ps += po;
+		drawcolorcodedstring(ps, "2) ^3next page", '8 8 0', 1, 0); ps += po;
+		for((n = 2), (p = i = 0); i < maxclients && n > 0; ++i) {
+			frags = getplayerkey(i, "frags");
+			if(!frags || (i+1) == player_localentnum)
+				continue;
+			if(frags == "-666" || getplayerkey(i, "topcolor") != color)
+				continue;
+			++p;
+			if(p > (8*order_page))
+			{
+				// only render current page
+				++n;
+				if(n == 10)
+					n = 0;
+				drawcolorcodedstring(ps, strcat(ftos(n), ") ", getplayerkey(i, "name"), " : ", ftos(getstatf(STAT_CTF_STATE))), '8 8 0', 1, 0); ps += po;
+			}
+		}
+		drawstring(ps, "ESC) Exit Menu", '8 8 0', '1 1 0', 1, 0); ps += po;
+	} else {
+		menu_close();
+	}
+};
+
+float(float bInputType, float nPrimary, float nSecondary) order_menu_action =
+{
+	local string arg;
+	local float p, i, n, chose;
+	local string frags, color;
+	if(bInputType != 0) // key down wanted
+		return FALSE;
+	
+	arg = chr2str(nSecondary);
+	chose = stof(chr2str(nPrimary));
+	//str2chr
+	if(arg == "1") {
+		color = getplayerkey(player_localentnum-1, "topcolor");
+		++order_page;
+		for(p = i = 0; i < maxclients; ++i) {
+			frags = getplayerkey(i, "frags");
+			if(!frags || (i+1) == player_localentnum)
+				continue;
+			if(frags == "-666" || getplayerkey(i, "topcolor") != color)
+				continue;
+			++p;
+		}
+		if(p <= (8*order_page)) // no ppl on page
+			order_page = 0;
+	} else if(arg == "2") {
+		color = getplayerkey(player_localentnum-1, "topcolor");
+		--order_page;
+		if(order_page < 0) {
+			for(p = i = 0; i < maxclients; ++i) {
+				frags = getplayerkey(i, "frags");
+				if(!frags || (i+1) == player_localentnum)
+					continue;
+				if(frags == "-666" || getplayerkey(i, "topcolor") != color)
+					continue;
+				++p;
+			}
+			order_page = floor(p/8);
+		}
+	} else if(chose >= 3 && chose <= 9 || arg == "0") { // the 10 needs extra checking, assuming that stof(astring) returns 0
+		if(chose == 0)
+			chose = 10;
+		n = 2;
+		color = getplayerkey(player_localentnum-1, "topcolor");
+		for(p = i = 0; i < maxclients && n > 0; ++i) {
+			frags = getplayerkey(i, "frags");
+			if(!frags || (i+1) == player_localentnum)
+				continue;
+			if(frags == "-666" || getplayerkey(i, "topcolor") != color)
+				continue;
+			++p;
+			if(p > (8*order_page))
+			{
+				// only render current page
+				++n;
+				if(n == chose) {
+					n = 0;
+					break;
+				}
+			}
+		}
+		if(n == 0) {
+			//print(strcat("Issuing order to: ", ftos(i+1), "\n"));
+			//print(strcat("cmd order #", ftos(i+1), " ", ctf_temp_1, ";\n"));
+			localcmd(strcat("\ncmd order #", ftos(i+1), " ", ctf_temp_1, ";"));
+		} else {
+			print(strcat("Couldn't find player ", ftos(chose), "\n"));
+		}
+		return TRUE;
+	} else if(nSecondary == K_ESCAPE) {
+		strunzone(ctf_temp_1);
+		menu_close();
+	} else {
+		//print(strcat("Menu action ", arg, " does not exist.\n"));
+		return FALSE;
+	}
+	return TRUE;
+};
+
+void() order_menu_show =
+{
+	order_page = 0;
+	menu_show = order_menu_render;
+	menu_action = order_menu_action;
+};
+
+
+void() ctf_menu_render =
+{
+	local vector ps, po;
+	ps = '0 200';
+	po = '0 8';
+	
+	if(getstati(STAT_CTF_STATE) == CTF_STATE_COMMANDER) {
+		drawstring(ps, "\x1D\x1E\x1E\x1E\x1E Command Menu \x1E\x1E\x1E\x1E\x1F", '8 8 0', '1 1 0', 1, 0); ps += po;
+		drawstring(ps, "Issue orders:", '8 8 0', '1 1 0', 1, 0); ps += po;
+		drawstring(ps, " 1) Attack ", '8 8 0', '1 1 0', 1, 0);
+		drawstring(ps + '80 0', " \x0F", '8 8 0', '1 1 1', 1, 0); ps += po;
+		drawstring(ps, " 2) Defend \x0E", '8 8 0', '1 1 0', 1, 0); ps += po;
+		ps += po;
+		drawstring(ps, "3) Resign from command.", '8 8 0', '1 1 0', 1, 0); ps += po;
+		drawstring(ps, "ESC) Exit Menu", '8 8 0', '1 1 0', 1, 0); ps += po;
+	} else {
+		menu_close();
+	}
+};
+
+float(float bInputType, float nPrimary, float nSecondary) ctf_menu_action =
+{
+	local string arg;
+	if(bInputType != 0) // key down wanted
+		return FALSE;
+	
+	arg = chr2str(nSecondary);
+
+	if(arg == "1") {
+		ctf_temp_1 = strzone("attack");
+		order_menu_show();
+	} else if(arg == "2") {
+		ctf_temp_1 = strzone("defend");
+		order_menu_show();
+	} else if(arg == "3") {
+		localcmd("\ncmd order resign;");
+		menu_close();
+	} else if(nSecondary == K_ESCAPE) {
+		menu_close();
+	} else {
+		//print(strcat("Menu action ", arg, " does not exist.\n"));
+		return FALSE;
+	}
+	return TRUE;
+};
+
+void() ctf_menu_show =
+{
+	if(getstati(STAT_CTF_STATE) < 0)
+		return;
+	menu_show = ctf_menu_render;
+	menu_action = ctf_menu_action;
+	menu_visible = TRUE;
+	//menu_default_binds();
+};
+
+void() ctf_view =
+{
+	local float stat;
+	stat = getstati(STAT_CTF_STATE);
+	if(stat == CTF_STATE_ATTACK) {
+		drawpic('0 0', "gfx/ctf_ic_atk.tga", '64 64 0', '1 1 1', 1, 0);
+	} else if(stat == CTF_STATE_DEFEND) {
+		drawpic('0 0', "gfx/ctf_ic_def.tga", '64 64 0', '1 1 1', 1, 0);
+	} else if(stat == CTF_STATE_COMMANDER) {
+		drawstring('0 0', "You're commander!", '8 8 0', '1 1 1', 1, 0);
+	} else if(stat < 0) {
+	} else {
+		drawstring('0 0', "Awaiting orders...", '8 8 0', '1 1 1', 0.5, 0);
+	}
+};

Copied: branches/nexuiz-2.0/data/qcsrc/client/main.qh (from rev 3761, trunk/data/qcsrc/client/main.qh)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/main.qh	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/client/main.qh	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,90 @@
+// --------------------------------------------------------------------------
+// MENU Functionality
+
+#define DATABUF_PING 0
+#define DATABUF_CAPTURES (1*maxclients)
+#define DATABUF_DEATHS (2*maxclients)
+#define DATABUF_RETURNS (3*maxclients)
+
+#define DATABUF_NEXT (5*maxclients)
+
+void() menu_show_error;
+void() menu_sub_null;
+
+float menu_visible;
+var void() menu_show;
+var float(float bInputType, float nPrimary, float nSecondary) menu_action;
+
+// --------------------------------------------------------------------------
+// CTF
+
+void() ctf_menu_show;
+string ctf_temp_1;
+
+// --------------------------------------------------------------------------
+// Onslaught
+
+// Map coordinate base calculations need these
+vector mi_center;
+vector mi_scale;
+// Minimap
+string minimapname;
+float ons_showmap;
+
+// --------------------------------------------------------------------------
+// General stuff
+
+float csqc_revision;
+
+float drawfont;
+float postinit;
+float gametype;
+entity gps_start;
+
+float draw_enginesbar;
+//float sorted_players;
+//float sorted_teams;
+
+// Defs
+//.float ctf_state;
+//.float health;
+
+// Constants
+const float COLOR_TEAM_RED = 64;
+const float COLOR_TEAM_BLUE = 208;
+
+const float COLOR_TEAM1       = 4;  // red
+const float COLOR_TEAM2       = 13; // blue
+const float COLOR_TEAM3       = 12; // yellow
+const float COLOR_TEAM4       = 9; // pink
+const float COLOR_SPECTATOR = 1337;
+
+#define FONT_DEFAULT 0
+#define FONT_USER 8
+
+// --------------------------------------------------------------------------
+// Scoreboard stuff
+
+#define MAX_SBAR_FIELDS 16
+
+#define SBF_END 0
+#define SBF_PING 1
+#define SBF_NAME 2
+#define SBF_CAPS 3
+#define SBF_RETS 4
+#define SBF_FRAGS 5
+#define SBF_DEATHS 6
+#define SBF_KDRATIO 7
+
+#define SBF_SEPARATOR 100
+
+float sbar_field[MAX_SBAR_FIELDS + 1];
+float sbar_size[MAX_SBAR_FIELDS + 1];
+string sbar_title[MAX_SBAR_FIELDS + 1];
+float sbar_num_fields;
+float sbar_font;
+
+float csqc_flags;
+#define CSQC_FLAG_READPICTURE 1
+
+string config_get(string key, string defaultvalue);

Copied: branches/nexuiz-2.0/data/qcsrc/client/mapvoting.qc (from rev 3821, trunk/data/qcsrc/client/mapvoting.qc)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/mapvoting.qc	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/client/mapvoting.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,328 @@
+float mv_num_maps;
+
+string mv_maps[MAPVOTE_COUNT];
+string mv_pics[MAPVOTE_COUNT];
+string mv_pk3[MAPVOTE_COUNT];
+float mv_preview[MAPVOTE_COUNT];
+float mv_votes[MAPVOTE_COUNT];
+entity mv_pk3list;
+float mv_abstain;
+float mv_ownvote;
+float mv_detail;
+float mv_timeout;
+
+void MapVote_DrawMapItem(vector pos, float isize, string map, string pic, float count, float id)
+{
+	vector img_size;
+	vector rgb;
+	//img_size_x = img_size_y = isize;
+	img_size_y = isize;
+	img_size_x = isize / 0.75; // 4:3 x can be stretched easily, height is defined in isize
+
+	drawpic(pos, pic, img_size, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+	// half size for the impulse number
+	img_size_x = img_size_y = isize*0.5;
+	pos_y += img_size_y*0.5;
+
+	if(id == mv_ownvote)
+		rgb = '1 1 0';
+	else
+		rgb = '1 1 1';
+	
+	drawstring(pos - '40 0', strcat(ftos(id+1), "."), img_size, rgb, 1, DRAWFLAG_NORMAL);
+
+	// half again for the mapname
+	img_size = img_size * 0.5; // *= broken???
+	pos_y += img_size_y*0.5;
+	pos_x += isize/0.75 + 10;
+
+	if(mv_detail)
+		drawstring(pos, strcat(ftos(count), " : ", map), img_size, rgb, 1, DRAWFLAG_NORMAL);
+	else
+		drawstring(pos, map, img_size, rgb, 1, DRAWFLAG_NORMAL);
+}
+
+void MapVote_DrawMapNotAvailable(vector pos, float isize, string map, float count, float id)
+{
+	vector img_size, a, b;
+	vector rgb;
+	img_size_y = isize;
+	img_size_x = isize / 0.75;
+
+	a_x = img_size_x; // for the lines
+	b_y = img_size_y;
+	drawfill(pos, img_size, '.5 .5 .5', .7, DRAWFLAG_NORMAL);
+	drawline(2, pos, pos + a, '1 1 1', 1, DRAWFLAG_NORMAL);
+	drawline(2, pos, pos + b, '1 1 1', 1, DRAWFLAG_NORMAL);
+	drawline(2, pos + img_size, pos + a, '1 1 1', 1, DRAWFLAG_NORMAL);
+	drawline(2, pos + img_size, pos + b, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+	img_size_x = img_size_y = isize*0.5;
+	pos_y += img_size_y*0.5;
+
+	if(id == mv_ownvote)
+		rgb = '1 1 0';
+	else
+		rgb = '1 1 1';
+	
+	drawstring(pos - '40 0', strcat(ftos(id+1), "."), img_size, rgb, 1, DRAWFLAG_NORMAL);
+	
+	img_size = img_size * 0.5; // *= broken???
+	pos_y += img_size_y*0.5;
+	pos_x += isize/0.75 + 10;
+
+	if(mv_detail)
+		drawstring(pos, strcat(ftos(count), " : ", map), img_size, rgb, 1, DRAWFLAG_NORMAL);
+	else
+		drawstring(pos, map, img_size, rgb, 1, DRAWFLAG_NORMAL);
+}
+
+void MapVote_DrawAbstain(vector pos, float isize, float count, float id)
+{
+	vector img_size;
+	vector rgb;
+	img_size_y = isize;
+	img_size_x = isize / 0.75;
+
+	img_size_x = img_size_y = isize*0.5;
+	pos_y += img_size_y*0.5;
+
+	if(id == mv_ownvote)
+		rgb = '1 1 0';
+	else
+		rgb = '1 1 1';
+	
+	drawstring(pos - '40 0', strcat(ftos(id+1), "."), img_size, rgb, 1, DRAWFLAG_NORMAL);
+	
+	img_size = img_size * 0.5; // *= broken???
+	pos_y += img_size_y*0.5;
+	pos_x += isize/0.75 + 10;
+
+	if(mv_detail)
+		drawstring(pos, strcat(ftos(count), " : Don't care"), img_size, rgb, 1, DRAWFLAG_NORMAL);
+	else
+		drawstring(pos, "Don't care", img_size, rgb, 1, DRAWFLAG_NORMAL);
+}
+
+void MapVote_Draw()
+{
+	string map;
+	float i, tmp;
+	vector pos;
+	float isize;
+	float center;
+	
+	center = (vid_conwidth - 1)/2;
+	xmin = vid_conwidth*0.2;
+	xmax = vid_conwidth - xmin;
+	ymin = 24;
+	i = cvar("con_chatpos"); //*cvar("con_chatsize");
+	if(i < 0)
+		ymax = vid_conheight + (i - cvar("con_chat")) * cvar("con_chatsize");
+	if(i >= 0 || ymax < (vid_conheight*0.5))
+		ymax = vid_conheight - ymin;
+
+	drawfont = sbar_font;
+	sbar_fontsize = stov(cvar_string("sbar_fontsize"));
+	if(sbar_fontsize_x == 0)
+		sbar_fontsize = '8 8 0';
+	if(sbar_fontsize_y == 0)
+		sbar_fontsize_y = sbar_fontsize_x;
+
+	pos_y = ymin;
+	pos_z = 0;
+	pos_x = center - stringwidth("Vote for a map", false) * 0.5 * 24;
+	drawstring(pos, "Vote for a map", '24 24', '1 1 1', 1, DRAWFLAG_NORMAL);
+	pos_y += 26;
+
+	i = ceil(mv_timeout - time);
+	map = strcat(ftos(i), " seconds left");
+	pos_x = center - stringwidth(map, false) * 0.5 * 16;
+	drawstring(pos, map, '16 16', '0 1 0', 1, DRAWFLAG_NORMAL);
+	pos_y += 22;
+	pos_x = xmin;
+	
+	isize = (ymax - pos_y - mv_num_maps*10) / mv_num_maps;
+	isize = min(isize, 64);
+	for(i = 0; i < (mv_num_maps - mv_abstain); ++i) // - mv_abstain safe? make sure it's 0 or 1
+	{
+		tmp = mv_votes[i]; // FTEQCC bug: too many array accesses in the function call screw it up
+		if(tmp < 0)
+		{
+			pos_y += isize + 10;
+			continue;
+		}
+		map = mv_maps[i];
+		if(mv_preview[i])
+			MapVote_DrawMapItem(pos, isize, map, mv_pics[i], tmp, i);
+		else
+			MapVote_DrawMapNotAvailable(pos, isize, map, tmp, i);
+		pos_y += isize + 10;
+	}
+	if(mv_abstain && i < mv_num_maps) {
+		tmp = mv_votes[i];
+		MapVote_DrawAbstain(pos, isize, tmp, i);
+	}
+}
+
+void Cmd_MapVote_MapDownload(float argc)
+{
+	float id;
+	entity pak;
+
+	if(argc != 2 || !mv_pk3list)
+	{
+		print("mv_mapdownload: ^3You're not supposed to use this command on your own!\n");
+		return;
+	}
+	
+	id = stof(argv(1));
+	for(pak = mv_pk3list; pak; pak = pak.chain)
+		if(pak.sv_entnum == id)
+			break;
+	
+	if(!pak || pak.sv_entnum != id) {
+		print("^1Error:^7 Couldn't find pak index.\n");
+		return;
+	}
+
+	//print(strcat("^3Adding: ", ftos(id), " - ", pak.message, " - "));
+	
+	if(PreviewExists(pak.message))
+	{
+		mv_preview[id] = true;
+		//print("^2Found...\n");
+		return;
+	} else if(csqc_flags & CSQC_FLAG_READPICTURE) {
+		print("Requesting preview...\n");
+		localcmd(strcat("\ncmd mv_getpic ", ftos(id), "\n"));
+	} else {
+		print("^3Missing map preview - Update to a newer build to be able to see them.\n");
+	}
+}
+
+void MapVote_CheckPK3(string pic, string pk3, float id)
+{
+	entity pak;
+	pak = spawn();
+	pak.netname = pk3;
+	pak.message = pic;
+	pak.sv_entnum = id;
+	
+	pak.chain = mv_pk3list;
+	mv_pk3list = pak;
+	
+	localcmd(strcat("\ncurl --pak ", pk3, "; wait; cl_cmd mv_download ", ftos(id), "\n"));
+}
+
+void MapVote_CheckPic(string pic, string pk3, float id)
+{
+	if(PreviewExists(pic))
+	{
+		mv_preview[id] = true;
+		return;
+	}
+	MapVote_CheckPK3(pic, pk3, id);
+}
+
+void MapVote_Init()
+{
+	float i, power, m;
+	string map, pk3;
+
+	registercmd("+showscores");
+	registercmd("-showscores");
+	
+	mv_num_maps = min(MAPVOTE_COUNT, ReadByte());
+	mv_abstain = ReadByte();
+	if(mv_abstain)
+		mv_abstain = 1; // must be 1 for bool-true, makes stuff easier
+	mv_detail = ReadByte();
+
+	mv_ownvote = -1;
+	mv_timeout = time + ReadByte();
+
+	if(mv_num_maps <= 8)
+		m = ReadByte();
+	else
+		m = ReadShort();
+	
+	// Assume mv_pk3list is NULL, there should only be 1 mapvote per round
+	mv_pk3list = NULL; // I'm still paranoid!
+	
+	for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
+	{
+		mv_votes[i] = 0;
+
+		if(m & power)
+		{
+			map = strzone(ReadString());
+			pk3 = strzone(ReadString());
+			mv_maps[i] = map;
+			mv_pk3[i] = pk3;
+			map = strzone(strcat(config_get("mv_screenshot_dir", "maps"), "/", map));
+			mv_pics[i] = map;
+
+			mv_preview[i] = false;
+
+			//print(strcat("RECV: ", map, " in ", pk3, "\n"));
+			MapVote_CheckPic(map, pk3, i);
+		}
+		else
+		{
+			mv_maps[i] = strzone("if-you-see-this-the-code-is-broken");
+			mv_pk3[i] = strzone("if-you-see-this-the-code-is-broken");
+			mv_pics[i] = strzone("if-you-see-this-the-code-is-broken");
+			mv_preview[i] = false;
+		}
+	}
+}
+
+void MapVote_Update()
+{
+	float i, power;
+	float m;
+	if(mv_num_maps <= 8)
+		m = ReadByte();
+	else
+		m = ReadShort();
+	for(i = 0, power = 1; i < mv_num_maps; ++i, power *= 2)
+	{
+		if(m & power)
+		{
+			if(mv_detail)
+				mv_votes[i] = ReadByte();
+			else
+				mv_votes[i] = 0;
+		}
+		else
+			mv_votes[i] = -1;
+	}
+}
+
+string Net_ReadPicture();
+void Net_Mapvote()
+{
+	float type;
+	type = ReadByte();
+	switch(type)
+	{
+	case MAPVOTE_NET_INIT:
+		MapVote_Init();
+		// do we NEED this, or can we handle key presses directly in CSQC?
+		localcmd("\nin_bind 7 1 \"impulse 1\"; in_bind 7 2 \"impulse 2\"; in_bind 7 3 \"impulse 3\"; in_bind 7 4 \"impulse 4\"; in_bind 7 5 \"impulse 5\"; in_bind 7 6 \"impulse 6\"; in_bind 7 7 \"impulse 7\"; in_bind 7 8 \"impulse 8\"; in_bind 7 9 \"impulse 9\"; in_bind 7 0 \"impulse 10\"; in_bind 7 KP_1 \"impulse 1\"; in_bind 7 KP_2 \"impulse 2\"; in_bind 7 KP_3 \"impulse 3\"; in_bind 7 KP_4 \"impulse 4\"; in_bind 7 KP_5 \"impulse 5\"; in_bind 7 KP_6 \"impulse 6\"; in_bind 7 KP_7 \"impulse 7\"; in_bind 7 KP_8 \"impulse 8\"; in_bind 7 KP_9 \"impulse 9\"; in_bind 7 KP_0 \"impulse 10\"; in_bindmap 7 0\n");
+		break;
+	case MAPVOTE_NET_UPDATE:
+		MapVote_Update();
+		break;
+	case MAPVOTE_NET_OWNVOTE:
+		mv_ownvote = ReadByte()-1;
+		break;
+	case MAPVOTE_NET_PIC:
+		type = ReadByte();
+		mv_preview[type] = true;
+		mv_pics[type] = strzone(Net_ReadPicture());
+		break;
+	}
+}

Copied: branches/nexuiz-2.0/data/qcsrc/client/miscfunctions.qc (from rev 3816, trunk/data/qcsrc/client/miscfunctions.qc)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/miscfunctions.qc	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/client/miscfunctions.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,87 @@
+float databuf;
+var float(string text, float handleColors) stringwidth;
+
+float stringwidth_oldfont(string text, float handleColors)
+{
+	float i, len, ch, width;
+	len = strlen(text);
+	if(!handleColors)
+		return len;
+	width = 0;
+	for(i = 0; i < len; ++i)
+	{
+		if(substring(text, i, 1) == "^")
+		{
+			ch = str2chr(text, i+1);
+			if(ch >= '0' && ch <= '9')
+				++i;
+			else
+				++width;
+		}
+		else
+			++width;
+	}
+	return width;
+}
+
+void CSQC_CheckEngine()
+{
+	/*
+	registercvar("csqc_flags", "0");
+	csqc_flags = cvar("csqc_flags");
+	*/
+
+	csqc_flags = 0;
+	
+	if(checkextension("DP_SV_WRITEPICTURE"))
+	{
+		stringwidth = stringwidth_engine;
+		sbar_font = FONT_USER+1;
+		csqc_flags |= CSQC_FLAG_READPICTURE;
+	} else {
+		stringwidth = stringwidth_oldfont;
+		sbar_font = FONT_DEFAULT;
+	}
+}
+
+vector Sbar_GetFontsize()
+{
+	if(csqc_flags & CSQC_FLAG_READPICTURE)
+		return stov(cvar_string("sbar_fontsize"));
+	return '8 8' ;
+}
+
+float PreviewExists(string name)
+{
+	float f;
+	string file;
+	file = strcat(name, ".tga");
+	f = fopen(file, FILE_READ);
+	if(f >= 0)
+	{
+		fclose(f);
+		return true;
+	}
+	file = strcat(name, ".png");
+	f = fopen(file, FILE_READ);
+	if(f >= 0)
+	{
+		fclose(f);
+		return true;
+	}
+	file = strcat(name, ".jpg");
+	f = fopen(file, FILE_READ);
+	if(f >= 0)
+	{
+		fclose(f);
+		return true;
+	}
+	file = strcat(name, ".pcx");
+	f = fopen(file, FILE_READ);
+	if(f >= 0)
+	{
+		fclose(f);
+		return true;
+	}
+	return false;
+}

Copied: branches/nexuiz-2.0/data/qcsrc/client/ons.qc (from rev 3761, trunk/data/qcsrc/client/ons.qc)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/ons.qc	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/client/ons.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,60 @@
+void() Cmd_ons_map =
+{
+	ons_showmap = !ons_showmap;
+};
+
+vector(vector coord) mapcoords =
+{
+	local vector ret;
+	ret = coord; // put that up to ret's definition and it's '0 0 0' ... stupid fteqcc
+	ret -= mi_center;
+	ret_x = ret_x * 256.0 / mi_scale_x;
+	ret_y = -ret_y * 256.0 / mi_scale_y;
+	ret_z = 0;
+	ret = ret + '400 178';
+	return ret;
+};
+
+void(vector coord, vector pangles, vector rgb) drawplayer =
+{
+	makevectors(pangles);
+	v_forward_z = 0;
+	v_forward = normalize(v_forward);
+	v_forward_y *= -1.0;
+	v_right_x = -v_forward_y;
+	v_right_y = v_forward_x;
+	// Ryling on !tex[0] => texture_white
+	// beware of the order, it has to be clockwise!
+	R_BeginPolygon("", 0);
+	R_PolygonVertex(coord+v_forward*2, '0 0', rgb, 1);
+	R_PolygonVertex(coord+v_right*3-v_forward*2, '0 1', rgb, 1);
+	R_PolygonVertex(coord-v_forward, '1 0', rgb, 1);
+	R_PolygonVertex(coord-v_right*3-v_forward*2, '1 1', rgb, 1);
+	R_EndPolygon();
+};
+
+void() ons_view =
+{
+	if(ons_showmap) {
+		local float color;
+		local vector coord, rgb;
+
+		color = GetPlayerColor(player_localentnum-1);
+		rgb = GetTeamRGB(color);
+
+		coord = mapcoords(pmove_org);
+			
+		drawpic('272 50', minimapname, '256 256', '1 1 1', 1, 0);
+		drawpic('257 35', "gfx/ons-frame.tga", '286 286', '1 1 1', 1, 0);
+		drawpic('257 35', "gfx/ons-frame-team.tga", '286 286', rgb, 1, 0);
+
+		drawplayer(coord, input_angles, '1 1 1');
+
+		local entity tm;
+		for(tm = gps_start; tm != world; tm = tm.chain)
+		{
+			//print(strcat("GPS: ", ftos(tm.sv_entnum), " - ", vtos(tm.origin), "\n"));
+			drawplayer(mapcoords(tm.origin), tm.angles, rgb);
+		}
+	}
+};

Copied: branches/nexuiz-2.0/data/qcsrc/client/pre.qh (from rev 3821, trunk/data/qcsrc/client/pre.qh)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/pre.qh	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/client/pre.qh	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,5 @@
+#ifdef USE_FTE
+#pragma target FTE
+#endif
+
+#define CSQC 1

Modified: branches/nexuiz-2.0/data/qcsrc/client/progs.src
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/progs.src	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/client/progs.src	2008-07-21 14:44:04 UTC (rev 3868)
@@ -1,8 +1,28 @@
 ../../csprogs.dat
+pre.qh
 
 Defs.qc
 csqc_constants.qc
+../common/constants.qh
+
 csqc_builtins.qc
 
+../common/util.qh
+
+main.qh
+
+miscfunctions.qc
+sortlist.qc
+teamplay.qc
+
+ons.qc
+ctf.qc
+
+sbar.qc
+mapvoting.qc
+
 Main.qc
-View.qc
\ No newline at end of file
+View.qc
+
+../common/util.qc
+../common/gamecommand.qc

Copied: branches/nexuiz-2.0/data/qcsrc/client/sbar.qc (from rev 3776, trunk/data/qcsrc/client/sbar.qc)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/sbar.qc	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/client/sbar.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,1375 @@
+
+float last_weapon;
+float activeweapon;
+float weapontime;
+
+float sb_lines; // still don't know what to do with that NOTE: check dp's sbar.c to see what that should be
+
+vector sbar;
+vector sbar_fontsize;
+float sbar_alpha_fg;
+float sbar_hudselector;
+
+entity sortedPlayers;
+entity sortedTeams;
+
+.float sb_frags;
+.float sb_team;
+.float sb_player;
+.float sb_caps;
+
+entity team1, team2, team3, team4, teamspec;
+
+void CSQC_kh_hud();
+void CSQC_ctf_hud();
+void MapVote_Draw();
+void Sbar_FinaleOverlay()
+{
+	/*vector pos;
+	pos_x = (vid_conwidth - 1)/2;
+	pos_y = 16;
+	pos_z = 0;*/
+	
+	//drawpic(pos, "gfx/finale", '0 0', '1 1 1', sbar_alpha_fg, DRAWFLAG_NORMAL);
+	
+	//drawstring(pos, "END", sbar_fontsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+	MapVote_Draw();
+}
+
+void Sbar_DrawWeapon(float nr, float fade, float active)
+{
+	vector pos, vsize, color;
+	float value;
+	
+	value = (active) ? 1 : 0.6;
+	color_x = color_y = color_z = value;
+	
+	if(sbar_hudselector == 1)
+	{
+		// width = 300, height = 100
+		const float w_width = 32, w_height = 12, w_space = 2, font_size = 8;
+		
+		pos_x = (vid_conwidth - w_width * 9) * 0.5 + w_width * nr;
+		pos_y = (vid_conheight - w_height);
+		pos_z = 0;
+		vsize_x = w_width;
+		vsize_y = w_height;
+		vsize_z = 0;
+		drawpic(pos, strcat("gfx/inv_weapon", ftos(nr)), vsize, color, value * fade * sbar_alpha_fg, 0);
+		pos_x += w_space;
+		pos_y += w_space;
+		vsize_x = font_size;
+		vsize_y = font_size;
+		vsize_z = 0;
+		drawstring(pos, ftos(nr+1), vsize, '1 1 0', sbar_alpha_fg, 0);
+
+	}
+	else
+	{
+		// width = 300, height = 100
+		const float w2_width = 300, w2_height = 100, w2_space = 10;
+		const float w2_scale = 0.4;
+
+		pos_x = vid_conwidth - (w2_width + w2_space) * w2_scale;
+		pos_y = (w2_height + w2_space) * w2_scale * nr + w2_space;
+		pos_z = 0;
+		vsize_x = w2_width * w2_scale;
+		vsize_y = w2_height * w2_scale;
+		vsize_z = 0;
+		
+		drawpic(pos, strcat("gfx/inv_weapon", ftos(nr)), vsize, color, value * fade * sbar_alpha_fg, 0);
+	}
+}
+void Sbar_DrawXNum (vector pos, float num, float digits, float lettersize, vector rgb, float a, float dflags)
+{
+	float l, i;
+	string str, tmp;
+	float minus;
+	vector vsize;
+
+	vsize_x = vsize_y = lettersize;
+	vsize_z = 0;
+
+	if(num < 0)
+	{
+		minus = true;
+		num = -num;
+		pos_x -= lettersize;
+	} else
+		minus = false;
+	
+	if(digits < 0)
+	{
+		tmp = ftos(num);
+		digits = -digits;
+		str = strcat(substring("0000000000", 0, digits - strlen(tmp)), tmp);
+	} else
+		str = ftos(num);
+	
+	l = strlen(str);
+
+	if(l > digits)
+	{
+		str = substring(str, l-digits, 999);
+		l = strlen(str);
+	} else if(l < digits)
+		pos_x += (digits-l) * lettersize;
+
+	if(minus)
+	{
+		drawpic(sbar + pos, "gfx/num_minus", vsize, rgb, a * sbar_alpha_fg, dflags);
+		pos_x += lettersize;
+	}
+
+	for(i = 0; i < l; ++i)
+	{
+		drawpic(sbar + pos, strcat("gfx/num_", substring(str, i, 1)), vsize, rgb, a * sbar_alpha_fg, dflags);
+		pos_x += lettersize;
+	}
+}
+
+float Sbar_PlayerCmp(entity l, entity r)
+{
+	if(teamplay)
+	{
+		if(l.sb_team > r.sb_team)
+			return true;
+		else if(l.sb_team > r.sb_team)
+			return false;
+		if(gametype == GAME_CTF)
+		{
+			if(l.sb_caps > r.sb_caps)
+				return true;
+			else if(l.sb_caps < r.sb_caps)
+				return false;
+		}
+	}
+	if(l.sb_frags > r.sb_frags)
+		return true;
+	else if(l.sb_frags < r.sb_frags)
+		return false;
+	return (l.sb_player > r.sb_player);
+}
+float Sbar_TeamCmp(entity l, entity r)
+{
+	if(gametype == GAME_CTF)
+	{
+		if(l.sb_caps > r.sb_caps)
+			return true;
+		else if(l.sb_caps < r.sb_caps)
+			return false;
+	}
+	if(l.sb_frags > r.sb_frags)
+		return true;
+	else if(l.sb_frags < r.sb_frags)
+		return false;
+	return (l.sb_player > r.sb_player);
+}
+
+void Sbar_Init()
+{
+	sortedPlayers = Sort_New(Sbar_PlayerCmp);
+	sortedTeams = Sort_New(Sbar_TeamCmp);
+	team1 = Sort_Next(sortedTeams);
+	team1.sb_team = COLOR_TEAM1;
+	team2 = Sort_Next(sortedTeams);
+	team2.sb_team = COLOR_TEAM2;
+	team3 = Sort_Next(sortedTeams);
+	team3.sb_team = COLOR_TEAM3;
+	team4 = Sort_Next(sortedTeams);
+	team4.sb_team = COLOR_TEAM4;
+	teamspec = Sort_Next(sortedTeams);
+	teamspec.sb_team = COLOR_SPECTATOR;
+}
+
+void Sbar_UpdatePosFrags(entity player)
+{
+	other = player.sort_prev;
+	while(other != sortedPlayers && player.sb_frags > other.sb_frags)
+	{
+		SORT_SWAP(other, player);
+		other = player.sort_prev;
+	}
+
+	other = player.sort_next;
+	while(other && player.sb_frags < other.sb_frags)
+	{
+		SORT_SWAP(player, other);
+		other = player.sort_next;
+	}
+}
+void Sbar_UpdatePosFragsCTF(entity player)
+{
+	other = player.sort_prev;
+	while(other != sortedPlayers && player.sb_frags > other.sb_frags && player.sb_caps == other.sb_caps)
+	{
+		SORT_SWAP(other, player);
+		other = player.sort_prev;
+	}
+
+	other = player.sort_next;
+	while(other && player.sb_frags < other.sb_frags && player.sb_caps == other.sb_caps)
+	{
+		SORT_SWAP(player, other);
+		other = player.sort_next;
+	}
+}
+void Sbar_UpdatePosCaps(entity player)
+{
+	other = player.sort_prev;
+	while(other != sortedPlayers && player.sb_caps > other.sb_caps)
+	{
+		SORT_SWAP(other, player);
+		other = player.sort_prev;
+	}
+	other = player.sort_next;
+	while(other && player.sb_caps < other.sb_caps)
+	{
+		SORT_SWAP(player, other);
+		other = player.sort_next;
+	}
+	// let it update the frags now too, so if we have more frags then the next guy with the same caps
+	// we beat his ass :)
+	player.sb_frags -= 1;
+}
+
+void Sbar_UpdatePosTeam(entity player)
+{
+	player.sb_caps -= 1; // team change needs a full update
+	other = player.sort_prev;
+	while(other != sortedPlayers && player.sb_team > other.sb_team)
+	{
+		SORT_SWAP(other, player);
+		other = player.sort_prev;
+	}
+
+	other = player.sort_next;
+	while(other && player.sb_team < other.sb_team)
+	{
+		SORT_SWAP(player, other);
+		other = player.sort_next;
+	}
+}
+
+void Sbar_UpdatePlayer(entity player)
+{
+	float i;
+
+	if(player.sb_frags == -666)
+		i = COLOR_SPECTATOR;
+	else
+		i = GetPlayerColor(player.sb_player);
+	
+	if(player.sb_team != i)
+	{
+		player.sb_team = i;
+		Sbar_UpdatePosTeam(player);
+	}
+	
+	if(gametype == GAME_CTF)
+	{
+		i = stof(bufstr_get(databuf, DATABUF_CAPTURES + player.sb_player));
+		if(player.sb_caps != i)
+		{
+			player.sb_caps = i;
+			Sbar_UpdatePosCaps(player);
+		}
+		i = stof(getplayerkey(player.sb_player, "frags"));
+		if(player.sb_frags != i)
+		{
+			player.sb_frags = i;
+			Sbar_UpdatePosFragsCTF(player);
+		}
+	} else {
+		i = stof(getplayerkey(player.sb_player, "frags"));
+		if(player.sb_frags != i)
+		{
+			player.sb_frags = i;
+			Sbar_UpdatePosFrags(player);
+		}
+	}
+}
+
+void Sbar_UpdateTeamPosCaps(entity tm)
+{
+	other = tm.sort_prev;
+	while(other != sortedTeams && tm.sb_caps > other.sb_caps)
+	{
+		SORT_SWAP(other, tm);
+		other = tm.sort_prev;
+	}
+
+	other = tm.sort_next;
+	while(other && tm.sb_caps < tm.sb_caps)
+	{
+		SORT_SWAP(tm, other);
+		other = tm.sort_next;
+	}
+}
+void Sbar_UpdateTeamPosFrags(entity tm)
+{
+	other = tm.sort_prev;
+	while(other != sortedTeams && tm.sb_caps == other.sb_caps && tm.sb_frags > other.sb_frags)
+	{
+		SORT_SWAP(other, tm);
+		other = tm.sort_prev;
+	}
+
+	other = tm.sort_next;
+	while(other && tm.sb_caps == tm.sb_caps && tm.sb_frags < other.sb_frags)
+	{
+		SORT_SWAP(tm, other);
+		other = tm.sort_next;
+	}
+}
+
+void Sbar_SortFrags()
+{
+	float i;
+	entity tmp;
+	float t1f, t2f, t3f, t4f;
+	
+	Sort_Reset(sortedPlayers);
+
+	numteams = 0;
+	if(teamplay)
+	{
+		Sort_Reset(sortedTeams);
+		tmp = Sort_Next(sortedTeams);
+
+		team1.sb_player = 0;
+		team2.sb_player = 0;
+		team3.sb_player = 0;
+		team4.sb_player = 0;
+		teamspec.sb_player = 0;
+		
+		t1f = team1.sb_frags;
+		t2f = team2.sb_frags;
+		t3f = team3.sb_frags;
+		t4f = team4.sb_frags;
+
+		team1.sb_frags = 0;
+		team2.sb_frags = 0;
+		team3.sb_frags = 0;
+		team4.sb_frags = 0;
+		
+		for(i = 0; i < maxclients; ++i)
+		{
+			if(strlen(getplayerkey(i, "name")) <= 0)
+				continue;
+
+			Sort_Reset(sortedPlayers);
+
+			tmp = NULL;
+			while(Sort_HasNext(sortedPlayers))
+			{
+				tmp = Sort_Next(sortedPlayers);
+				if(tmp.sb_player == i)
+					break;
+			}
+			if(!tmp || tmp.sb_player != i)
+				tmp = Sort_Next(sortedPlayers);
+			
+			tmp.sb_player = i;
+			tmp.frame = time;
+			Sbar_UpdatePlayer(tmp);
+			
+			switch(tmp.sb_team)
+			{
+			case COLOR_TEAM1: team1.sb_frags += tmp.sb_frags; team1.sb_player++; break;
+			case COLOR_TEAM2: team2.sb_frags += tmp.sb_frags; team2.sb_player++; break;
+			case COLOR_TEAM3: team3.sb_frags += tmp.sb_frags; team3.sb_player++; break;
+			case COLOR_TEAM4: team4.sb_frags += tmp.sb_frags; team4.sb_player++; break;
+			case COLOR_SPECTATOR: teamspec.sb_frags += tmp.sb_frags; teamspec.sb_player++; break;
+			}
+
+			if(i == player_localentnum-1)
+				myteam = tmp.sb_team;
+		}
+		if(team1.sb_player) ++numteams;
+		if(team2.sb_player) ++numteams;
+		if(team3.sb_player) ++numteams;
+		if(team4.sb_player) ++numteams;
+
+		if(team1.sb_caps != caps_team1)
+		{
+			team1.sb_caps = caps_team1;
+			Sbar_UpdateTeamPosCaps(team1);
+		}
+		if(team2.sb_caps != caps_team2)
+		{
+			team2.sb_caps = caps_team2;
+			Sbar_UpdateTeamPosCaps(team2);
+		}
+		if(team1.sb_frags != t1f) Sbar_UpdateTeamPosFrags(team1);
+		if(team2.sb_frags != t2f) Sbar_UpdateTeamPosFrags(team2);
+		if(team3.sb_frags != t3f) Sbar_UpdateTeamPosFrags(team3);
+		if(team4.sb_frags != t4f) Sbar_UpdateTeamPosFrags(team4);
+	} else {
+		for(i = 0; i < maxclients; ++i)
+		{
+			if(strlen(getplayerkey(i, "name")) <= 0)
+				continue;
+		
+			Sort_Reset(sortedPlayers);
+			tmp = NULL;
+			while(Sort_HasNext(sortedPlayers))
+			{
+				tmp = Sort_Next(sortedPlayers);
+				if(tmp.sb_player == i)
+					break;
+			}
+			if(!tmp || tmp.sb_player != i)
+				tmp = Sort_Next(sortedPlayers);
+			
+			tmp.sb_player = i;
+			tmp.frame = time;
+			Sbar_UpdatePlayer(tmp);
+		}
+	}
+	Sort_RemoveOld(sortedPlayers);
+}
+
+void Cmd_Sbar_Help(float argc)
+{
+	print("You can modify the scoreboard using the\n");
+	print("^3|---------------------------------------------------------------|\n");
+	print("^2sbar_columns^7 cvar and the ^2sbar_columns_set command.\n");
+	print("^2sbar_columns^7             specifies the default layout and\n");
+	print("^2sbar_columns_set^7         actually changes the layout.\n");
+	print("You can call ^2sbar_columns_set^7 with the new layout\n");
+	print("as parameters, or eithout parameters it will read the cvar.\n\n");
+	print("Usage:\n");
+	print("^2sbar_columns_set ^7filed1 field2 ...\n");
+	print("Fields which are not relevant to the current gametype\n");
+	print("won't be displayed\n\n");
+	print("The following field names are recognized (case INsensitive):\n");
+	print("^3name^7 or ^3nick^7             Name of a player\n");
+	print("^3caps^7 or ^3captures^7         Number of flags captured\n");
+	print("^3rets^7 or ^3returns^7          Number of flags returned\n");
+	print("^3frags^7 or ^3kills^7           Frags\n");
+	print("^3deaths^7 or ^3dths^7           Number of deaths\n");
+	print("^3kd^7 or ^3kdr^7 or ^3kdratio^7 or ^3k/d\n");
+	print("                         The kill-death ratio\n");
+	print("^3ping^7                     Ping time\n\n");
+	print("You can use a ^3|^7 to start the right-aligned fields.\n");
+	print("Example: ping name | caps rets frags k/d\n");
+	print("This will put the ping and the name on the left side.\n");
+	print("The captures, returns, frags and kill-death ratio will be\n");
+	print("rendered beginning on the right side.\n");
+
+}
+
+#define MIN_NAMELEN 24
+#define MAX_NAMELEN 24
+
+void Cmd_Sbar_SetFields(float argc)
+{
+	float i;
+	string str;
+	float digit;
+
+	if(argc < 2)
+		argc = tokenize(strcat("x ", cvar_string("sbar_columns")));
+	
+	argc = min(MAX_SBAR_FIELDS, argc);
+	sbar_num_fields = 0;
+	drawfont = sbar_font;
+	digit = stringwidth("0123456789", FALSE) / 10;
+	for(i = 0; i < argc-1; ++i)
+	{
+		str = argv(i+1);
+		strunzone(sbar_title[i]);
+		sbar_title[i] = strzone(str);
+		sbar_size[i] = stringwidth(str, FALSE);
+		str = strtolower(str);
+		if(str == "ping") {
+			sbar_field[i] = SBF_PING;
+		} else if(str == "name" || str == "nick") {
+			sbar_field[i] = SBF_NAME;
+			sbar_size[i] = MIN_NAMELEN; // minimum size? any use?
+		} else if(str == "caps" || str == "captures") {
+			if(sbar_size[i] < 3*digit)
+				sbar_size[i] = 3*digit;
+			sbar_field[i] = SBF_CAPS;
+		} else if(str == "rets" || str == "returns") {
+			if(sbar_size[i] < 3*digit)
+				sbar_size[i] = 3*digit;
+			sbar_field[i] = SBF_RETS;
+		} else if(str == "frags" || str == "kills") {
+			if(sbar_size[i] < 5*digit)
+				sbar_size[i] = 5*digit;
+			sbar_field[i] = SBF_FRAGS;
+		} else if(str == "deaths" || str == "dths") {
+			if(sbar_size[i] < 5*digit)
+				sbar_size[i] = 5*digit;
+			sbar_field[i] = SBF_DEATHS;
+		} else if(str == "kdratio") {
+			sbar_field[i] = SBF_KDRATIO;
+		} else if(str == "kdr" || str == "k/d") {
+			sbar_field[i] = SBF_KDRATIO;
+		} else if(str == "kd") {
+			sbar_field[i] = SBF_KDRATIO;
+		} else if(str == "|") {
+			sbar_field[i] = SBF_SEPARATOR;
+		} else {
+			print(strcat("^1Error:^7 Unknown score field: '", str, "'\n"));
+			--sbar_num_fields;
+		}
+		++sbar_num_fields;
+	}
+	sbar_field[i] = SBF_END;
+}
+
+vector sbar_field_rgb;
+string Sbar_GetField(entity pl, float field)
+{
+	float tmp;
+	string str;
+	sbar_field_rgb = '1 1 1';
+	switch(field)
+	{
+	case SBF_PING:
+		str = bufstr_get(databuf, DATABUF_PING + pl.sb_player);
+		tmp = max(0, min(220, stof(str)-80)) / 220;
+		sbar_field_rgb = '1 1 1' - '0 1 1'*tmp;
+		return str;
+	case SBF_NAME: return getplayerkey(pl.sb_player, "name");
+	case SBF_CAPS: return ftos(pl.sb_caps);
+	case SBF_RETS: return bufstr_get(databuf, DATABUF_RETURNS + pl.sb_player);
+	case SBF_FRAGS: return ftos(pl.sb_frags);
+	case SBF_DEATHS: return bufstr_get(databuf, DATABUF_DEATHS + pl.sb_player);
+	case SBF_KDRATIO:
+		tmp = stof(bufstr_get(databuf, DATABUF_DEATHS + pl.sb_player));
+		if(tmp == 0) {
+			sbar_field_rgb = '0 1 0';
+			str = ftos(pl.sb_frags);
+		} else if(pl.sb_frags <= 0) {
+			sbar_field_rgb = '1 0 0';
+			str = ftos(pl.sb_frags / tmp);
+		} else
+			str = ftos(pl.sb_frags / tmp);
+		
+		tmp = strstrofs(str, ".", 0);
+		if(tmp > 0)
+			str = substring(str, 0, tmp+2);
+		return str;
+	}
+}
+#define SBAR_DEFAULT_MASK 0
+#define SBAR_MASK_SPECTATORS 1
+float Sbar_IsFieldMasked(float field, float mask)
+{
+	if(mask&1) // spectator
+		return (field != SBF_NAME && field != SBF_PING);
+	if(gametype != GAME_CTF)
+	{
+		if(field == SBF_CAPS || field == SBF_RETS)
+			return true;
+	}
+	return false;
+}
+
+// shamelessly stolen from menu QC :P <- as if I would steal YOUR code pfft ;)
+float textLengthUpToWidth(string theText, float maxWidth, float handleColors)
+{
+	// STOP.
+	// The following function is SLOW.
+	// For your safety and for the protection of those around you...
+	// DO NOT CALL THIS AT HOME.
+	// No really, don't.
+	if(stringwidth(theText, handleColors) <= maxWidth)
+		return strlen(theText); // yeah!
+
+	// binary search for right place to cut string
+	float left, right, middle; // this always works
+	left = 0;
+	right = strlen(theText); // this always fails
+	do
+	{
+		middle = floor((left + right) / 2);
+		if(stringwidth(substring(theText, 0, middle), handleColors) <= maxWidth)
+			left = middle;
+		else
+			right = middle;
+	}
+	while(left < right - 1);
+
+	// NOTE: when color codes are involved, this binary search is,
+	// mathematically, BROKEN. However, it is obviously guaranteed to
+	// terminate, as the range still halves each time - but nevertheless, it is
+	// guaranteed that it finds ONE valid cutoff place (where "left" is in
+	// range, and "right" is outside).
+
+	return left;
+}
+string textShortenToWidth(string theText, float maxWidth, float handleColors)
+{
+	if(stringwidth(theText, handleColors) <= maxWidth)
+		return theText;
+	else
+		return strcat(substring(theText, 0, textLengthUpToWidth(theText, maxWidth - stringwidth("...", handleColors), handleColors)), "...");
+}
+
+float xmin, xmax, ymin, ymax, sbwidth, sbheight;
+void Sbar_PrintScoreboardItem(vector pos, entity pl, float is_self, float mask)
+{
+	vector tmp;
+	string str;
+	float i, field, len;
+
+	// Layout:
+	tmp_z = 0;
+	if(is_self)
+	{
+		tmp_x = sbwidth;
+		tmp_y = sbar_fontsize_y;
+		drawfill(pos - '1 1', tmp + '2 2', '1 1 1', 0.3, DRAWFLAG_NORMAL);
+	}	
+	tmp_y = 0;
+	
+	for(i = 0; i < sbar_num_fields; ++i)
+	{
+		field = sbar_field[i];
+		if(field == SBF_SEPARATOR)
+			break;
+		if(Sbar_IsFieldMasked(field, mask))
+			continue;
+
+		str = Sbar_GetField(pl, field);
+
+		if(field == SBF_NAME)
+		{
+			float realsize;
+			float j;
+			realsize = sbar_size[i];
+			if(i+1 < sbar_num_fields)
+				if(sbar_field[i+1] == SBF_SEPARATOR)
+				{
+					realsize = (xmax - xmin) / sbar_fontsize_x;
+					print("remaining size: ", ftos(realsize), "\n");
+					for(j = 0; j < sbar_num_fields; ++j) if(j != i) if(sbar_field[j] != SBF_SEPARATOR)
+						realsize -= sbar_size[j] + 1;
+					realsize += 1;
+					print("remaining size: ", ftos(realsize), "\n");
+				}
+			str = textShortenToWidth(str, realsize, TRUE);
+		}
+		len = stringwidth(str, TRUE);
+		
+		if(sbar_size[i] < len)
+			sbar_size[i] = len;
+
+		pos_x += sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+		if(field == SBF_NAME) {
+			tmp_x = sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+			drawcolorcodedstring(pos - tmp, str, sbar_fontsize, 1, DRAWFLAG_NORMAL);
+		} else {
+			tmp_x = len*sbar_fontsize_x + sbar_fontsize_x;
+			drawstring(pos - tmp, str, sbar_fontsize, sbar_field_rgb, 1, DRAWFLAG_NORMAL);
+		}
+	}
+	
+	if(sbar_field[i] == SBF_SEPARATOR)
+	{
+		pos_x = xmax;
+		for(i = sbar_num_fields-1; i > 0; --i)
+		{
+			field = sbar_field[i];
+			if(field == SBF_SEPARATOR)
+				break;
+			if(Sbar_IsFieldMasked(field, mask))
+				continue;
+			
+			str = Sbar_GetField(pl, field);
+
+			if(field == SBF_NAME)
+				str = textShortenToWidth(str, sbar_size[i], TRUE);
+			len = stringwidth(str, TRUE);
+
+			if(sbar_size[i] < len)
+				sbar_size[i] = len;
+			
+			if(field == SBF_NAME) {
+				tmp_x = sbar_fontsize_x*len; // left or right aligned? let's put it right...
+				drawcolorcodedstring(pos - tmp, str, sbar_fontsize, 1, DRAWFLAG_NORMAL);
+			} else {
+				tmp_x = sbar_fontsize_x*len; //strlen(str);
+				drawstring(pos - tmp, str, sbar_fontsize, sbar_field_rgb, 1, DRAWFLAG_NORMAL);
+			}
+			pos_x -= sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+		}
+	}
+}
+
+void Sbar_DrawScoreboard()
+{
+	//float xmin, ymin, xmax, ymax;
+	vector rgb, pos, tmp, sbar_save;
+	entity pl, tm;
+	float specs, i;
+	float center_x;
+
+	sbar_fontsize = Sbar_GetFontsize();
+	if(sbar_fontsize_x == 0)
+		sbar_fontsize = '8 8 0';
+	if(sbar_fontsize_y == 0)
+		sbar_fontsize_y = sbar_fontsize_x;
+	
+	xmin = vid_conwidth / 5;
+	ymin = 20;
+
+	xmax = vid_conwidth - xmin;
+	ymax = vid_conheight - 0.2*vid_conheight;
+
+	sbwidth = xmax - xmin;
+	sbheight = ymax - ymin;
+
+	center_x = xmin + 0.5*sbwidth;
+
+	//Sbar_UpdateFields();
+
+	// Initializes position
+	//pos_x = xmin;
+	pos_y = ymin;
+	pos_z = 0;
+
+	// Heading
+	drawfont = sbar_font;
+	pos_x = center_x - stringwidth("Scoreboard", TRUE)*0.5*24;
+	drawstring(pos, "Scoreboard", '24 24', '1 1 1', 1, DRAWFLAG_NORMAL);
+	pos_x = xmin;
+	pos_y += 24 + 4;
+
+	// Titlebar background:
+	tmp_x = sbwidth;
+	tmp_y = sbar_fontsize_y;
+	drawfill(pos - '1 1', tmp + '2 2', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
+	
+	for(i = 0; i < sbar_num_fields; ++i)
+	{
+		if(Sbar_IsFieldMasked(sbar_field[i], SBAR_DEFAULT_MASK))
+			continue;
+		if(sbar_field[i] == SBF_SEPARATOR)
+			break;
+		drawstring(pos, sbar_title[i], sbar_fontsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+		pos_x += sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+	}
+	
+	if(sbar_field[i] == SBF_SEPARATOR)
+	{
+		pos_x = xmax + sbar_fontsize_x;
+		tmp_y = tmp_z = 0;
+		for(i = sbar_num_fields-1; i > 0; --i)
+		{
+			if(Sbar_IsFieldMasked(sbar_field[i], SBAR_DEFAULT_MASK))
+				continue;
+			if(sbar_field[i] == SBF_SEPARATOR)
+				break;
+			
+			pos_x -= sbar_fontsize_x*sbar_size[i] + sbar_fontsize_x;
+			/**
+			 * FTEQCC BUG!
+			 * Using the following line will fuck it all up:
+			 **
+			 * tmp_x = sbar_size[i] - strlen(sbar_title[i])*8;
+			 */
+			tmp_x = sbar_fontsize_x*sbar_size[i];
+			tmp_x -= stringwidth(sbar_title[i], FALSE)*sbar_fontsize_x;
+			drawstring(pos + tmp, sbar_title[i], sbar_fontsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+		}
+	}
+		
+	pos_x = xmin;
+	pos_y += 1.5 * sbar_fontsize_y;
+
+	sbar_save = sbar;
+	sbar = '0 0 0';
+	
+	if(teamplay)
+	{
+		for(tm = sortedTeams.sort_next; tm; tm = tm.sort_next)
+		{
+			if(!tm.sb_player || tm.sb_team == COLOR_SPECTATOR) // no players in it?
+				continue;
+
+			rgb = GetTeamRGB(tm.sb_team);
+
+			pos_x = xmin - 4*24;
+			if(gametype == GAME_CTF)
+			{
+				if(tm.sb_team == COLOR_TEAM1)
+					Sbar_DrawXNum(pos, caps_team1, 4, 24, rgb, 1, DRAWFLAG_NORMAL);
+				else if(tm.sb_team == COLOR_TEAM2)
+					Sbar_DrawXNum(pos, caps_team2, 4, 24, rgb, 1, DRAWFLAG_NORMAL);
+				pos_x = xmin - 4*10;
+				Sbar_DrawXNum(pos + '0 24', tm.sb_frags, 4, 10, rgb, 1, DRAWFLAG_NORMAL);
+				pos_x = xmin;
+			} else
+				Sbar_DrawXNum(pos, tm.sb_frags, 4, 24, rgb, 1, DRAWFLAG_NORMAL);
+			pos_x = xmin;
+
+			// abuse specs as playerounter
+			specs = 0;
+			for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
+			{
+				if(pl.sb_team == tm.sb_team)
+					++specs;
+			}
+
+			if(specs < 2)
+				specs = 2;
+			if(gametype == GAME_CTF && specs < 4)
+				specs = 4;
+			
+			tmp_x = sbwidth;
+			tmp_y = 1.25 * sbar_fontsize_y * specs;
+			drawfill(pos - '1 1', tmp + '2 0', rgb, 0.2, DRAWFLAG_NORMAL);
+			
+			for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
+			{
+				if(pl.sb_team != tm.sb_team)
+					continue;
+				Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), SBAR_DEFAULT_MASK);
+				pos_y += 1.25 * sbar_fontsize_y;
+				tmp_y -= 1.25 * sbar_fontsize_y;
+			}
+			pos_y += tmp_y + 1.5 * sbar_fontsize_y;
+		}
+		// rgb := tempvector :)
+		rgb = pos + '0 1.5 0' * sbar_fontsize_y;
+		pos_y += 3 * sbar_fontsize_y;
+		specs = 0;
+		for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
+		{
+			if(pl.sb_team != COLOR_SPECTATOR)
+				continue;
+			//drawcolorcodedstring(pos, getplayerkey(pl.sb_player, "name"), '8 8 0', 1, 0);
+			Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), SBAR_MASK_SPECTATORS);
+			pos += '0 1.25 0' * sbar_fontsize_y;
+			++specs;
+		}
+			
+		if(specs)
+			drawstring(rgb, "Spectators", sbar_fontsize, '1 1 1', 1, 0);
+	} else {
+		pos_x = xmin;
+		for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
+		{
+			if(pl.sb_team == COLOR_SPECTATOR)
+				continue;
+			Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), SBAR_DEFAULT_MASK);
+			pos_y += 1.25 * sbar_fontsize_y;
+			tmp_y -= 1.25 * sbar_fontsize_y;
+		}
+
+		// rgb := tempvector :)
+		rgb = pos + '0 1.5 0' * sbar_fontsize_y;
+		pos_y += 3 * sbar_fontsize_y;
+		specs = 0;
+		for(pl = sortedPlayers.sort_next; pl; pl = pl.sort_next)
+		{
+			if(pl.sb_team != COLOR_SPECTATOR)
+				continue;
+			//drawcolorcodedstring(pos, getplayerkey(pl.sb_player, "name"), '8 8 0', 1, 0);
+			Sbar_PrintScoreboardItem(pos, pl, (pl.sb_player == player_localentnum - 1), SBAR_MASK_SPECTATORS);
+			pos += '0 1.25 0' * sbar_fontsize_y;
+			++specs;
+		}
+			
+		if(specs)
+			drawstring(rgb, "Spectators", sbar_fontsize, '1 1 1', 1, 0);
+	}
+	sbar = sbar_save;
+}
+
+void Sbar_Score(float margin)
+{
+	float timelimit, timeleft, minutes, seconds, distribution, myplace;
+	vector sbar_save, place;
+	entity tm, pl, me;
+	sbar_save = sbar;
+
+	sbar_y = vid_conheight - (32+12);
+	sbar_x -= margin;
+	
+	place = '-48 -12 0';
+	if(teamplay)
+	{
+		// Layout:
+		//
+		//   team1 team3 team4
+		//
+		//         TEAM2
+		//for(i = 0; i < 4; ++i)
+		for(tm = sortedTeams.sort_next; tm; tm = tm.sort_next)
+		{
+			if(tm.sb_team == COLOR_SPECTATOR || !tm.sb_player) // no players? don't display
+				continue;
+			// -32*4 = -128
+			if(tm.sb_team == myteam)
+				Sbar_DrawXNum('-128 0', tm.sb_frags, 4, 32, GetTeamRGB(tm.sb_team), 1, DRAWFLAG_NORMAL);
+			else
+			{
+				Sbar_DrawXNum(place, tm.sb_frags, 4, 12, GetTeamRGB(tm.sb_team), 1, DRAWFLAG_NORMAL);
+				place_x -= 4*12;
+			}
+		}
+	} else {
+		// me vector := [team/connected frags id]
+		myplace = 0;
+		for(me = sortedPlayers.sort_next; me; me = me.sort_next)
+		{
+			if(me.sb_team != COLOR_SPECTATOR)
+				++myplace;
+			if(me.sb_player == player_localentnum - 1)
+				break;
+		}
+		pl = sortedPlayers.sort_next;
+		if(pl == me)
+			pl = pl.sort_next;
+		
+		if(pl && myplace != 1)
+		{
+			distribution = me.sb_frags - pl.sb_frags;
+		} else if(pl) {
+			distribution = me.sb_frags - pl.sb_frags;
+		} else
+			distribution = 0;
+		
+		if(myplace == 1)
+			Sbar_DrawXNum('-36 -12', myplace, 3, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
+		else if(myplace == 2)
+			Sbar_DrawXNum('-36 -12', myplace, 3, 12, '1 1 0', 1, DRAWFLAG_NORMAL);
+		else
+			Sbar_DrawXNum('-36 -12', myplace, 3, 12, '1 0 0', 1, DRAWFLAG_NORMAL);
+
+		if(distribution >= 0)
+		{
+			Sbar_DrawXNum('-84 -12', distribution, 4, 12, ' 1 1 1', 1, DRAWFLAG_NORMAL);
+			Sbar_DrawXNum('-128 0', me.sb_frags, 4, 32, '1 1 1', 1, DRAWFLAG_NORMAL);
+		} else if(distribution >= -5)
+		{
+			Sbar_DrawXNum('-84 -12', distribution, 4, 12, ' 1 1 0', 1, DRAWFLAG_NORMAL);
+			Sbar_DrawXNum('-128 0', me.sb_frags, 4, 32, '1 1 0', 1, DRAWFLAG_NORMAL);
+		} else {
+			Sbar_DrawXNum('-84 -12', distribution, 4, 12, ' 1 0 0', 1, DRAWFLAG_NORMAL);
+			Sbar_DrawXNum('-128 0', me.sb_frags, 4, 32, '1 0 0', 1, DRAWFLAG_NORMAL);
+		}
+	}
+	timelimit = getstatf(STAT_TIMELIMIT);
+	if(timelimit)
+	{
+		timeleft = max(0, timelimit * 60 - time);
+		minutes = floor(timeleft / 60);
+		seconds = floor(timeleft - minutes*60);
+		if(minutes >= 5)
+		{
+			Sbar_DrawXNum('-72 32', minutes, 3, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
+			drawpic(sbar + '-36 32', "gfx/num_colon", '12 12', '1 1 1', sbar_alpha_fg, 0);
+			Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
+		} else if(minutes >= 1)
+		{
+			Sbar_DrawXNum('-72 32', minutes, 3, 12, '1 1 0', 1, DRAWFLAG_NORMAL);
+			drawpic(sbar + '-36 32', "gfx/num_colon", '12 12', '1 1 0', sbar_alpha_fg, 0);
+			Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 1 0', 1, DRAWFLAG_NORMAL);
+		} else {
+			Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 0 0', 1, DRAWFLAG_NORMAL);
+		}
+	} else {
+		minutes = floor(time / 60);
+		seconds = floor(time - minutes*60);
+		Sbar_DrawXNum('-72 32', minutes, 3, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
+		drawpic(sbar + '-36 32', "gfx/num_colon", '12 12', '1 1 1', sbar_alpha_fg, 0);
+		Sbar_DrawXNum('-24 32', seconds, -2, 12, '1 1 1', 1, DRAWFLAG_NORMAL);
+	}
+	sbar = sbar_save;
+}
+
+void Sbar_MiniscoreItem(vector pos, entity pl, float is_self)
+{
+	float x;
+	pos_x += 72;
+	
+	if(teamplay)
+		drawfill(pos + '0 1 0', '40 6 0', GetTeamRGB(pl.sb_team)*0.5, 1, DRAWFLAG_NORMAL);
+	else
+		drawfill(pos + '0 1 0', '40 6 0', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
+	x = pos_x;
+	pos_x += 5*8;
+	pos_x -= stringwidth(ftos(pl.sb_frags), FALSE)*8;
+	drawstring(pos, ftos(pl.sb_frags), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+	pos_x = x;
+	if(is_self)
+	{
+		pos_x += 48;
+		drawstring(pos, "\x0D", '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+		pos_x += 8;
+	} else
+		pos_x += 56;
+	drawcolorcodedstring(pos, getplayerkey(pl.sb_player, "name"), '8 8 0', 1, 0);
+}
+
+void Sbar_MiniscoreTeamItem(vector pos, float color, float frags, float is_self)
+{
+	float x;
+	pos_x += 72;
+	
+	if(teamplay)
+		drawfill(pos + '0 1 0', '40 6 0', GetTeamRGB(color)*0.5, 1, DRAWFLAG_NORMAL);
+	else
+		drawfill(pos + '0 1 0', '40 6 0', '0.5 0.5 0.5', 0.5, DRAWFLAG_NORMAL);
+	x = pos_x;
+	pos_x += 5*8;
+	pos_x -= stringwidth(ftos(frags), FALSE)*8;
+	drawstring(pos, ftos(frags), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+	pos_x = x;
+	if(is_self)
+	{
+		pos_x += 48;
+		drawstring(pos, "\x0D", '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+		pos_x += 8;
+	} else
+		pos_x += 56;
+	drawstring(pos, GetTeamName(color), '8 8 0', '1 1 1', 1, DRAWFLAG_NORMAL);
+}
+
+void Sbar_MiniDeathmatchOverlay(vector pos)
+{
+	float numlines, up, down;
+	entity me, tm, pl;
+	float miniscoreboard_size;
+	miniscoreboard_size = cvar("sbar_miniscoreboard_size");
+	
+	if(miniscoreboard_size == 0)
+		return;
+	pos_y = vid_conheight - 8;
+	
+	if(miniscoreboard_size < 0)
+		numlines = (vid_conheight - sbar_y + 7) / 8;
+	else
+		numlines = miniscoreboard_size;
+
+	// give up if there isn't enough room
+	if(pos_x >= vid_conwidth || pos_y >= vid_conheight || numlines < 1)
+		return;
+
+	// me vector := [team/connected frags id]
+	for(me = sortedPlayers.sort_next; me; me = me.sort_next)
+	{
+		if(me.sb_player == player_localentnum - 1)
+			break;
+	}
+
+	if(teamplay)
+		numlines -= numteams;
+
+	// figure out how many players above and below we can show
+	up = floor(numlines/2);
+	down = up;
+	if((up + down) > numlines)
+		down = numlines - up;
+
+	// render bottom-up
+	for(pl = me.sort_next; pl && down > 0; pl = pl.sort_next)
+	{
+		if(pl.sb_team == COLOR_SPECTATOR)
+			continue;
+		Sbar_MiniscoreItem(pos, pl, false);
+		pos_y -= 9;
+		--down;
+	}
+	Sbar_MiniscoreItem(pos, me, true);
+	pos_y -= 9;
+	up += down; // if there weren't enough lines below... add them
+	for(pl = me.sort_prev; pl != sortedPlayers && up > 0; pl = pl.sort_prev)
+	{
+		if(pl.sb_team == COLOR_SPECTATOR)
+			continue;
+		Sbar_MiniscoreItem(pos, pl, false);
+		pos_y -= 9;
+		--up;
+	}
+
+	if(teamplay)
+	{
+		for(tm = sortedTeams.sort_next; tm.sort_next; tm = tm.sort_next);
+		for(; tm != sortedTeams; tm = tm.sort_prev)
+		{
+			if(!tm.sb_player || tm.sb_team == COLOR_SPECTATOR) // no players?
+				continue;
+			Sbar_MiniscoreTeamItem(pos, tm.sb_team, tm.sb_frags, (tm.sb_team == me.sb_team));
+			pos_y -= 9;
+		}
+	}
+}
+
+void Sbar_Draw (void)
+{
+	float i;
+	float x, fade;
+	float stat_items;
+
+	Sbar_SortFrags();
+
+	sb_lines = 24;
+	
+	if (sb_showscores)
+		Sbar_DrawScoreboard();
+	else if (intermission == 1)
+	{
+		Sbar_DrawScoreboard();
+		return;
+	}
+	else if (intermission == 2)
+		Sbar_FinaleOverlay();
+	else
+	{
+		if (sb_showscores || (getstati(STAT_HEALTH) <= 0 && cvar("cl_deathscoreboard")))
+		{
+			sbar_x = (vid_conwidth - 640.0)*0.5;
+			sbar_y = vid_conheight - 47;
+			//Sbar_DrawAlphaPic (sbar_x, sbar_y, sb_scorebar, sbar_alpha_bg.value);
+			//drawpic('0 0', "gfx/scorebar", '0 0 0', '1 1 1', cvar("sbar_alpha_bg"), 0);
+			Sbar_DrawScoreboard ();
+		}
+		else
+		{
+			if (sb_lines && sbar_hudselector == 1)
+			{
+				stat_items = getstati(STAT_ITEMS);
+
+				sbar_x = (vid_conwidth - 320.0)*0.5;
+				sbar_y = vid_conheight - 24.0 - 16.0;
+				sbar_z = 0;
+			
+				fade = 3.2 - 2 * (time - weapontime);
+				fade = bound(0.7, fade, 1);
+
+				x = 1.0;
+				for(i = 0; i < 8; ++i)
+				{
+					if(stat_items & x)
+					{
+						Sbar_DrawWeapon(i+1, fade, (i + 2 == activeweapon));
+					}
+					x *= 2;
+				}
+				x *= 2*2*2*2;
+				if(stat_items & x)
+				{
+					Sbar_DrawWeapon(0, fade, (activeweapon == 1));
+				}
+
+				// armor
+				x = getstati(STAT_ARMOR);
+				if (x > 0)
+				{
+					// "gfx/sb_armor"
+					//Sbar_DrawStretchPic (72, 0, sb_armor[0], sbar_alpha_fg.value, 24, 24);
+					drawpic(sbar + '72 0', "gfx/sb_armor", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+					if(x > 200)
+						Sbar_DrawXNum('0 0', x, 3, 24, '0 1 0', 1, 0);
+					else if(x > 100)
+						Sbar_DrawXNum('0 0', x, 3, 24, '0.2 1 0', 1, 0);
+					else if(x > 50)
+						Sbar_DrawXNum('0 0', x, 3, 24, '0.6 0.7 0.8', 1, 0);
+					else if(x > 25)
+						Sbar_DrawXNum('0 0', x, 3, 24, '1 1 0.2', 1, 0);
+					else
+						Sbar_DrawXNum('0 0', x, 3, 24, '0.7 0 0', 1, 0);
+				}
+
+				// health
+				x = getstati(STAT_HEALTH);
+				if (x != 0)
+				{
+					// "gfx/sb_health"
+					//Sbar_DrawStretchPic (184, 0, sb_health, sbar_alpha_fg.value, 24, 24);
+					drawpic(sbar + '184 0', "gfx/sb_health", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+					if(x > 200)
+						Sbar_DrawXNum('112 0', x, 3, 24, '0 1 0', 1, 0);
+					else if(x > 100)
+						Sbar_DrawXNum('112 0', x, 3, 24, '0.2 1 0', 1, 0);
+					else if(x > 50)
+						Sbar_DrawXNum('112 0', x, 3, 24, '0.6 0.7 0.8', 1, 0);
+					else if(x > 25)
+						Sbar_DrawXNum('112 0', x, 3, 24, '1 1 0.2', 1, 0);
+					else
+						Sbar_DrawXNum('112 0', x, 3, 24, '0.7 0 0', 1, 0);
+				}
+
+				// ammo
+				x = getstati(STAT_AMMO);
+				if ((stat_items & (NEX_IT_SHELLS | NEX_IT_BULLETS | NEX_IT_ROCKETS | NEX_IT_CELLS)) || x != 0)
+				{
+					if (stat_items & NEX_IT_SHELLS)
+						drawpic(sbar + '296 0', "gfx/sb_shells", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+					else if (stat_items & NEX_IT_BULLETS)
+						drawpic(sbar + '296 0', "gfx/sb_bullets", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+					else if (stat_items & NEX_IT_ROCKETS)
+						drawpic(sbar + '296 0', "gfx/sb_rocket", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+					else if (stat_items & NEX_IT_CELLS)
+						drawpic(sbar + '296 0', "gfx/sb_cells", '24 24 0', '1 1 1', sbar_alpha_fg, 0);
+					if(x > 10)
+						Sbar_DrawXNum('224 0', x, 3, 24, '0.6 0.7 0.8', 1, 0);
+					else
+						Sbar_DrawXNum('224 0', x, 3, 24, '0.7 0 0', 1, 0);
+				}
+
+				if (sbar_x + 320 + 160 <= vid_conwidth)
+					Sbar_MiniDeathmatchOverlay(sbar + '320 0');
+				if (sbar_x > 0)
+					Sbar_Score(16);
+				// The margin can be at most 8 to support 640x480 console size:
+				//   320 + 2 * (144 + 16) = 640
+			}
+			else if (sb_lines)
+			{
+			
+				stat_items = getstati(STAT_ITEMS);
+			
+				sbar_x = (vid_conwidth - 640.0)*0.5;
+				sbar_y = vid_conheight - 47;
+				sbar_z = 0;
+
+				fade = 3 - 2 * (time - weapontime);
+
+				x = 1.0;
+				for(i = 0; i < 8; ++i)
+				{
+					if(stat_items & x)
+					{
+						Sbar_DrawWeapon(i+1, fade, (i + 2 == activeweapon));
+					}
+					x *= 2;
+				}
+				x *= 2*2*2*2;
+				if(stat_items & x)
+				{
+					Sbar_DrawWeapon(0, fade, (activeweapon == 1));
+				}
+
+				if (sb_lines > 24)
+					drawpic(sbar, "gfx/sbar", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+				else
+					drawpic(sbar, "gfx/sbar_minimal", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+
+				// armor
+				// (340-3*24) = 268
+				Sbar_DrawXNum('268 12', getstati(STAT_ARMOR), 3, 24, '0.6 0.7 0.8', 1, 0);
+
+				// health
+				// (154-3*24) = 82
+				x = getstati(STAT_HEALTH);
+				if(x > 100)
+					Sbar_DrawXNum('82 12', x, 3, 24, '1 1 1', 1, 0);
+				else if(x <= 25 && time - floor(time) > 0.5)
+					Sbar_DrawXNum('82 12', x, 3, 24, '0.7 0 0', 1, 0);
+				else
+					Sbar_DrawXNum('81 12', x, 3, 24, '0.6 0.7 0.8', 1, 0);
+
+				// AK dont draw ammo for the laser
+				x = getstati(STAT_AMMO);
+				if(activeweapon != 12)
+				{
+					// (519-3*24) = 447
+					if (stat_items & NEX_IT_SHELLS)
+						drawpic(sbar + '519 0', "gfx/sb_shells", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+					else if (stat_items & NEX_IT_BULLETS)
+						drawpic(sbar + '519 0', "gfx/sb_bullets", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+					else if (stat_items & NEX_IT_ROCKETS)
+						drawpic(sbar + '519 0', "gfx/sb_rocket", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+					else if (stat_items & NEX_IT_CELLS)
+						drawpic(sbar + '519 0', "gfx/sb_cells", '0 0 0', '1 1 1', sbar_alpha_fg, 0);
+					if(x > 10)
+						Sbar_DrawXNum('447 12', x, 3, 24, '0.6 0.7 0.8', 1, 0);
+					else
+						Sbar_DrawXNum('447 12', x, 3, 24, '0.7 0 0', 1, 0);
+				}
+
+				if (sb_lines > 24)
+					drawpic(sbar, "gfx/sbar_overlay", '0 0 0', '1 1 1', 1, DRAWFLAG_MODULATE);
+
+				if (sbar_x + 600 + 160 <= vid_conwidth)
+					Sbar_MiniDeathmatchOverlay (sbar + '600 0');
+
+				if (sbar_x > 0)
+					Sbar_Score(-16);
+				// Because:
+				//   Mini scoreboard uses 12*4 per other team, that is, 144
+				//   pixels when there are four teams...
+				//   Nexuiz by default sets vid_conwidth to 800... makes
+				//   sbar_x == 80...
+				//   so we need to shift it by 64 pixels to the right to fit
+				//   BUT: then it overlaps with the image that gets drawn
+				//   for viewsize 100! Therefore, just account for 3 teams,
+				//   that is, 96 pixels mini scoreboard size, needing 16 pixels
+				//   to the right!
+			}
+		
+		
+			if(gametype == GAME_KEYHUNT)
+			{
+				CSQC_kh_hud();
+			} else if(gametype == GAME_CTF)
+			{
+				CSQC_ctf_hud();
+			}
+		}
+	}
+}
+
+void CSQC_ctf_hud(void)
+{
+	// cvar("sbar_flagstatus_right") move the flag icons right
+	// cvar("sbar_flagstatus_pos") pixel position of the nexuiz flagstatus icons
+	float redflag, blueflag;
+	float stat_items;
+	vector pos;
+	
+	stat_items = getstati(STAT_ITEMS);
+	redflag = (stat_items/32768) & 3;
+	blueflag = (stat_items/131072) & 3;
+
+	/**
+	 * FTEQCC BUG!
+	 * For some reason now not even THAT works there...
+	 * Maybe the minus' precedence screws it up? The last one there, maybe I should use brackets
+	 **
+	 * pos_x = (cvar("sbar_flagstatus_right")) ? vid_conwidth - 10 - sbar_x - 64 : 10 - sbar_x;
+	 ** Should try those later:
+	 * pos_x = (cvar("sbar_flagstatus_right")) ? (vid_conwidth - 10 - sbar_x - 64) : (10 - sbar_x);
+	 * pos_x = ( (cvar("sbar_flagstatus_right")) ? vid_conwidth - 10 - 64 : 10 ) - sbar_x;
+	 */
+	
+	if(cvar("sbar_flagstatus_right"))
+		pos_x = vid_conwidth - 10 - sbar_x - 64;
+	else
+		pos_x = 10 - sbar_x;
+	
+	pos_z = 0;
+
+	if(sbar_hudselector == 1)
+		pos_y = (vid_conheight - sbar_y) - cvar("sbar_flagstatus_pos") - 64;
+	else
+		pos_y = -117;
+
+	pos += sbar;
+
+	switch(redflag)
+	{
+	case 1: drawpic(pos, "gfx/sb_flag_red_taken", '0 0 0', '1 1 1', 1, DRAWFLAG_NORMAL); break;
+	case 2: drawpic(pos, "gfx/sb_flag_red_lost", '0 0 0', '1 1 1', 1, DRAWFLAG_NORMAL); break;
+	case 3: drawpic(pos, "gfx/sb_flag_red_carrying", '0 0 0', '1 1 1', 1, DRAWFLAG_NORMAL); break;
+	}
+
+	pos_y -= 64;
+	
+	switch(blueflag)
+	{
+	case 1: drawpic(pos, "gfx/sb_flag_blue_taken", '0 0 0', '1 1 1', 1, 0); break;
+	case 2: drawpic(pos, "gfx/sb_flag_blue_lost", '0 0 0', '1 1 1', 1, 0); break;
+	case 3: drawpic(pos, "gfx/sb_flag_blue_carrying", '0 0 0', '1 1 1', 1, 0); break;
+	}
+}

Copied: branches/nexuiz-2.0/data/qcsrc/client/sortlist.qc (from rev 3776, trunk/data/qcsrc/client/sortlist.qc)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/sortlist.qc	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/client/sortlist.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,118 @@
+.float(entity,entity) sort_cmp;
+.entity sort_next, sort_prev;
+
+entity Sort_New(float(entity,entity) cmp)
+{
+	entity sort;
+	sort = spawn();
+	sort.sort_cmp = cmp;
+	sort.sort_next = NULL;
+	sort.chain = sort;
+	return sort;
+}
+
+void Sort_Remove(entity sort)
+{
+	entity next;
+	while(sort.sort_next)
+	{
+		next = sort.sort_next;
+		remove(sort);
+		sort = next;
+	}
+	remove(sort);
+}
+
+void Sort_Add(entity sort, entity ent)
+{
+	entity next, parent;
+	parent = sort;
+	next = sort.sort_next;
+	while(next)
+	{
+		if(!sort.sort_cmp(next, ent))
+			break;
+		parent = next;
+		next = next.sort_next;
+	}
+	ent.sort_next = next;
+	ent.sort_prev = parent;
+	parent.sort_next = ent;
+	if(next)
+		next.sort_prev = ent;
+}
+
+void Sort_Reset(entity sort)
+{
+	sort.chain = sort;
+}
+
+float Sort_HasNext(entity sort)
+{
+	return (sort.chain.sort_next != NULL);
+}
+
+entity Sort_Next(entity sort)
+{
+	entity next;
+	next = sort.chain.sort_next;
+	if(!next) {
+		next = spawn();
+		sort.chain.sort_next = next;
+		next.sort_prev = sort.chain;
+		next.sort_next = NULL;
+	}
+	sort.chain = next;
+	return next;
+}
+
+void Sort_Finish(entity sort)
+{
+	entity next;
+	next = sort.chain;
+	if(!next)
+		return;
+
+	while(next.sort_next)
+	{
+		sort = next.sort_next;
+		next.sort_next = sort.sort_next;
+		remove(sort);
+	}
+}
+
+entity Sort_Get(entity sort, float i)
+{
+	for(; sort.sort_next && i > 0; --i)
+		sort = sort.sort_next;
+	return sort;
+}
+
+#define SORT_SWAP(a,b) \
+	b.sort_prev = a.sort_prev;			\
+	a.sort_next = b.sort_next;			\
+	if(b.sort_next) b.sort_next.sort_prev = a;			\
+	a.sort_prev.sort_next = b;			\
+	a.sort_prev = b;				\
+	b.sort_next = a
+
+void Sort_Erase(entity ent)
+{
+	ent.sort_prev.sort_next = ent.sort_next;
+	if(ent.sort_next)
+		ent.sort_next.sort_prev = ent.sort_prev;
+	remove(ent);
+}
+
+void Sort_RemoveOld(entity sort)
+{
+	entity tmp;
+	for(tmp = sort.sort_next; tmp; tmp = tmp.sort_next)
+	{
+		if(tmp.frame < time)
+		{
+			tmp = tmp.sort_prev;
+			Sort_Erase(tmp.sort_next);
+		}
+	}
+}

Copied: branches/nexuiz-2.0/data/qcsrc/client/teamplay.qc (from rev 3776, trunk/data/qcsrc/client/teamplay.qc)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/client/teamplay.qc	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/client/teamplay.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,44 @@
+float numteams; // NOTE: This is changed in Sbar_SortFrags, so use it only AFTER that
+float teamplay;
+float myteam;
+
+float TeamByColor(float color)
+{
+	switch(color)
+	{
+	case COLOR_TEAM1: return 0;
+	case COLOR_TEAM2: return 1;
+	case COLOR_TEAM3: return 2;
+	case COLOR_TEAM4: return 3;
+	default: return 0;
+	}
+}
+
+float GetPlayerColor(float i)
+{
+	return stof(getplayerkey(i, "colors")) & 15;
+}
+
+vector GetTeamRGB(float color)
+{
+	switch(color)
+	{
+	default: return '1 1 1';
+	case COLOR_TEAM1: return '1 0 0'; // red
+	case COLOR_TEAM2: return '0 0 1'; // blue
+	case COLOR_TEAM3: return '1 1 0'; // yellow
+	case COLOR_TEAM4: return '1 0 1'; // pink
+	}
+}
+
+string GetTeamName(float color)
+{
+	switch(color)
+	{
+	default: return "Spectators";
+	case COLOR_TEAM1: return "Red Team";
+	case COLOR_TEAM2: return "Blue Team";
+	case COLOR_TEAM3: return "Yellow Team";
+	case COLOR_TEAM4: return "Pink Team";
+	}
+}

Modified: branches/nexuiz-2.0/data/qcsrc/common/campaign_file.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/campaign_file.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/common/campaign_file.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -35,7 +35,7 @@
 
 #define CAMPAIGN_GETARG0                  if(i >= entlen)
 #define CAMPAIGN_GETARG1 CAMPAIGN_GETARG0     error("syntax error in campaign file: line has not enough fields");
-#define CAMPAIGN_GETARG2 CAMPAIGN_GETARG1 a = argv(i++);
+#define CAMPAIGN_GETARG2 CAMPAIGN_GETARG1 a = argv(++i);
 #define CAMPAIGN_GETARG3 CAMPAIGN_GETARG2 if(a == ",")
 #define CAMPAIGN_GETARG4 CAMPAIGN_GETARG3     a = "";
 #define CAMPAIGN_GETARG5 CAMPAIGN_GETARG4 else
@@ -43,7 +43,7 @@
 // What you're seeing here is what people will do when your compiler supports
 // C-style macros but no line continuations.
 
-				i = 0;
+				i = -1; // starts at -1 so I don't need postincrement; that is, i points to BEFORE the current arg!
 				CAMPAIGN_GETARG; campaign_gametype[campaign_entries] = strzone(a);
 				CAMPAIGN_GETARG; campaign_mapname[campaign_entries] = strzone(a);
 				CAMPAIGN_GETARG; campaign_bots[campaign_entries] = stof(a);

Modified: branches/nexuiz-2.0/data/qcsrc/common/constants.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/constants.qh	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/common/constants.qh	2008-07-21 14:44:04 UTC (rev 3868)
@@ -1,10 +1,10 @@
+// COMMIT-TODO: Update if necessary before committing
+// Revision 1: additional statistics sent (flag caps, returns, deaths)
+// Revision 2: Mapvote preview pictures
+// Revision 3: optimized map vote protocol
+// Revision 4: CSQC config var system
+#define CSQC_REVISION 4
 
-const float STAT_CTF_STATE = 32;
-
-const float CTF_STATE_ATTACK = 1;
-const float CTF_STATE_DEFEND = 2;
-const float CTF_STATE_COMMANDER = 3;
-
 // probably put these in common/
 // so server/ and client/ can be synced better
 const float GAME_DEATHMATCH		= 1;
@@ -25,7 +25,7 @@
 
 const float ENT_CLIENT = 0;
 const float ENT_CLIENT_DEAD = 1;
-const float ENT_CLIENT_GPS = 2;
+const float ENT_CLIENT_ENTCS = 2;
 
 ///////////////////////////
 // key constants
@@ -152,3 +152,40 @@
 const float K_MOUSE14		=	527;
 const float K_MOUSE15		=	528;
 const float K_MOUSE16		=	529;
+
+///////////////////////////
+// cvar constants
+
+float CVAR_SAVE 	= 1;
+float CVAR_NOTIFY 	= 2;
+float CVAR_READONLY	= 4;
+
+///////////////////////////
+// csqc communication stuff
+
+const float ENTCS_MSG_END = 0;
+const float ENTCS_MSG_ONS_GPS = 1;
+const float ENTCS_MSG_ONS_REMOVE = 2;
+
+const float TE_CSQC_INIT = 100;
+const float TE_CSQC_PING = 101;
+const float TE_CSQC_CAPTURES = 102;
+const float TE_CSQC_RETURNS = 103;
+const float TE_CSQC_DEATHS = 104;
+const float TE_CSQC_PICTURE = 105;
+const float TE_CSQC_MAPVOTE = 106;
+const float TE_CSQC_CONFIG = 107;
+
+const float STAT_KH_KEYS = 32;
+const float STAT_CTF_STATE = 33;
+const float CTF_STATE_ATTACK = 1;
+const float CTF_STATE_DEFEND = 2;
+const float CTF_STATE_COMMANDER = 3;
+
+// moved that here so the client knows the max.
+// # of maps, I'll use arrays for them :P
+#define MAPVOTE_COUNT 10
+const float MAPVOTE_NET_INIT = 0;
+const float MAPVOTE_NET_UPDATE = 1;
+const float MAPVOTE_NET_PIC = 2;
+const float MAPVOTE_NET_OWNVOTE = 3;

Modified: branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/common/mapinfo.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -133,12 +133,12 @@
 		i = stof(s);
 
 	// now store all the stuff
-	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, MapInfo_Map_bspname);
-	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, MapInfo_Map_title);
-	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, MapInfo_Map_description);
-	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, MapInfo_Map_author);
-	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, ftos(MapInfo_Map_supportedGametypes));
-	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, i++, ftos(MapInfo_Map_supportedFeatures));
+	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData,   i, MapInfo_Map_bspname);
+	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, MapInfo_Map_title);
+	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, MapInfo_Map_description);
+	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, MapInfo_Map_author);
+	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, ftos(MapInfo_Map_supportedGametypes));
+	bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, ftos(MapInfo_Map_supportedFeatures));
 }
 
 float MapInfo_Cache_Retrieve(string map)
@@ -154,12 +154,12 @@
 	i = stof(s);
 
 	// now retrieve all the stuff
-	MapInfo_Map_bspname = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++);
-	MapInfo_Map_title = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++);
-	MapInfo_Map_description = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++);
-	MapInfo_Map_author = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++);
-	MapInfo_Map_supportedGametypes = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++));
-	MapInfo_Map_supportedFeatures = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i++));
+	MapInfo_Map_bspname = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, i);
+	MapInfo_Map_title = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i);
+	MapInfo_Map_description = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i);
+	MapInfo_Map_author = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i);
+	MapInfo_Map_supportedGametypes = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i));
+	MapInfo_Map_supportedFeatures = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i));
 	return 1;
 }
 
@@ -264,7 +264,7 @@
 		_MapInfo_filtered = buf_create();
 	}
 	MapInfo_count = 0;
-	for(i = 0, j = 0; i < _MapInfo_globcount; ++i)
+	for(i = 0, j = -1; i < _MapInfo_globcount; ++i)
 	{
 		if(MapInfo_Get_ByName(_MapInfo_GlobItem(i), 1, 0) == 2) // if we generated one... BAIL OUT and let the caller continue in the next frame.
 			if(pAbortOnGenerate)
@@ -274,9 +274,9 @@
 				return 0;
 			}
 		if(((MapInfo_Map_supportedGametypes & pGametype) != 0) && ((MapInfo_Map_supportedFeatures & pFeatures) == pFeatures))
-			bufstr_set(_MapInfo_filtered, j++, ftos(i));
+			bufstr_set(_MapInfo_filtered, ++j, ftos(i));
 	}
-	MapInfo_count = j;
+	MapInfo_count = j + 1;
 	MapInfo_ClearTemps();
 	return 1;
 }
@@ -476,6 +476,7 @@
 
 void _MapInfo_Map_ApplyGametype(string s, float pWantedType, float pThisType)
 {
+	string sa;
 	MapInfo_Map_supportedGametypes |= pThisType;
 	if(!(pThisType & pWantedType))
 		return;
@@ -488,15 +489,24 @@
 
 	if(pWantedType == MAPINFO_TYPE_TEAM_DEATHMATCH)
 	{
-		cvar_set("g_tdm_teams", car(s));
+		sa = car(s); if(sa == "") sa = "2";
+		cvar_set("g_tdm_teams", sa);
 		s = cdr(s);
 	}
 
 	if(pWantedType == MAPINFO_TYPE_KEYHUNT)
 	{
-		cvar_set("g_keyhunt_teams", car(s));
+		sa = car(s); if(sa == "") sa = "3";
+		cvar_set("g_keyhunt_teams", sa);
 		s = cdr(s);
 	}
+
+	if(pWantedType == MAPINFO_TYPE_CTF)
+	{
+		sa = car(s); if(sa == "") sa = "10";
+		cvar_set("capturelimit", sa);
+		s = cdr(s);
+	}
 }
 
 float MapInfo_Type_FromString(string t)
@@ -550,7 +560,7 @@
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH)      fputs(fh, "type dm 30 20\n");
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_TEAM_DEATHMATCH) fputs(fh, "type tdm 50 20 2\n");
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DOMINATION)      fputs(fh, "type dom 200 20\n");
-		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_CTF)             fputs(fh, "type ctf 300 20\n");
+		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_CTF)             fputs(fh, "type ctf 300 20 10\n");
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_RUNEMATCH)       fputs(fh, "type rune 200 20\n");
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_LMS)             fputs(fh, "type lms 9 20\n");
 		if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_ARENA)           fputs(fh, "type arena 10 20\n");

Modified: branches/nexuiz-2.0/data/qcsrc/common/util.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/util.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/common/util.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -16,6 +16,7 @@
 }
 
 #ifndef MENUQC
+#ifndef CSQC
 void wordwrap_buffer_sprint(string s)
 {
 	wordwrap_buffer = strcat(wordwrap_buffer, s);
@@ -36,6 +37,7 @@
 	return;
 }
 #endif
+#endif
 
 string unescape(string in)
 {
@@ -75,13 +77,13 @@
 
 	s = strzone(s);
 	lleft = l;
-	for (i = 0;i < strlen(s);i++)
+	for (i = 0;i < strlen(s);++i)
 	{
 		if (substring(s, i, 2) == "\\n")
 		{
 			callback("\n");
 			lleft = l;
-			i++;
+			++i;
 		}
 		else if (substring(s, i, 1) == "\n")
 		{
@@ -98,7 +100,7 @@
 		}
 		else
 		{
-			for (j = i+1;j < strlen(s);j++)
+			for (j = i+1;j < strlen(s);++j)
 				//    ^^ this skips over the first character of a word, which
 				//       is ALWAYS part of the word
 				//       this is safe since if i+1 == strlen(s), i will become

Modified: branches/nexuiz-2.0/data/qcsrc/common/util.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/common/util.qh	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/common/util.qh	2008-07-21 14:44:04 UTC (rev 3868)
@@ -13,8 +13,10 @@
 // NOTE: s IS allowed to be a tempstring
 string wordwrap(string s, float l);
 #ifndef MENUQC
+#ifndef CSQC
 void wordwrap_sprint(string s, float l);
 #endif
+#endif
 void wordwrap_cb(string s, float l, void(string) callback)
 
 float GameCommand_Generic(string cmd);

Modified: branches/nexuiz-2.0/data/qcsrc/menu/item.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/item.c	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/menu/item.c	2008-07-21 14:44:04 UTC (rev 3868)
@@ -14,6 +14,7 @@
 	METHOD(Item, showNotify, void(entity))
 	METHOD(Item, hideNotify, void(entity))
 	METHOD(Item, toString, string(entity))
+	METHOD(Item, destroy, void(entity))
 	ATTRIB(Item, focused, float, 0)
 	ATTRIB(Item, focusable, float, 0)
 	ATTRIB(Item, parent, entity, NULL)
@@ -21,6 +22,11 @@
 #endif
 
 #ifdef IMPLEMENTATION
+void destroyItem(entity me)
+{
+	// free memory associated with me
+}
+
 void relinquishFocusItem(entity me)
 {
 	if(me.parent)

Modified: branches/nexuiz-2.0/data/qcsrc/menu/menu.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/menu.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/menu/menu.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -389,7 +389,14 @@
 
 void() m_shutdown =
 {
+	entity e;
+
 	m_hide();
+	for(e = NULL; (e = nextent(e)) != NULL; )
+	{
+		if(e.destroy)
+			e.destroy(e);
+	}
 };
 
 void(string itemname) m_goto =

Modified: branches/nexuiz-2.0/data/qcsrc/menu/msys.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/msys.qh	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/menu/msys.qh	2008-07-21 14:44:04 UTC (rev 3868)
@@ -84,13 +84,6 @@
 
 
 ///////////////////////////
-// cvar constants
-
-float CVAR_SAVE 	= 1;
-float CVAR_NOTIFY 	= 2;
-float CVAR_READONLY	= 4;
-
-///////////////////////////
 // server list constants
 
 float SLIST_HOSTCACHEVIEWCOUNT  = 0;

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/credits.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/credits.c	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/credits.c	2008-07-21 14:44:04 UTC (rev 3868)
@@ -6,6 +6,7 @@
 	METHOD(NexuizCreditsList, drawListBoxItem, void(entity, float, vector, float))
 	METHOD(NexuizCreditsList, resizeNotify, void(entity, vector, vector, vector, vector))
 	METHOD(NexuizCreditsList, keyDown, float(entity, float, float, float))
+	METHOD(NexuizCreditsList, destroy, void(entity))
 
 	ATTRIB(NexuizCreditsList, realFontSize, vector, '0 0 0')
 	ATTRIB(NexuizCreditsList, realUpperMargin, float, 0)
@@ -30,6 +31,10 @@
 	me.bufferIndex = buf_load("nexuiz-credits.txt");
 	me.nItems = buf_getsize(me.bufferIndex);
 }
+void destroyNexuizCreditsList(entity me)
+{
+	buf_del(me.bufferIndex);
+}
 void drawNexuizCreditsList(entity me)
 {
 	float i;

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_create_mapinfo.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_create_mapinfo.c	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/dialog_multiplayer_create_mapinfo.c	2008-07-21 14:44:04 UTC (rev 3868)
@@ -131,9 +131,9 @@
 		{
 			me.TD(me, 1, w/4, e = makeNexuizTextLabel(0, "Assault"));
 				me.typeAssaultLabel = e;
-			me.TD(me, 1, w/4, e = makeNexuizTextLabel(0, "Onslaught"));
-				me.typeOnslaughtLabel = e;
 		}
+		me.TD(me, 1, w/4, e = makeNexuizTextLabel(0, "Onslaught"));
+			me.typeOnslaughtLabel = e;
 
 	me.gotoRC(me, me.rows - 2, 0);
 		me.TD(me, 1, me.columns, e = makeNexuizTextLabel(0.5, ""));

Modified: branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/menu/nexuiz/maplist.c	2008-07-21 14:44:04 UTC (rev 3868)
@@ -39,6 +39,8 @@
 
 	ATTRIB(NexuizMapList, typeToSearchString, string, string_null)
 	ATTRIB(NexuizMapList, typeToSearchTime, float, 0)
+
+	METHOD(NexuizMapList, destroy, void(entity))
 ENDCLASS(NexuizMapList)
 entity makeNexuizMapList();
 void MapList_All(entity btn, entity me);
@@ -47,6 +49,11 @@
 #endif
 
 #ifdef IMPLEMENTATION
+void destroyNexuizMapList(entity me)
+{
+	MapInfo_Shutdown();
+}
+
 entity makeNexuizMapList()
 {
 	entity me;

Modified: branches/nexuiz-2.0/data/qcsrc/server/assault.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/assault.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/assault.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -13,8 +13,8 @@
 -------- SPAWNFLAGS --------
 INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
 void spawnfunc_info_player_attacker() {
+	self.team = COLOR_TEAM1; // red, gets swapped every round
 	spawnfunc_info_player_deathmatch();
-	self.team = COLOR_TEAM1; // red, gets swapped every round
 }
 
 //=============================================================================
@@ -32,8 +32,8 @@
 -------- SPAWNFLAGS --------
 INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
 void spawnfunc_info_player_defender() {
+	self.team = COLOR_TEAM2; // blue, gets swapped every round
 	spawnfunc_info_player_deathmatch();
-	self.team = COLOR_TEAM2; // blue, gets swapped every round
 }
 
 // reset this objective. Used when spawning an objective
@@ -44,7 +44,7 @@
 
 void assault_objective_use() {
 	// activate objective
-	self.health = 100; 
+	self.health = 100;
 	self.nextthink = time + 0.1;
 }
 
@@ -57,7 +57,7 @@
 		//self.effects = EF_STARDUST;
 		self.nextthink = time + 0.1;
 	}
-	
+
 }
 //=============================================================================
 
@@ -102,7 +102,7 @@
 		if(objective.classname == "target_objective") {
 			found = 1;
 			if(objective.health < ASSAULT_VALUE_INACTIVE) { // targeted objective is active
-				if(self.cnt == 1 && self.max_health >= ASSAULT_VALUE_INACTIVE) { 
+				if(self.cnt == 1 && self.max_health >= ASSAULT_VALUE_INACTIVE) {
 					// decrease was fired already, but objective did recover (round reset)
 					self.cnt = 0;
 				}
@@ -131,11 +131,15 @@
 // decrease the health of targeted objectives
 void assault_objective_decrease_use() {
 
-	if(self.cnt > 0)
+	if(self.cnt > 0) {
+		// did already fire
 		return;
+	}
 
-	if(activator.team != assault_attacker_team)
+	if(activator.team != assault_attacker_team) {
+		// wrong team triggered decrease
 		return;
+	}
 
 	local entity ent;
 	ent = find(world, targetname, self.target);
@@ -199,7 +203,6 @@
 	self.model = "";
 	self.takedamage = DAMAGE_NO;
 	self.solid = SOLID_NOT;
-	activator = other;
 	SUB_UseTargets();
 }
 
@@ -233,7 +236,7 @@
 		self.health = 100;
 
 	self.max_health = self.health;
-	
+
 	self.cnt = 0; // not yet activated
 
 	self.classname = "func_assault_destructible";
@@ -280,7 +283,7 @@
 
 void target_assault_roundend_reset() {
 	self.cnt = self.cnt + 1; // up round counter
-	self.winning = 0; // up round 
+	self.winning = 0; // up round
 }
 
 void target_assault_roundend_use() {
@@ -299,8 +302,33 @@
 }
 
 void assault_roundstart_use() {
+
 	activator = self;
 	SUB_UseTargets();
+
+#ifdef TTURRETS_ENABLED
+    entity ent,oldself;
+
+	//(Re)spawn all turrets
+	oldself = self;
+	ent = find(world, classname, "turret_main");
+	while(ent) {
+	    // Swap turret teams
+        if(ent.team == COLOR_TEAM1)
+            ent.team = COLOR_TEAM2;
+        else
+            ent.team = COLOR_TEAM1;
+
+        self = ent;
+
+        // Dubbles as teamchange
+        ent.turret_spawnfunc();
+
+		ent = find(ent, classname, "turret_main");
+	}
+	self = oldself;
+#endif
+
 }
 
 void spawnfunc_target_assault_roundstart() {
@@ -314,7 +342,7 @@
 // trigger new round
 // reset objectives, toggle spawnpoints, reset triggers, ...
 void assault_new_round() {
-	
+
 	// up round counter
 	self.winning = self.winning + 1;
 	// set end time for next round
@@ -353,7 +381,7 @@
 		self = oldself;
 
 		ent = find(ent, classname, "info_player_deathmatch");
-	} 
+	}
 
 	// reset all objectives
 	ent = find(world, classname, "target_objective");
@@ -365,7 +393,7 @@
 		self = oldself;
 
 		ent = find(ent, classname, "target_objective");
-	} 
+	}
 
 	// reset round end triggers
 	ent = find(world, classname, "target_assault_roundend");
@@ -385,7 +413,7 @@
 	{
 		ent.cnt = 0;
 		ent = find(ent, classname, "target_objective_decrease");
-	} 
+	}
 
 	// reset all spawnfunc_func_assault_destructible
 	ent = find(world, classname, "func_assault_destructible");
@@ -393,6 +421,12 @@
 	{
 		oldself = self;
 		self = ent;
+
+        if(ent.team == COLOR_TEAM1)
+            ent.team = COLOR_TEAM2;
+        else
+            ent.team = COLOR_TEAM1;
+
 		assault_destructible_reset();
 		self = oldself;
 		ent = find(ent, classname, "func_assault_destructible");
@@ -416,6 +450,7 @@
 		PutClientInServer();
 		self = oldself;
 		ent = find(ent, classname, "player");
+
 	}
 
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_client.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -147,7 +147,7 @@
 
 	RandomSelection_Init();
 	for(spot = firstspot; spot; spot = spot.chain)
-		RandomSelection_Add(spot, 0, pow(bound(lower, spot.frags, upper), exponent) * spot.cnt);
+		RandomSelection_Add(spot, 0, pow(bound(lower, spot.frags, upper), exponent) * spot.cnt, spot.frags >= lower);
 
 	return RandomSelection_chosen_ent;
 }
@@ -348,6 +348,8 @@
 putting a client as observer in the server
 =============
 */
+void ctf_UpdateCaptures(float);
+void ctf_UpdateReturns(float);
 void PutObserverInServer (void)
 {
 	entity	spot;
@@ -372,6 +374,11 @@
 	WaypointSprite_PlayerDead();
 
 	DistributeFragsAmongTeam(self, self.team, 1);
+	if(g_ctf)
+	{
+		self.captures = 0;
+		ctf_UpdateCaptures(MSG_BROADCAST);
+	}
 
 	if(self.frags <= 0 && self.frags > -666 && g_lms && self.killcount != -666)
 		bprint ("^4", self.netname, "^4 has no more lives left\n");
@@ -396,6 +403,8 @@
 	self.death_time = 0;
 	self.dead_frame = 0;
 	self.deaths = 0;
+	self.captures = 0;
+	self.returns = 0;
 	self.alpha = 0;
 	self.scale = 0;
 	self.fade_time = 0;
@@ -448,6 +457,8 @@
 	}
 	else if(!g_lms)
 		self.frags = -666;
+	
+	net_UpdateDeaths(MSG_BROADCAST);
 }
 
 float RestrictSkin(float s)
@@ -520,6 +531,7 @@
 Called when a client spawns in the server
 =============
 */
+//void() ctf_playerchanged;
 void PutClientInServer (void)
 {
 	if(clienttype(self) == CLIENTTYPE_BOT)
@@ -655,6 +667,15 @@
 			if(!g_arena)
 			if(!g_lms)
 				self.frags = 0;
+			if(g_ctf)
+			{
+				self.captures = 0;
+				self.returns = 0;
+				ctf_UpdateCaptures(MSG_BROADCAST);
+				ctf_UpdateReturns(MSG_BROADCAST);
+			}
+			self.deaths = 0;
+			net_UpdateDeaths(MSG_BROADCAST);
 		}
 
 		self.cnt = WEP_LASER;
@@ -691,10 +712,31 @@
 	} else if(self.classname == "observer") {
 		PutObserverInServer ();
 	}
+
+	//if(g_ctf)
+	//	ctf_playerchanged();
 }
 
 /*
 =============
+SendCSQCInfo
+
+Send whatever CSQC needs NOW and cannot wait for SendServerInfo to happen...
+=============
+*/
+void SendCSQCInfo(void)
+{
+	if(clienttype(self) != CLIENTTYPE_REAL)
+		return;
+	msg_entity = self;
+	WriteByte(MSG_ONE, SVC_TEMPENTITY);
+	WriteByte(MSG_ONE, TE_CSQC_INIT);
+	WriteShort(MSG_ONE, CSQC_REVISION);
+	WriteByte(MSG_ONE, maxclients);
+}
+
+/*
+=============
 SetNewParms
 =============
 */
@@ -738,6 +780,15 @@
 
 void ClientKill_Now_TeamChange()
 {
+	if(g_ctf)
+	{
+		self.captures = 0;
+		self.returns = 0;
+		ctf_UpdateCaptures(MSG_BROADCAST);
+		ctf_UpdateReturns(MSG_BROADCAST);
+	}
+	self.deaths = 0;
+	net_UpdateDeaths(MSG_BROADCAST);
 	if(self.killindicator_teamchange == -1)
 	{
 		self.team = -1;
@@ -931,6 +982,7 @@
 Called when a client connects to the server
 =============
 */
+//void ctf_clientconnect();
 string ColoredTeamName(float t);
 void DecodeLevelParms (void);
 //void dom_player_join_team(entity pl);
@@ -1068,7 +1120,14 @@
 		self.classname = "observer";
 		Spawnqueue_Insert(self);
 	}
+	/*else if(g_ctf)
+	{
+		ctf_clientconnect();
+	}*/
 
+	if(entcs_start)
+		attach_entcs();
+
 	bot_relinkplayerlist();
 
 	self.spectatortime = time;
@@ -1079,6 +1138,21 @@
 
 	self.jointime = time;
 	self.allowedTimeouts = cvar("sv_timeout_number");
+
+	if(clienttype(self) == CLIENTTYPE_REAL)
+	{
+		sprint(self, strcat("nexuiz-csqc protocol ", ftos(CSQC_REVISION), "\n"));
+		SendCSQCInfo();
+		msg_entity = self;
+		ctf_UpdateCaptures(MSG_ONE);
+		ctf_UpdateReturns(MSG_ONE);
+		net_UpdateDeaths(MSG_ONE);
+		if(mapvote_initialized && !cvar("g_maplist_textonly"))
+		{
+			MapVote_SendData(MSG_ONE);
+			MapVote_UpdateData(MSG_ONE);
+		}
+	}
 }
 
 /*
@@ -1091,12 +1165,16 @@
 void(entity e) DropFlag;
 .entity chatbubbleentity;
 .entity teambubbleentity;
+//void() ctf_clientdisconnect;
 void ClientDisconnect (void)
 {
 	float save;
 
 	bot_clientdisconnect();
 
+	if(entcs_start)
+		detach_entcs();
+	
 	if(cvar("sv_eventlog"))
 		GameLogEcho(strcat(":part:", ftos(self.playerid)), FALSE);
 	bprint ("^4",self.netname);
@@ -1129,6 +1207,11 @@
 		DropFlag(self.flagcarried);
 
 	DistributeFragsAmongTeam(self, self.team, 1);
+	if(g_ctf)
+	{
+		self.captures = 0;
+		ctf_UpdateCaptures(MSG_BROADCAST);
+	}
 
 	save = self.flags;
 	self.flags = self.flags - (self.flags & FL_CLIENT);
@@ -1145,6 +1228,11 @@
 		Spawnqueue_Unmark(self);
 		Spawnqueue_Remove(self);
 	}
+	/*if(g_ctf)
+	{
+		ctf_clientdisconnect();
+	}
+	*/
 
 	if(self.netname_previous)
 		strunzone(self.netname_previous);
@@ -2130,5 +2218,21 @@
 		//do nothing
 	}
 
+	/*
+	float i;
+	for(i = 0; i < 1000; ++i)
+	{
+		vector end;
+		end = self.origin + '0 0 1024' + 512 * randomvec();
+		tracebox(self.origin, self.mins, self.maxs, end, MOVE_NORMAL, self);
+		if(trace_fraction < 1)
+		if(!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
+		{
+			print("I HIT SOLID: ", vtos(self.origin), " -> ", vtos(end), "\n");
+			break;
+		}
+	}
+	*/
+
 	Arena_Warmup();
 }

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_impulse.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -260,6 +260,109 @@
 					CopyBody(0);
 					self.lip += 1;
 				}
+				else if (imp == 143) // actually: impulse 911
+				{
+					vector start, end, enddown;
+					float i;
+					float m;
+					float good, evil, evilsurf;
+					float maxattempts;
+					vector org, delta;
+
+					good = DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP;
+					evil = DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER;
+					evilsurf = Q3SURFACEFLAG_SKY;
+
+					m = self.dphitcontentsmask;
+					self.dphitcontentsmask = good | evil;
+
+					org = world.mins;
+					delta = world.maxs - world.mins;
+
+					maxattempts = ((sv_cheats >= 2) ? 100000 : 100);
+
+					for(i = 0; i < maxattempts; ++i)
+					{
+						start_x = org_x + random() * delta_x;
+						start_y = org_y + random() * delta_y;
+						start_z = org_z + random() * delta_z;
+
+						// rule 1: start inside world bounds, and outside
+						// solid, and don't start from somewhere where you can
+						// fall down to evil
+						tracebox(start, self.mins, self.maxs, start - '0 0 1' * delta_z, MOVE_NORMAL, self);
+						if(trace_fraction >= 1)
+							continue;
+						if(trace_startsolid)
+							continue;
+						dprint("hit contents ", ftos(trace_dphitcontents), "\n");
+						if(trace_dphitcontents & evil)
+							continue;
+						if(trace_dphitq3surfaceflags & evilsurf)
+							continue;
+
+						// rule 2: if we are too high, lower the point
+						if(trace_fraction * delta_z > 1024)
+							start = trace_endpos + '0 0 1024';
+						enddown = trace_endpos;
+
+						// these can be traceLINES as we already verified the starting box
+						traceline(start, start + '1 0 0' * delta_x, MOVE_NORMAL, self);
+						if(trace_fraction >= 1)
+							continue;
+						traceline(start, start - '1 0 0' * delta_x, MOVE_NORMAL, self);
+						if(trace_fraction >= 1)
+							continue;
+						traceline(start, start + '0 1 0' * delta_y, MOVE_NORMAL, self);
+						if(trace_fraction >= 1)
+							continue;
+						traceline(start, start - '0 1 0' * delta_y, MOVE_NORMAL, self);
+						if(trace_fraction >= 1)
+							continue;
+						traceline(start, start + '0 0 1' * delta_z, MOVE_NORMAL, self);
+						if(trace_fraction >= 1)
+							continue;
+
+						end_x = org_x + random() * delta_x;
+						end_y = org_y + random() * delta_y;
+						end_z = org_z + random() * delta_z;
+						end = start + normalize(end - start) * vlen(delta);
+
+						// rule 3: start TO end must not be too short
+						tracebox(start, self.mins, self.maxs, end, MOVE_NORMAL, self);
+						if(trace_startsolid)
+							continue;
+						if(trace_fraction < 256 / vlen(delta))
+							continue;
+
+						// rule 4: don't want to look at sky
+						if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
+							continue;
+
+						// rule 5: we must not end up in trigger_hurt
+						if(tracebox_hits_trigger_hurt(start, self.mins, self.maxs, enddown))
+						{
+							dprint("trigger_hurt! ouch! and nothing else could find it!\n");
+							continue;
+						}
+
+						break;
+					}
+
+					if(i < maxattempts)
+					{
+						self.origin = start;
+						self.angles = vectoangles(end - start);
+						self.angles_x = -self.angles_x;
+						self.fixangle = TRUE;
+						self.velocity = '0 0 0';
+						dprint("Needed ", ftos(i + 1), " attempts\n");
+					}
+					else
+						sprint(self, "Emergency teleport could not find a good location, forget it!\n");
+
+					self.dphitcontentsmask = m;
+				}
 			}
 		}
 	}

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_physics.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -46,8 +46,9 @@
 	if (!(self.flags & FL_ONGROUND))
 		return;
 
-	if (!(self.flags & FL_JUMPRELEASED))
-		return;
+	if(!sv_pogostick)
+		if (!(self.flags & FL_JUMPRELEASED))
+			return;
 
 	if(g_runematch)
 	{
@@ -231,6 +232,14 @@
 
 	if(self.classname == "player")
 	{
+		if(sv_doublejump)
+		{
+			self.flags = self.flags - (self.flags & FL_ONGROUND);
+			tracebox(self.origin + '0 0 1', self.mins, self.maxs, self.origin - '0 0 2', MOVE_NORMAL, self);
+			if(trace_fraction < 1 && trace_plane_normal_z > 0.7)
+				self.flags = self.flags | FL_ONGROUND;
+		}
+
 		if (self.BUTTON_JUMP)
 			PlayerJump ();
 		else

Modified: branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/cl_player.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -351,6 +351,19 @@
 
 void ClientKill_Now_TeamChange();
 
+void net_UpdateDeaths(float msg_target)
+{
+	entity p;
+	WriteByte(msg_target, SVC_TEMPENTITY);
+	WriteByte(msg_target, TE_CSQC_DEATHS);
+	FOR_EACH_PLAYER(p)
+	{
+		WriteByte(msg_target, num_for_edict(p));
+		WriteByte(msg_target, p.deaths);
+	}
+	WriteByte(msg_target, 0);
+}
+
 void PlayerDamage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
 {
 	local float take, save, waves, sdelay;
@@ -447,6 +460,7 @@
 		defer_ClientKill_Now_TeamChange = FALSE;
 
 		self.deaths += 1;
+		net_UpdateDeaths(MSG_BROADCAST);
 
 		// get rid of kill indicator
 		if(self.killindicator)

Modified: branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/clientcommands.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -137,6 +137,33 @@
 	strunzone(msgstr);
 }
 
+entity GetPlayer(string name)
+{
+	float num;
+	entity e;
+	string ns;
+
+	if(substring(name, 0, 1) == "#") {
+		num = stof(substring(name, 1, 999));
+		if(num >= 1 && num <= maxclients) {
+			for((e = world); num > 0; --num, (e = nextent(e)))
+				;
+			//if(clienttype(e) == CLIENTTYPE_REAL)
+			if(e.classname == "player")
+				return e;
+		}
+	} else {
+		ns = strdecolorize(name);
+		FOR_EACH_REALPLAYER(e) {
+			if(!strcasecmp(strdecolorize(e.netname), ns)) {
+				return e;
+			}
+		}
+	}
+	return world;
+}
+
+//float ctf_clientcommand();
 void SV_ParseClientCommand(string s) {
 	local string cmd;
 	local float i;
@@ -145,6 +172,8 @@
 
 	if(GameCommand_Vote(s, self)) {
 		return;
+	} else if(GameCommand_MapVote(argv(0))) {
+		return;
 	} else if(argv(0) == "autoswitch") {
 		// be backwards compatible with older clients (enabled)
 		self.autoswitch = ("0" != argv(1));
@@ -304,6 +333,8 @@
 			evaluateResumeGame();
 		}
 	} else {
+		//if(ctf_clientcommand())
+		//	return;
 		cmd = argv(0);
 		/* checks not needed any more since DP has separated clientcommands and regular commands
 		if(cmd != "status")

Modified: branches/nexuiz-2.0/data/qcsrc/server/constants.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/constants.qh	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/constants.qh	2008-07-21 14:44:04 UTC (rev 3868)
@@ -151,7 +151,11 @@
 float	DEATH_SHOOTING_STAR			= 10012;
 float	DEATH_ROT				= 10013;
 float	DEATH_MIRRORDAMAGE		= 10014;
+float   DEATH_TURRET            = 10100;
 
+
+
+
 float	IT_LASER				= 4096;
 float	IT_SHOTGUN				= 1;
 float	IT_UZI					= 2;

Modified: branches/nexuiz-2.0/data/qcsrc/server/ctf.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/ctf.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -4,7 +4,6 @@
 
 .float next_take_time;			// the next time a player can pick up a flag (time + blah)
 								/// I used this, in part, to fix the looping score bug. - avirox
-
 //float FLAGSCORE_PICKUP        =  1;
 //float FLAGSCORE_RETURN        =  5; // returned by owner team
 //float FLAGSCORE_RETURNROGUE   = 10; // returned by rogue team
@@ -26,6 +25,8 @@
 
 float   flagcaptimerecord;
 .float  flagpickuptime;
+//.float  iscommander;
+//.float  ctf_state;
 
 void() FlagThink;
 void() FlagTouch;
@@ -128,6 +129,12 @@
 		return;
 	}
 	bprint(p.netname, "^7 lost the ", e.netname, "\n");
+
+	if(cvar("g_ctf_flagpenalty_drop"))
+		UpdateFrags(p, -cvar("g_ctf_flagpenalty_drop"));
+	
+	//if(e.enemy && e.enemy != e)
+	//UpdateFrags(e.enemy, cvar("g_ctf_flagscore_kill"));
 	WaypointSprite_DetachCarrier(p);
 	LogCTF("dropped", p.team, p.flagcarried);
 
@@ -223,6 +230,34 @@
 	}
 };
 
+void ctf_UpdateCaptures(float msg_target)
+{
+	entity p;
+	WriteByte(msg_target, SVC_TEMPENTITY);
+	WriteByte(msg_target, TE_CSQC_CAPTURES);
+	WriteByte(msg_target, cvar("g_ctf_win_mode"));
+	WriteByte(msg_target, caps_team1);
+	WriteByte(msg_target, caps_team2);
+	FOR_EACH_PLAYER(p)
+	{
+		WriteByte(msg_target, num_for_edict(p));
+		WriteByte(msg_target, p.captures);
+	}
+	WriteByte(msg_target, 0);
+}
+void ctf_UpdateReturns(float msg_target)
+{
+	entity p;
+	WriteByte(msg_target, SVC_TEMPENTITY);
+	WriteByte(msg_target, TE_CSQC_RETURNS);
+	FOR_EACH_PLAYER(p)
+	{
+		WriteByte(msg_target, num_for_edict(p));
+		WriteByte(msg_target, p.returns);
+	}
+	WriteByte(msg_target, 0);
+}
+
 void FlagTouch()
 {
 	if(gameover) return;
@@ -276,6 +311,16 @@
 			bprint(other.netname, "^7 captured the ", other.flagcarried.netname, " in ", s, ", failing to break ", strcat(h0, " record of ", s0, " seconds\n"));
 		}
 
+		other.captures += 1;
+		if(other.team == COLOR_TEAM1)
+			++caps_team1;
+		else if(other.team == COLOR_TEAM2)
+			++caps_team2;
+		else
+			print("Unknown team captured the flag!\n");
+		ctf_UpdateCaptures(MSG_BROADCAST);
+		// FIXME: When counting captures, should the score be updated?
+
 		LogCTF("capture", other.flagcarried.team, other);
 		// give credit to the individual player
 		UpdateFrags(other, cvar("g_ctf_flagscore_capture"));
@@ -337,10 +382,15 @@
 		{
 			// return flag
 			bprint(other.netname, "^7 returned the ", self.netname, "\n");
-			if (other.team == COLOR_TEAM1 || other.team == COLOR_TEAM2)
-				UpdateFrags(other, cvar("g_ctf_flagscore_return"));
-			else
-				UpdateFrags(other, cvar("g_ctf_flagscore_return_rogue"));
+			if(cvar("g_ctf_win_mode") == 2)
+			{
+				if (other.team == COLOR_TEAM1 || other.team == COLOR_TEAM2)
+					UpdateFrags(other, cvar("g_ctf_flagscore_return"));
+				else
+					UpdateFrags(other, cvar("g_ctf_flagscore_return_rogue"));
+			}
+			other.returns += 1;
+			ctf_UpdateReturns(MSG_BROADCAST);
 			LogCTF("return", self.team, other);
 			sound (self, CHAN_AUTO, self.noise1, 1, ATTN_NONE);
 			ReturnFlag(self);
@@ -662,6 +712,15 @@
 void ctf_init()
 {
 	local entity e;
+
+	caps_team1 = caps_team2 = 0;
+	registercvar("capturelimit", "8");
+	registercvar("g_ctf_win_mode", "0");
+	//registercvar("g_overtime", "1");
+	registercvar("g_ctf_flagscore_kill", "6");
+	registercvar("g_ctf_flagpenalty_drop", "0");
+	//addstat(STAT_CTF_CAPTURES, AS_INT, captures);
+	//addstat(STAT_CTF_STATE, AS_FLOAT_TRUNCATED, ctf_state);
 	e = spawn();
 	e.think = ctf_delayedinit;
 	e.nextthink = time + 0.1;
@@ -715,14 +774,153 @@
 		{
 			if(flag.team == COLOR_TEAM1)
 			{
-				if(redflags-- == 0) // happens exactly once
+				if(--redflags == -1) // happens exactly once (redflags is in 0..count-1, and will --'ed count times)
 					ctf_setstatus2(flag, IT_RED_FLAG_TAKEN);
 			}
 			else if(flag.team == COLOR_TEAM2)
 			{
-				if(blueflags-- == 0) // happens exactly once
+				if(--blueflags == -1) // happens exactly once
 					ctf_setstatus2(flag, IT_BLUE_FLAG_TAKEN);
 			}
 		}
 	}
 };
+/*
+entity(float cteam) ctf_team_has_commander =
+{
+	entity pl;
+	if(cteam != COLOR_TEAM1 || cteam != COLOR_TEAM2)
+		return world;
+	
+	FOR_EACH_REALPLAYER(pl) {
+		if(pl.team == cteam && pl.iscommander) {
+			return pl;
+		}
+	}
+	return world;
+};
+
+void(entity e, float st) ctf_setstate =
+{
+	e.ctf_state = st;
+	++e.version;
+};
+
+void(float cteam) ctf_new_commander =
+{
+	entity pl, plmax;
+	
+	plmax = world;
+	FOR_EACH_REALPLAYER(pl) {
+		if(pl.team == cteam) {
+			if(pl.iscommander) { // don't reassign if alreay there
+				return;
+			}
+			if(plmax == world || plmax.frags < pl.frags)
+				plmax = pl;
+		}
+	}
+	if(plmax == world) {
+		bprint(strcat(ColoredTeamName(cteam), " Team has no Commander!\n"));
+		return;
+	}
+
+	plmax.iscommander = TRUE;
+	ctf_setstate(plmax, 3);
+	sprint(plmax, "^3You're the commander now!\n");
+	centerprint(plmax, "^3You're the commander now!\n");
+};
+
+void() ctf_clientconnect =
+{
+	self.iscommander = FALSE;
+	
+	if(!self.team || self.classname != "player") {
+		ctf_setstate(self, -1);
+	} else
+		ctf_setstate(self, 0);
+
+	self.team_saved = self.team;
+	
+	if(self.team != 0 && self.classname == "player" && !ctf_team_has_commander(self.team)) {
+		ctf_new_commander(self.team);
+	}
+};
+
+void() ctf_playerchanged =
+{
+	if(!self.team || self.classname != "player") {
+		ctf_setstate(self, -1);
+	} else if(self.ctf_state < 0 && self.classname == "player") {
+		ctf_setstate(self, 0);
+	}
+
+	if(self.iscommander &&
+	   (self.classname != "player" || self.team != self.team_saved)
+		)
+	{
+		self.iscommander = FALSE;
+		if(self.classname == "player")
+			ctf_setstate(self, 0);
+		else
+			ctf_setstate(self, -1);
+		ctf_new_commander(self.team_saved);
+	}
+	
+	self.team_saved = self.team;
+	
+	ctf_new_commander(self.team);
+};
+
+void() ctf_clientdisconnect =
+{
+	if(self.iscommander)
+	{
+		ctf_new_commander(self.team);
+	}
+};
+
+entity GetPlayer(string);
+float() ctf_clientcommand =
+{
+	entity e;
+	if(argv(0) == "order") {
+		if(!g_ctf) {
+			sprint(self, "This command is not supported in this gamemode.\n");
+			return TRUE;
+		}
+		if(!self.iscommander) {
+			sprint(self, "^1You are not the commander!\n");
+			return TRUE;
+		}
+		if(argv(2) == "") {
+			sprint(self, "Usage: order #player status   - (playernumber as in status)\n");
+			return TRUE;
+		}
+		e = GetPlayer(argv(1));
+		if(e == world) {
+			sprint(self, "Invalid player.\nUsage: order #player status   - (playernumber as in status)\n");
+			return TRUE;
+		}
+		if(e.team != self.team) {
+			sprint(self, "^3You can only give orders to your own team!\n");
+			return TRUE;
+		}
+		if(argv(2) == "attack") {
+			sprint(self, strcat("Ordering ", e.netname, " to attack!\n"));
+			sprint(e, "^1Attack!\n");
+			centerprint(e, "^7You've been ordered to^9\n^1Attack!\n");
+			ctf_setstate(e, 1);
+		} else if(argv(2) == "defend") {
+			sprint(self, strcat("Ordering ", e.netname, " to defend!\n"));
+			sprint(e, "^Defend!\n");
+			centerprint(e, "^7You've been ordered to^9\n^2Defend!\n");
+			ctf_setstate(e, 2);
+		} else {
+			sprint(self, "^7Invalid command, use ^3attack^7, or ^3defend^7.\n");
+		}
+		return TRUE;
+	}
+	return FALSE;
+};
+*/

Modified: branches/nexuiz-2.0/data/qcsrc/server/defs.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/defs.qh	2008-07-21 14:44:04 UTC (rev 3868)
@@ -435,3 +435,13 @@
 .float parm_idlesince;
 float sv_maxidle;
 float sv_maxidle_spectatorsareidle;
+
+float sv_pogostick;
+float sv_doublejump;
+float tracebox_hits_trigger_hurt(vector start, vector mi, vector ma, vector end);
+
+float next_pingtime;
+
+.float captures;
+.float returns;
+float caps_team1, caps_team2;

Copied: branches/nexuiz-2.0/data/qcsrc/server/ent_cs.qc (from rev 3761, trunk/data/qcsrc/server/ent_cs.qc)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/ent_cs.qc	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/server/ent_cs.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,135 @@
+/**
+ * The point of these entities is to avoid the problems
+ * with clientprediction.
+ * If you add SendEntity to players, the engine will not
+ * do any prediction anymore, and you'd have to write the whole
+ * prediction code in CSQC, you want that? :P
+ * Data can depend on gamemode. For now, it serves as GPS entities
+ * in onslaught... YAY ;)
+ */
+
+// Beware: do not redefine those in other files
+// and NO, you cannot use ".version", which already exists (at least
+// it did when I added this) But you have to use .Version
+// Capital V
+
+.float(entity to) SendEntity;
+.float Version;
+
+entity entcs_start;
+
+void entcs_init()
+{
+	print("Initializing ClientSide information entities\n");
+	entcs_start = spawn();
+	entcs_start.solid = SOLID_NOT;
+	entcs_start.chain = world;
+};
+
+entity get_entcs_ent(float num)
+{
+	entity entcs;
+	entcs = spawn();
+	entcs.chain = entcs_start.chain;
+	entcs_start.chain = entcs;
+	return entcs;
+};
+
+void entcs_ons(entity to)
+{
+	if(to == self.owner || self.team != to.team ||
+	   self.owner.classname == "observer" || to.classname == "observer")
+	{
+		WriteByte(MSG_ENTITY, ENTCS_MSG_ONS_REMOVE);
+		return;
+	}
+	WriteByte(MSG_ENTITY, ENTCS_MSG_ONS_GPS);
+	WriteCoord(MSG_ENTITY, self.owner.origin_x);
+	WriteCoord(MSG_ENTITY, self.owner.origin_y);
+	WriteCoord(MSG_ENTITY, self.owner.angles_y);
+}
+
+void entcs_common_self()
+{
+	/*
+	entity pl;
+	if(self.pingtime < time)
+	{
+		self.pingtime = time + 9; // keep it 1 below the non-ons update intervall
+		// just to be safe... (blah)
+		WriteByte(MSG_ENTITY, ENTCS_MSG_PING);
+		FOR_EACH_REALCLIENT(pl)
+		{
+			WriteByte(MSG_ENTITY, num_for_edict(pl));
+			WriteShort(MSG_ENTITY, pl.ping);
+		}
+		WriteByte(MSG_ENTITY, 0);
+	}
+	*/
+}
+
+float entcs_send(entity to)
+{
+	WriteByte(MSG_ENTITY, ENT_CLIENT_ENTCS);
+	WriteByte(MSG_ENTITY, self.health); // serves as entitynumber
+	
+	if(to == self.owner)
+	{
+		entcs_common_self();
+	}
+	
+	if(g_onslaught)
+		entcs_ons(to);
+	
+	WriteByte(MSG_ENTITY, ENTCS_MSG_END);
+	return TRUE;
+};
+
+void entcs_think()
+{
+	self.team = self.owner.team;
+	self.Version++;
+	setorigin(self, self.owner.origin);
+	if(game == GAME_ONSLAUGHT)
+		self.nextthink = time + 0.1;
+	else
+		self.nextthink = time + 10; // update pings every 10 seconds
+};
+
+entity attach_entcs()
+{
+	local float num;
+	local entity ent;
+
+	print("Attaching ENTCS entity\n");
+
+	num = num_for_edict(self);
+	ent = get_entcs_ent(num);
+
+	ent.classname = "entcs_sender";
+	ent.health = num;
+	setorigin(ent, self.origin);
+	ent.owner = self;
+	ent.think = entcs_think;
+	ent.nextthink = time;
+	ent.effects = EF_NODEPTHTEST | EF_LOWPRECISION;
+	ent.model = "entcs_sender";
+	ent.modelindex = 1;
+	setsize(ent, '0 0 0', '0 0 0');
+		
+	ent.SendEntity = entcs_send;
+	return ent;
+};
+
+void detach_entcs()
+{
+	local float num;
+	local entity ent;
+	num = num_for_edict(self);
+	for(ent = entcs_start; ent.chain.owner != self && ent.chain != world; ent = ent.chain);
+	if(ent.chain != world && ent.chain.owner == self)
+	{
+		remove(ent.chain);
+		ent.chain = ent.chain.chain;
+	}
+};

Modified: branches/nexuiz-2.0/data/qcsrc/server/extensions.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/extensions.qh	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/extensions.qh	2008-07-21 14:44:04 UTC (rev 3868)
@@ -568,6 +568,31 @@
 //edict_num returns the entity corresponding to a given number, this works even for freed entities, but you should call wasfreed(ent) to see if is currently active.
 //wasfreed returns whether an entity slot is currently free (entities that have never spawned are free, entities that have had remove called on them are also free).
 
+//DP_QC_ENTITYDATA
+//idea: KrimZon
+//darkplaces implementation: KrimZon
+//builtin definitions:
+float() numentityfields = #496;
+string(float fieldnum) entityfieldname = #497;
+float(float fieldnum) entityfieldtype = #498;
+string(float fieldnum, entity ent) getentityfieldstring = #499;
+float(float fieldnum, entity ent, string s) putentityfieldstring = #500;
+//constants:
+//Returned by entityfieldtype
+float FIELD_STRING   = 1;
+float FIELD_FLOAT    = 2;
+float FIELD_VECTOR   = 3;
+float FIELD_ENTITY   = 4;
+float FIELD_FUNCTION = 6;
+//description:
+//Versatile functions intended for storing data from specific entities between level changes, but can be customized for some kind of partial savegame.
+//WARNING: .entity fields cannot be saved and restored between map loads as they will leave dangling pointers.
+//numentityfields returns the number of entity fields. NOT offsets. Vectors comprise 4 fields: v, v_x, v_y and v_z.
+//entityfieldname returns the name as a string, eg. "origin" or "classname" or whatever.
+//entityfieldtype returns a value that the constants represent, but the field may be of another type in more exotic progs.dat formats or compilers.
+//getentityfieldstring returns data as would be written to a savegame, eg... "0.05" (float), "0 0 1" (vector), or "Hello World!" (string). Function names can also be returned.
+//putentityfieldstring puts the data returned by getentityfieldstring back into the entity.
+
 //DP_QC_ETOS
 //idea: id Software
 //darkplaces implementation: id Software
@@ -868,6 +893,29 @@
 //description:
 //creates v_forward, v_right, and v_up vectors given a forward vector, similar to makevectors except it takes a forward direction vector instead of angles.
 
+//DP_QC_WHICHPACK
+//idea: div0
+//darkplaces implementation: div0
+//builtin definitions:
+string(string filename) whichpack = #503;
+//description:
+//returns the name of the pak/pk3/whatever containing the given file, in the same path space as FRIK_FILE functions use (that is, possibly with a path name prefix)
+
+//DP_QC_URI_ESCAPE
+//idea: div0
+//darkplaces implementation: div0
+//URI::Escape's functionality
+string(string in) uri_escape = #510;
+string(string in) uri_unescape = #511;
+
+//DP_SV_SPAWNFUNC_PREFIX
+//idea: div0
+//darkplaces implementation: div0
+//Make functions whose name start with spawnfunc_ take precedence as spawn function for loading entities.
+//Useful if you have a field ammo_shells (required in any Quake mod) but want to support spawn functions called ammo_shells (like in Q3A).
+//Optionally, you can declare a global "float require_spawnfunc_prefix;" which will require ANY spawn function to start with that prefix.
+
+
 //DP_QUAKE2_MODEL
 //idea: quake community
 //darkplaces implementation: LordHavoc
@@ -1215,6 +1263,21 @@
 //sets the time scale of the server, mainly intended for use in singleplayer by the player, however potentially useful for mods, so here's an extension for it.
 //range is 0 to infinite, recommended values to try are 0.1 (very slow, 10% speed), 1 (normal speed), 5 (500% speed).
 
+//DP_SV_WRITEPICTURE
+//idea: div0
+//darkplaces implementation: div0
+//builtin definitions:
+void(float to, string s, float sz) WritePicture = #501;
+//description:
+//writes a picture to the data stream so CSQC can read it using ReadPicture, which has the definition
+//  string(void) ReadPicture = #501;
+//The picture data is sent as at most sz bytes, by compressing to low quality
+//JPEG. The data being sent will be equivalent to:
+//  WriteString(to, s);
+//  WriteShort(to, imagesize);
+//  for(i = 0; i < imagesize; ++i)
+//    WriteByte(to, [the i-th byte of the compressed JPEG image]);
+
 //DP_SV_WRITEUNTERMINATEDSTRING
 //idea: FrikaC
 //darkplaces implementation: Sajt
@@ -1694,16 +1757,6 @@
 //It is not called on a crash or error.
 //void SV_Shutdown();
 
-//DP_QC_URI_ESCAPE
-//idea: div0
-//darkplaces implementation: div0
-//URI::Escape's functionality
-string(string in) uri_escape = #510;
-string(string in) uri_unescape = #511;
-
-//DP_SV_SPAWNFUNC_PREFIX
-//idea: div0
-//darkplaces implementation: div0
-//Make functions whose name start with spawnfunc_ take precedence as spawn function for loading entities.
-//Useful if you have a field ammo_shells (required in any Quake mod) but want to support spawn functions called ammo_shells (like in Q3A).
-//Optionally, you can declare a global "float require_spawnfunc_prefix;" which will require ANY spawn function to start with that prefix.
+//EXT_CSQC
+// #232 void(float index, float type, .void field) SV_AddStat (EXT_CSQC)
+void(float index, float type, ...) addstat = #232;

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_damage.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -169,7 +169,7 @@
 				else
 					centerprint(targ, "^1You grew too old without taking your medicine\n\n\n");
 			} else if (deathtype == DEATH_MIRRORDAMAGE) {
-				if(sv_gentle)				
+				if(sv_gentle)
 					centerprint(targ, "^1Don't go against team mates!\n\n\n");
 				else
 					centerprint(targ, "^1Don't shoot your team mates!\n\n\n");
@@ -187,7 +187,7 @@
 					bprint ("^1",s, "^1 didn't become friends with the Lord of Teamplay\n");
 				else
 					bprint ("^1",s, "^1 will be reinserted into the game due to his own actions\n");
-	
+
 				if(deathtype != DEATH_TEAMCHANGE)
 				{
 					LogDeath("suicide", deathtype, targ, targ);
@@ -218,7 +218,7 @@
 					bprint ("^1",s, "^1 didn't become friends with the Lord of Teamplay\n");
 				else if (deathtype != DEATH_TEAMCHANGE)
 					bprint ("^1",s, "^1 couldn't resist the urge to self-destruct\n");
-	
+
 				if(deathtype != DEATH_TEAMCHANGE)
 				{
 					LogDeath("suicide", deathtype, targ, targ);
@@ -235,7 +235,7 @@
 				if(sv_gentle) {
 					centerprint(attacker, "^1Moron! You went against a teammate!\n\n\n");
 					bprint ("^1", a, "^1 took action against a teammate\n");
-				} else {				
+				} else {
 					centerprint(attacker, "^1Moron! You fragged a teammate!\n\n\n");
 					bprint ("^1", a, "^1 mows down a teammate\n");
 				}
@@ -315,11 +315,15 @@
 						bprint ("^1",s, "^1 was conserved by ", a, "\n");
 					else if (deathtype == DEATH_HURTTRIGGER)
 						bprint ("^1",s, "^1 was thrown into a world of hurt by ", a, "\n");
+                    else if(deathtype == DEATH_TURRET)
+                        bprint ("^1",s, "^1 was pushed into the line of fire by ^1", a, "\n");
 					else
 						bprint ("^1",s, "^1 was fragged by ", a, "\n");
 				}
-
-				GiveFrags(attacker, targ, 1);
+				if(g_ctf && targ.flagcarried)
+					GiveFrags(attacker, targ, cvar("g_ctf_flagscore_kill"));
+				else
+					GiveFrags(attacker, targ, 1);
 				if (targ.killcount > 2) {
 					if(sv_gentle)
 						bprint ("^1",s,"'s ^1", ftos(targ.killcount), " scoring spree was ended by ", a, "\n");
@@ -430,6 +434,8 @@
 					bprint ("^1",s, "^1 discovered a swamp\n");
 				else
 					bprint ("^1",s, "^1 is now conserved for centuries to come\n");
+            else if(deathtype == DEATH_TURRET)
+                    bprint ("^1",s, "^1 was mowed down by a turret \n");
 			else
 				if(sv_gentle)
 					bprint ("^1",s, "^1 needs a restart\n");

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_decors.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_decors.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_decors.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -176,7 +176,7 @@
 entity newdecor()
 {
 	local entity e;
-	numdecors++;
+	++numdecors;
 	e = spawn();
 	e.classname = "decor";
 	return e;
@@ -184,7 +184,7 @@
 
 void removedecor(entity e)
 {
-	numdecors--;
+	--numdecors;
 	remove(e);
 };
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_triggers.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_triggers.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_triggers.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -378,6 +378,9 @@
 set dmg to damage amount
 defalt dmg = 5
 */
+.entity trigger_hurt_next;
+entity trigger_hurt_last;
+entity trigger_hurt_first;
 void spawnfunc_trigger_hurt()
 {
 	InitTrigger ();
@@ -386,8 +389,75 @@
 		self.dmg = 1000;
 	if (!self.message)
 		self.message = "was in the wrong place.";
+
+	if(!trigger_hurt_first)
+		trigger_hurt_first = self;
+	if(trigger_hurt_last)
+		trigger_hurt_last.trigger_hurt_next = self;
+	trigger_hurt_last = self;
 };
 
+float trace_hits_box_a0, trace_hits_box_a1;
+
+float trace_hits_box_1d(float end, float thmi, float thma)
+{
+	if(end == 0)
+	{
+		// just check if x is in range
+		if(0 < thmi)
+			return FALSE;
+		if(0 > thma)
+			return FALSE;
+	}
+	else
+	{
+		// do the trace with respect to x
+		// 0 -> end has to stay in thmi -> thma
+		trace_hits_box_a0 = max(trace_hits_box_a0, min(thmi / end, thma / end));
+		trace_hits_box_a1 = min(trace_hits_box_a1, max(thmi / end, thma / end));
+		if(trace_hits_box_a0 > trace_hits_box_a1)
+			return FALSE;
+	}
+	return TRUE;
+}
+
+float trace_hits_box(vector start, vector end, vector thmi, vector thma)
+{
+	end -= start;
+	thmi -= start;
+	thma -= start;
+	// now it is a trace from 0 to end
+
+	trace_hits_box_a0 = 0;
+	trace_hits_box_a1 = 1;
+
+	if(!trace_hits_box_1d(end_x, thmi_x, thma_x))
+		return FALSE;
+	if(!trace_hits_box_1d(end_y, thmi_y, thma_y))
+		return FALSE;
+	if(!trace_hits_box_1d(end_z, thmi_z, thma_z))
+		return FALSE;
+
+	return TRUE;
+}
+
+float tracebox_hits_box(vector start, vector mi, vector ma, vector end, vector thmi, vector thma)
+{
+	return trace_hits_box(start, end, thmi - ma, thma - mi);
+}
+
+float tracebox_hits_trigger_hurt(vector start, vector mi, vector ma, vector end)
+{
+	entity th;
+
+	for(th = trigger_hurt_first; th; th = th.trigger_hurt_next)
+		if(tracebox_hits_box(start, mi, ma, end, th.absmin, th.absmax))
+			return TRUE;
+
+	return FALSE;
+}
+
+
 void target_speaker_use() {sound(self, CHAN_VOICE, self.noise, 1, 1);}
 
 void spawnfunc_target_speaker()
@@ -619,12 +689,18 @@
 	self.nextthink = time;
 }
 
+// tZorks trigger impulse / gravity
+.float radius;
+.float falloff;
 .float strength;
 .float lastpushtime;
+
+// targeted (directional) mode
 void trigger_impulse_touch1()
 {
 	entity targ;
     float pushdeltatime;
+    float str;
 
 	// FIXME: Better checking for what to push and not.
 	if (other.classname != "player")
@@ -646,11 +722,17 @@
     targ = find(world, targetname, self.target);
     if(!targ)
     {
-        objerror("trigger_force without a (valif) .target!\n");
+        objerror("trigger_force without a (valid) .target!\n");
         remove(self);
         return;
     }
 
+    if(self.falloff == 1)
+        str = (str / self.radius) * self.strength;
+    else if(self.falloff == 2)
+        str = (1 - (str / self.radius)) * self.strength;
+    else
+        str = self.strength;
 
     pushdeltatime = time - other.lastpushtime;
     if (pushdeltatime > 0.15) pushdeltatime = 0;
@@ -660,8 +742,10 @@
     other.velocity = other.velocity + normalize(targ.origin - self.origin) * self.strength * pushdeltatime;
 }
 
+// Directionless (accelerator/decelerator) mode
 void trigger_impulse_touch2()
 {
+    float pushdeltatime;
 
 	// FIXME: Better checking for what to push and not.
 	if (other.classname != "player")
@@ -680,10 +764,59 @@
 	if (other.deadflag && other.classname == "player")
 		return;
 
-    other.velocity = other.velocity * self.strength;
+    pushdeltatime = time - other.lastpushtime;
+    if (pushdeltatime > 0.15) pushdeltatime = 0;
+    other.lastpushtime = time;
+    if(!pushdeltatime) return;
+
+    //if(self.strength > 1)
+        other.velocity = other.velocity * (self.strength * pushdeltatime);
+    //else
+    //    other.velocity = other.velocity - (other.velocity * self.strength * pushdeltatime);
 }
 
+// Spherical (gravity/repulsor) mode
+void trigger_impulse_touch3()
+{
+    float pushdeltatime;
+    float str;
 
+	// FIXME: Better checking for what to push and not.
+	if (other.classname != "player")
+	if (other.classname != "corpse")
+	if (other.classname != "body")
+	if (other.classname != "gib")
+	if (other.classname != "missile")
+	if (other.classname != "casing")
+	if (other.classname != "grenade")
+	if (other.classname != "plasma")
+	if (other.classname != "plasma_prim")
+	if (other.classname != "plasma_chain")
+	if (other.classname != "droppedweapon")
+		return;
+
+	if (other.deadflag && other.classname == "player")
+		return;
+
+    pushdeltatime = time - other.lastpushtime;
+    if (pushdeltatime > 0.15) pushdeltatime = 0;
+    other.lastpushtime = time;
+    if(!pushdeltatime) return;
+
+    setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius);
+
+	str = min(self.radius, vlen(self.origin - other.origin));
+
+    if(self.falloff == 1)
+        str = (1 - str / self.radius) * self.strength; // 1 in the inside
+    else if(self.falloff == 2)
+        str = (str / self.radius) * self.strength; // 0 in the inside
+    else
+        str = self.strength;
+
+    other.velocity = other.velocity + normalize(other.origin - self.origin) * str * pushdeltatime;
+}
+
 /*QUAKED spawnfunc_trigger_impulse (.5 .5 .5) ?
 -------- KEYS --------
 target : If this is set, this points to the spawnfunc_target_position to which the player will get pushed.
@@ -693,23 +826,37 @@
            when .target is set. If not, this is hoe mutch to slow down/accelerate
            someting cought inside this trigger. (1=no change, 0,5 half speed rougthly each tic, 2 = doubble)
 
+radius   : If set, act as a spherical device rather then a liniar one.
+
+falloff : 0 = none, 1 = liniar, 2 = inverted liniar
+
 -------- NOTES --------
 Use a brush textured with common/origin in the trigger entity to determine the origin of the force
-in directional push mode. For damper/accelerator mode this is no nessesary (and has no effect).
+in directional and sperical mode. For damper/accelerator mode this is not nessesary (and has no effect).
 */
 
 void spawnfunc_trigger_impulse()
 {
     InitTrigger ();
-    if(self.target)
+    if(self.radius)
     {
-        if(!self.strength) self.strength = 950;
-        self.touch = trigger_impulse_touch1;
+        if(!self.strength) self.strength = 2000;
+        setorigin(self, self.origin);
+        setsize(self, '-1 -1 -1' * self.radius,'1 1 1' * self.radius);
+        self.touch = trigger_impulse_touch3;
     }
     else
     {
-        if(!self.strength) self.strength = 0.9;
-        self.touch = trigger_impulse_touch2;
+        if(self.target)
+        {
+            if(!self.strength) self.strength = 950;
+            self.touch = trigger_impulse_touch1;
+        }
+        else
+        {
+            if(!self.strength) self.strength = 0.9;
+            self.touch = trigger_impulse_touch2;
+        }
     }
 }
 

Modified: branches/nexuiz-2.0/data/qcsrc/server/g_world.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/g_world.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -175,6 +175,15 @@
 		error("world already spawned - you may have EXACTLY ONE worldspawn!");
 	world_already_spawned = TRUE;
 
+	local entity head;
+	head = nextent(world);
+	maxclients = 0;
+	while(head)
+	{
+		++maxclients;
+		head = nextent(head);
+	}
+
 	if(GotoFirstMap())
 		return;
 
@@ -262,15 +271,6 @@
 	//if (g_domination)
 	//	dom_init();
 
-	local entity head;
-	head = nextent(world);
-	maxclients = 0;
-	while(head)
-	{
-		maxclients++;
-		head = nextent(head);
-	}
-
 	GameLogInit(); // prepare everything
 	if(cvar("sv_eventlog"))
 	{
@@ -357,6 +357,7 @@
 		fclose(fd);
 	}
 
+	next_pingtime = time + 5;
 	world_initialized = 1;
 }
 
@@ -1315,8 +1316,12 @@
 			}
 			else
 			{
+				local entity oldself;
+				oldself = self;
+				self = ent;
 				cvar_set("timelimit", ftos((2*time)/60));
 				assault_new_round();
+				self = oldself;
 			}
 		}
 	}
@@ -1485,7 +1490,7 @@
 			AddWinners(team, COLOR_TEAM4);
 	}
 
-	if(!g_runematch && !g_domination)
+	if(!g_runematch && !g_domination && !g_ctf)
 		if(tdm_max_score != tdm_old_score)
 		{
 			if(tdm_max_score == fraglimit - 1)
@@ -1559,6 +1564,23 @@
 	return WinningConditionBase_Teamplay(fraglimit);
 }
 
+float WinningCondition_CTF(float capturelimit, float fraglimit)
+{
+	if(cvar("g_ctf_win_mode") == 2)
+		return WinningCondition_MaxTeamSum(fraglimit);
+	
+	team1_score = caps_team1;
+	team2_score = caps_team2;
+	team3_score = team4_score = 0;
+
+	if(team1_score == team2_score && cvar("g_ctf_win_mode"))
+	{
+		return WinningCondition_MaxTeamSum(0);
+	}
+
+	return WinningConditionBase_Teamplay(capturelimit);
+}
+
 void print_to(entity e, string s)
 {
 	if(e)
@@ -1759,6 +1781,7 @@
 	local float status;
 	local float timelimit;
 	local float fraglimit;
+	local float capturelimit;
 
 	VoteThink();
 	MapVote_Think();
@@ -1787,6 +1810,7 @@
 
 	timelimit = cvar("timelimit") * 60;
 	fraglimit = cvar("fraglimit");
+	capturelimit = cvar("capturelimit");
 
 	if(checkrules_overtimeend)
 	{
@@ -1832,6 +1856,10 @@
 	{
 		status = WinningCondition_Onslaught();
 	}
+	else if(g_ctf)
+	{
+		status = WinningCondition_CTF(capturelimit, fraglimit);
+	}
 	else
 	{
 		if(teams_matter)
@@ -1868,38 +1896,13 @@
 		NextLevel();
 };
 
-float randsel_value;
-float randsel_priority;
-float randsel_count;
-void RandSel_Init()
-{
-	randsel_value = -1;
-	randsel_priority = -1;
-	randsel_count = -1;
-}
-void RandSel_Add(float priority, float value)
-{
-	if(priority > randsel_priority)
-	{
-		randsel_priority = priority;
-		randsel_value = value;
-		randsel_count = 1;
-	}
-	else if(priority == randsel_priority)
-	{
-		randsel_count += 1;
-		if(ceil(random() * randsel_count) == 1)
-			randsel_value = value;
-	}
-}
-
 float mapvote_nextthink;
 float mapvote_initialized;
 float mapvote_keeptwotime;
 float mapvote_timeout;
 string mapvote_message;
+string mapvote_screenshot_dir;
 
-#define MAPVOTE_COUNT 10
 float mapvote_count;
 float mapvote_count_real;
 string mapvote_maps[MAPVOTE_COUNT];
@@ -1912,6 +1915,7 @@
 float mapvote_run;
 float mapvote_detail;
 float mapvote_abstain;
+float mapvote_dirty;
 .float mapvote;
 
 void MapVote_ClearAllVotes()
@@ -1984,6 +1988,7 @@
 	mapvote_count += 1;
 }
 
+void MapVote_SendData(float target);
 void MapVote_Init()
 {
 	float i;
@@ -1999,7 +2004,7 @@
 		nmax = min(MAPVOTE_COUNT - 1, cvar("g_maplist_votable"));
 	else
 		nmax = min(MAPVOTE_COUNT, cvar("g_maplist_votable"));
-	smax = min(nmax, cvar("g_maplist_votable_suggestions"));
+	smax = min3(nmax, cvar("g_maplist_votable_suggestions"), mapvote_suggestion_ptr);
 
 	if(mapvote_suggestion_ptr)
 		for(i = 0; i < 100 && mapvote_count < smax; ++i)
@@ -2032,7 +2037,112 @@
 	if(mapvote_count_real < 3 || mapvote_keeptwotime <= time)
 		mapvote_keeptwotime = 0;
 	mapvote_message = "Choose a map and press its key!";
+
+	mapvote_screenshot_dir = cvar_string("g_maplist_votable_screenshot_dir");
+	if(mapvote_screenshot_dir == "")
+		mapvote_screenshot_dir = "maps";
+	mapvote_screenshot_dir = strzone(mapvote_screenshot_dir);
+
+	if(!cvar("g_maplist_textonly"))
+		MapVote_SendData(MSG_BROADCAST);
 }
+
+void MapVote_SendPicture(float id)
+{
+	msg_entity = self;
+	WriteByte(MSG_ONE, SVC_TEMPENTITY);
+	WriteByte(MSG_ONE, TE_CSQC_MAPVOTE);
+	WriteByte(MSG_ONE, MAPVOTE_NET_PIC);
+	WriteByte(MSG_ONE, id);
+	WritePicture(MSG_ONE, strcat(mapvote_screenshot_dir, "/", mapvote_maps[id]), 1024);
+}
+
+float GameCommand_MapVote(string cmd)
+{
+	if(!intermission_running)
+		return FALSE;
+	if(!cvar("g_maplist_textonly"))
+	{
+		if(cmd == "mv_getpic")
+		{
+			MapVote_SendPicture(stof(argv(1)));
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+float MapVote_GetMapMask()
+{
+	float mask, i, power;
+	mask = 0;
+	for(i = 0, power = 1; i < mapvote_count; ++i, power *= 2)
+		if(mapvote_maps[i] != "")
+			mask |= power;
+	return mask;
+}
+
+void MapVote_SendData(float targ)
+{
+	string mapfile;
+	float i, o;
+	WriteByte(targ, SVC_TEMPENTITY);
+	WriteByte(targ, TE_CSQC_CONFIG);
+	WriteString(targ, "mv_screenshot_dir");
+	WriteString(targ, mapvote_screenshot_dir);
+
+	WriteByte(targ, SVC_TEMPENTITY);
+	WriteByte(targ, TE_CSQC_MAPVOTE);
+	WriteByte(targ, MAPVOTE_NET_INIT);
+
+  	WriteByte(targ, mapvote_count);
+  	WriteByte(targ, mapvote_abstain);
+  	WriteByte(targ, mapvote_detail);
+ 	if(mapvote_count <= 8)
+ 		WriteByte(targ, MapVote_GetMapMask());
+ 	else
+ 		WriteShort(targ, MapVote_GetMapMask());
+ 	for(i = 0; i < mapvote_count; ++i)
+		if(mapvote_maps[i] != "")
+		{
+			WriteString(targ, mapvote_maps[i]);
+			mapfile = strcat(mapvote_screenshot_dir, "/", mapvote_maps[i]);
+			mapfile = whichpack(strcat(mapfile, ".tga"));
+			if(mapfile == "")
+				mapfile = whichpack(strcat(mapfile, ".jpg"));
+			if(mapfile == "")
+				mapfile = whichpack(strcat(mapfile, ".png"));
+			for(o = strstr(mapfile, "/", 0)+1; o > 0; o = strstr(mapfile, "/", 0)+1)
+				mapfile = substring(mapfile, o, 999);
+			WriteString(targ, mapfile);
+		}
+}
+
+void MapVote_UpdateData(float targ)
+{
+	float i;
+	WriteByte(targ, SVC_TEMPENTITY);
+	WriteByte(targ, TE_CSQC_MAPVOTE);
+	WriteByte(targ, MAPVOTE_NET_UPDATE);
+	if(mapvote_count <= 8)
+		WriteByte(targ, MapVote_GetMapMask());
+	else
+		WriteShort(targ, MapVote_GetMapMask());
+	if(mapvote_detail)
+		for(i = 0; i < mapvote_count; ++i)
+			if(mapvote_maps[i] != "")
+				WriteByte(targ, mapvote_votes[i]);
+}
+
+void MapVote_TellVote(float targ, float vote)
+{
+	WriteByte(targ, SVC_TEMPENTITY);
+	WriteByte(targ, TE_CSQC_MAPVOTE);
+	WriteByte(targ, MAPVOTE_NET_OWNVOTE);
+	WriteByte(targ, vote);
+}
+
 float MapVote_Finished(float mappos)
 {
 	string result;
@@ -2104,20 +2214,20 @@
 	if(mapvote_abstain)
 		mapvote_voters_real -= mapvote_votes[mapvote_count - 1];
 
-	RandSel_Init();
+	RandomSelection_Init();
 	for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
-		RandSel_Add(mapvote_votes[i], i);
-	firstPlace = randsel_value;
-	firstPlaceVotes = randsel_priority;
+		RandomSelection_Add(world, i, 1, mapvote_votes[i]);
+	firstPlace = RandomSelection_chosen_float;
+	firstPlaceVotes = RandomSelection_best_priority;
 	//dprint("First place: ", ftos(firstPlace), "\n");
 	//dprint("First place votes: ", ftos(firstPlaceVotes), "\n");
 
-	RandSel_Init();
+	RandomSelection_Init();
 	for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "")
 		if(i != firstPlace)
-			RandSel_Add(mapvote_votes[i], i);
-	secondPlace = randsel_value;
-	secondPlaceVotes = randsel_priority;
+			RandomSelection_Add(world, i, 1, mapvote_votes[i]);
+	secondPlace = RandomSelection_chosen_float;
+	secondPlaceVotes = RandomSelection_best_priority;
 	//dprint("Second place: ", ftos(secondPlace), "\n");
 	//dprint("Second place votes: ", ftos(secondPlaceVotes), "\n");
 
@@ -2131,6 +2241,7 @@
 		if(time > mapvote_keeptwotime || (mapvote_voters_real - firstPlaceVotes - secondPlaceVotes) < secondPlaceVotes)
 		{
 			float didntvote;
+			mapvote_dirty = TRUE;
 			mapvote_message = "Now decide between the TOP TWO!";
 			mapvote_keeptwotime = 0;
 			result = strcat(":vote:keeptwo:", mapvote_maps[firstPlace]);
@@ -2184,7 +2295,9 @@
 			other.impulse = 0;
 			if(clienttype(other) == CLIENTTYPE_REAL)
 			{
-				stuffcmd(other, "\nin_bind 7 1 \"impulse 1\"; in_bind 7 2 \"impulse 2\"; in_bind 7 3 \"impulse 3\"; in_bind 7 4 \"impulse 4\"; in_bind 7 5 \"impulse 5\"; in_bind 7 6 \"impulse 6\"; in_bind 7 7 \"impulse 7\"; in_bind 7 8 \"impulse 8\"; in_bind 7 9 \"impulse 9\"; in_bind 7 0 \"impulse 10\"; in_bind 7 KP_1 \"impulse 1\"; in_bind 7 KP_2 \"impulse 2\"; in_bind 7 KP_3 \"impulse 3\"; in_bind 7 KP_4 \"impulse 4\"; in_bind 7 KP_5 \"impulse 5\"; in_bind 7 KP_6 \"impulse 6\"; in_bind 7 KP_7 \"impulse 7\"; in_bind 7 KP_8 \"impulse 8\"; in_bind 7 KP_9 \"impulse 9\"; in_bind 7 KP_0 \"impulse 10\"; in_bindmap 7 0\n");
+				if(cvar("g_maplist_textonly"))
+					stuffcmd(other, "\nin_bind 7 1 \"impulse 1\"; in_bind 7 2 \"impulse 2\"; in_bind 7 3 \"impulse 3\"; in_bind 7 4 \"impulse 4\"; in_bind 7 5 \"impulse 5\"; in_bind 7 6 \"impulse 6\"; in_bind 7 7 \"impulse 7\"; in_bind 7 8 \"impulse 8\"; in_bind 7 9 \"impulse 9\"; in_bind 7 0 \"impulse 10\"; in_bind 7 KP_1 \"impulse 1\"; in_bind 7 KP_2 \"impulse 2\"; in_bind 7 KP_3 \"impulse 3\"; in_bind 7 KP_4 \"impulse 4\"; in_bind 7 KP_5 \"impulse 5\"; in_bind 7 KP_6 \"impulse 6\"; in_bind 7 KP_7 \"impulse 7\"; in_bind 7 KP_8 \"impulse 8\"; in_bind 7 KP_9 \"impulse 9\"; in_bind 7 KP_0 \"impulse 10\"; in_bindmap 7 0\n");
+
 				msg_entity = other;
 				WriteByte(MSG_ONE, SVC_FINALE);
 				WriteString(MSG_ONE, "");
@@ -2201,7 +2314,14 @@
 		// use impulses as new vote
 		if(other.impulse >= 1 && other.impulse <= mapvote_count)
 			if(mapvote_maps[other.impulse - 1] != "")
+			{
 				other.mapvote = other.impulse;
+				if(mapvote_detail)
+					mapvote_dirty = TRUE;
+
+				msg_entity = other;
+				MapVote_TellVote(MSG_ONE, other.mapvote);
+			}
 		other.impulse = 0;
 
 		if(other.mapvote)
@@ -2210,51 +2330,61 @@
 
 	MapVote_CheckRules_1(); // just count
 
-	FOR_EACH_REALCLIENT(other)
+	if(!cvar("g_maplist_textonly"))
+	if(mapvote_dirty) // 1 if "keeptwo" or "impulse" happened before
 	{
-		// display voting screen
-		msgstr = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
-		msgstr = substring(msgstr, 0, strlen(msgstr) - mapvote_count);
-		if(mapvote_abstain)
-			msgstr = substring(msgstr, 1, strlen(msgstr) - 1);
-		msgstr = strcat(msgstr, mapvote_message);
-		msgstr = strcat(msgstr, "\n\n");
-		for(i = 0; i < mapvote_count; ++i)
-			if(mapvote_maps[i] == "")
-				msgstr = strcat(msgstr, "\n");
-			else
-			{
-				tmp = mapvote_maps[i];
-				tmp = strpad(mapvote_maxlen, tmp);
-				tmp = strcat(ftos(mod(i + 1, 10)), ": ", tmp);
- 				if(mapvote_detail)
- 				{
- 					tmp = strcat(tmp, " ^2(", ftos(mapvote_votes[i]), " vote");
- 					if(mapvote_votes[i] != 1)
- 						tmp = strcat(tmp, "s");
- 					tmp = strcat(tmp, ")");
- 					tmp = strpad(mapvote_maxlen + 15, tmp);
- 				}
-				if(mapvote_abstain)
-					if(i == mapvote_count - 1)
-						msgstr = strcat(msgstr, "\n");
-				if(other.mapvote == i + 1)
-					msgstr = strcat(msgstr, "^3> ", tmp, "\n");
+		MapVote_UpdateData(MSG_BROADCAST);
+		mapvote_dirty = FALSE;
+	}
+
+	if(cvar("g_maplist_textonly"))
+	{
+		FOR_EACH_REALCLIENT(other)
+		{
+			// display voting screen
+			msgstr = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
+			msgstr = substring(msgstr, 0, strlen(msgstr) - mapvote_count);
+			if(mapvote_abstain)
+				msgstr = substring(msgstr, 1, strlen(msgstr) - 1);
+			msgstr = strcat(msgstr, mapvote_message);
+			msgstr = strcat(msgstr, "\n\n");
+			for(i = 0; i < mapvote_count; ++i)
+				if(mapvote_maps[i] == "")
+					msgstr = strcat(msgstr, "\n");
 				else
-					msgstr = strcat(msgstr, "^7  ", tmp, "\n");
-			}
+				{
+					tmp = mapvote_maps[i];
+					tmp = strpad(mapvote_maxlen, tmp);
+					tmp = strcat(ftos(mod(i + 1, 10)), ": ", tmp);
+					if(mapvote_detail)
+					{
+						tmp = strcat(tmp, " ^2(", ftos(mapvote_votes[i]), " vote");
+						if(mapvote_votes[i] != 1)
+							tmp = strcat(tmp, "s");
+						tmp = strcat(tmp, ")");
+						tmp = strpad(mapvote_maxlen + 15, tmp);
+					}
+					if(mapvote_abstain)
+						if(i == mapvote_count - 1)
+							msgstr = strcat(msgstr, "\n");
+					if(other.mapvote == i + 1)
+						msgstr = strcat(msgstr, "^3> ", tmp, "\n");
+					else
+						msgstr = strcat(msgstr, "^7  ", tmp, "\n");
+				}
 
- 		msgstr = strcat(msgstr, "\n\n^2", ftos(totalvotes), " vote");
- 		if(totalvotes != 1)
- 			msgstr = strcat(msgstr, "s");
- 		msgstr = strcat(msgstr, " cast");
-		i = ceil(mapvote_timeout - time);
- 		msgstr = strcat(msgstr, "\n", ftos(i), " second");
-		if(i != 1)
-			msgstr = strcat(msgstr, "s");
-		msgstr = strcat(msgstr, " left");
+			msgstr = strcat(msgstr, "\n\n^2", ftos(totalvotes), " vote");
+			if(totalvotes != 1)
+				msgstr = strcat(msgstr, "s");
+			msgstr = strcat(msgstr, " cast");
+			i = ceil(mapvote_timeout - time);
+			msgstr = strcat(msgstr, "\n", ftos(i), " second");
+			if(i != 1)
+				msgstr = strcat(msgstr, "s");
+			msgstr = strcat(msgstr, " left");
 
-		centerprint_atprio(other, CENTERPRIO_MAPVOTE, msgstr);
+			centerprint_atprio(other, CENTERPRIO_MAPVOTE, msgstr);
+		}
 	}
 }
 void MapVote_Start()

Modified: branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -23,6 +23,19 @@
 
 string kh_Controller_Waitmsg;
 
+// kh_state
+//     bits 0-7: player's key status
+//     bits 8-15: general key status
+.float kh_state;
+.float siren_time;  //  time delay the siren
+//.float stuff_time;  //  time delay to stuffcmd a cvar
+
+float test[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+//test[0] = status of dropped keys, test[1 - 16] = player #
+//replace 17 with cvar("maxplayers") or similar !!!!!!!!!
+//for(i = 0; i < maxplayers; ++i)
+//	test[i] = "0";
+
 float kh_Team_ByID(float t)
 {
 	if(t == 0) return COLOR_TEAM1;
@@ -47,11 +60,12 @@
 string kh_sound_destroy = "sound/kh/destroy.wav";
 string kh_sound_drop = "sound/kh/drop.wav";
 string kh_sound_collect = "sound/kh/collect.wav";
+string kh_sound_alarm = "sound/kh/alarm.wav";  // the new siren/alarm
 
 float kh_sprite_dropped, kh_sprite_finish, kh_sprite_red, kh_sprite_blue, kh_sprite_pink, kh_sprite_yellow, kh_sprite_friend;
 float kh_key_dropped, kh_key_carried;
 
-float kh_GetCarrierSprite(float t, float e)
+float kh_GetCarrierSprite(float t, float e)  // runs all the time
 {
 	if(t == e)           return kh_sprite_friend;
 	if(t == COLOR_TEAM1) return kh_sprite_red;
@@ -61,7 +75,7 @@
 	return 0;
 }
 
-void kh_Controller_SetThink(float t, string msg, kh_Think_t func)
+void kh_Controller_SetThink(float t, string msg, kh_Think_t func)  // runs occasionaly
 {
 	kh_Controller_Thinkfunc = func;
 	kh_controller.cnt = t;
@@ -75,7 +89,7 @@
 		kh_controller.nextthink = time; // force
 }
 
-void kh_Controller_Think()
+void kh_Controller_Think()  // called a lot
 {
 	entity e;
 	if(intermission_running)
@@ -108,7 +122,7 @@
 
 // frags f: take from cvar * f
 // frags 0: no frags
-void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner)
+void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner)  // update the score when a key is captured
 {
 	string s;
 	if(intermission_running)
@@ -117,7 +131,7 @@
 		UpdateFrags(player, frags_player);
 	if(key && key.owner && frags_owner)
 		UpdateFrags(key.owner, frags_owner);
-	if(!cvar("sv_eventlog"))
+	if(!cvar("sv_eventlog"))  //output extra info to the console or text file
 		return;
 	s = strcat(":keyhunt:", what, ":", ftos(player.playerid));
 	s = strcat(s, ":", ftos(frags_player));
@@ -131,7 +145,7 @@
 	GameLogEcho(s, FALSE);
 }
 
-vector kh_AttachedOrigin(entity e)
+vector kh_AttachedOrigin(entity e)  // runs when a team captures the flag, it can run 2 or 3 times.
 {
 	if(e.tag_entity)
 	{
@@ -142,7 +156,7 @@
 		return e.origin;
 }
 
-void kh_Key_Attach(entity key)
+void kh_Key_Attach(entity key)  // runs when a player picks up a key and several times when a key is assigned to a player at the start of a round
 {
 #ifdef KH_PLAYER_USE_ATTACHMENT
 	entity first;
@@ -172,7 +186,7 @@
 	}
 #else
 	setattachment(key, key.owner, "");
-	setorigin(key, '0 0 1' * KH_KEY_ZSHIFT); // fixing x, y in think
+	setorigin(key, '0 0 1' * KH_KEY_ZSHIFT);  // fixing x, y in think
 	key.angles_y -= key.owner.angles_y;
 #endif
 	key.flags = 0;
@@ -184,8 +198,25 @@
 	key.modelindex = kh_key_carried;
 }
 
-void kh_Key_Detach(entity key)
+void kh_Key_Detach(entity key) // runs every time a key is dropped or lost. Runs several times times when all the keys are captured
 {
+	float i;
+	i = test[key.owner.playerid];
+		if(key.netname == "^1red key")
+			i -= 1;
+		if(key.netname == "^4blue key")
+			i -= 2;
+		if(key.netname == "^3yellow key")
+			i -= 4;
+		if(key.netname == "^6pink key")
+			i -= 8;
+	test[key.owner.playerid] = i;
+
+	kh_show_temp();
+	if(key.owner)
+		key.owner.kh_state = (key.owner.kh_state | 255) - 255 + test[key.owner.playerid];
+	//key.owner.kh_state += test[key.owner.playerid];
+
 #ifdef KH_PLAYER_USE_ATTACHMENT
 	entity first;
 	first = key.owner.kh_next;
@@ -224,7 +255,7 @@
 	key.kh_previous_owner = key.owner;
 }
 
-void kh_Key_AssignTo(entity key, entity player)
+void kh_Key_AssignTo(entity key, entity player)  // runs every time a key is picked up or assigned. Runs prior to kh_key_attach
 {
 	if(key.owner == player)
 		return;
@@ -258,6 +289,18 @@
 		if(key.kh_next)
 			key.kh_next.kh_prev = key;
 
+		float i;
+		i = test[key.owner.playerid];
+			if(key.netname == "^1red key")
+				i += 1;
+			if(key.netname == "^4blue key")
+				i += 2;
+			if(key.netname == "^3yellow key")
+				i += 4;
+			if(key.netname == "^6pink key")
+				i += 8;
+		test[key.owner.playerid] = i;
+
 		kh_Key_Attach(key);
 
 		if(key.kh_next == world)
@@ -268,7 +311,12 @@
 			player.waypointsprite_attachedforcarrier.team = player.team;
 		}
 	}
-
+	
+	// moved that here, also update if there's no player
+	kh_show_temp();
+	if(key.owner)
+		key.owner.kh_state = (key.owner.kh_state | 255) - 255 + test[key.owner.playerid];
+		
 	key.pusher = world;
 }
 
@@ -283,7 +331,7 @@
 			self.team = attacker.team;
 }
 
-void kh_Key_Spawn(entity initial_owner, float angle)
+void kh_Key_Spawn(entity initial_owner, float angle)  // runs every time a new flag is created, ie after all the keys have been collected
 {
 	entity key;
 	key = spawn();
@@ -326,7 +374,7 @@
 	key.kh_worldkeynext = kh_worldkeylist;
 	kh_worldkeylist = key;
 
-	sprint(initial_owner, strcat("You got the ^2", key.netname, "\n"));
+	centerprint(initial_owner, strcat("You are starting with the ", key.netname, "\n"));  // message to player at start of round
 
 	WaypointSprite_Spawn("", 0, 0, key, '0 0 1' * KH_KEY_WP_ZSHIFT, world, key.team, key, waypointsprite_attachedforcarrier, FALSE);
 	key.waypointsprite_attachedforcarrier.waypointsprite_for_player = kh_Key_waypointsprite_for_player;
@@ -334,7 +382,7 @@
 	kh_Key_AssignTo(key, initial_owner);
 }
 
-void kh_Key_Remove(entity key)
+void kh_Key_Remove(entity key)  // runs after when all the keys have been collected or when a key has been dropped for more than X seconds
 {
 	entity o;
 	o = key.owner;
@@ -365,7 +413,7 @@
 }
 
 // -1 when no team completely owns all keys yet
-float kh_Key_AllOwnedByWhichTeam()
+float kh_Key_AllOwnedByWhichTeam()  // constantly called. check to see if all the keys are owned by the same team
 {
 	entity key;
 	float teem;
@@ -383,16 +431,17 @@
 	return teem;
 }
 
-void kh_Key_Collect(entity key, entity player)
+void kh_Key_Collect(entity key, entity player)  //a player picks up a dropped key
 {
 	sound(player, CHAN_AUTO, kh_sound_collect, 1, ATTN_NORM);
 
 	if(key.kh_dropperteam != player.team)
 		kh_Scores_Event(player, key, "collect", cvar("g_balance_keyhunt_score_collect"), 0);
 	key.kh_dropperteam = 0;
-	bprint(player.netname, "^7 collected the ", key.netname, "\n");
-	kh_Key_AssignTo(key, player);
+	bprint(player.netname, "^7 picked up the ", key.netname, "\n");
 
+	kh_Key_AssignTo(key, player); // this also updates .kh_state
+
 	if(kh_Key_AllOwnedByWhichTeam() != -1)
 	{
 		kh_interferemsg_time = time + 0.2;
@@ -400,7 +449,7 @@
 	}
 }
 
-void kh_Key_DropAll(entity player, float suicide)
+void kh_Key_DropAll(entity player, float suicide) // runs whenever a player dies
 {
 	entity key;
 	entity mypusher;
@@ -413,7 +462,7 @@
 		while((key = player.kh_next))
 		{
 			kh_Scores_Event(player, key, "losekey", 0, 0);
-			bprint(player.netname, "^7 lost the ", key.netname, "\n");
+			bprint(player.netname, "^7 died and lost the ", key.netname, "\n");
 			kh_Key_AssignTo(key, world);
 			makevectors('-1 0 0' * (45 + 45 * random()) + '0 360 0' * random());
 			key.velocity = W_CalculateProjectileVelocity(player.velocity, cvar("g_balance_keyhunt_dropvelocity") * v_forward);
@@ -426,7 +475,7 @@
 	}
 }
 
-void kh_Key_Touch()
+void kh_Key_Touch()  // runs many, many times when a key has been dropped and can be picked up
 {
 	if(intermission_running)
 		return;
@@ -439,17 +488,27 @@
 		return;
 	if(other == self.enemy)
 		if(time < self.kh_droptime + cvar("g_balance_keyhunt_delay_collect"))
-			return; // you just dropped it!
+			return;  // you just dropped it!
 	kh_Key_Collect(self, other);
 }
 
-void kh_Key_Think()
+void kh_Key_Think()  // runs all the time
 {
 	entity head;
+	//entity player;  // needed by FOR_EACH_PLAYER
 
 	if(intermission_running)
 		return;
+	/*
+	if(time > self.stuff_time)
+	{
+		FOR_EACH_PLAYER(player)
+			player.kh_state = test[0]*256 + (player.kh_state&255);
 
+		self.stuff_time = time + 1;  // repeat in 1 second
+	}
+	*/
+
 #ifdef KH_KEY_ATTACHMENT_DEBUG
 	if(self.kh_prev == self.owner)
 	{
@@ -472,7 +531,7 @@
 		if(time >= self.owner.kh_droptime + cvar("g_balance_keyhunt_delay_drop"))
 		{
 			self.owner.kh_droptime = time;
-			self.kh_droptime = time; // prevent collecting this one for some time
+			self.kh_droptime = time;  // prevent collecting this one for some time
 			self.enemy = self.owner;
 			self.pusher = world;
 			kh_Scores_Event(self.owner, self, "dropkey", 0, 0);
@@ -494,6 +553,12 @@
 	if(self.owner)
 	if(kh_Key_AllOwnedByWhichTeam() != -1)
 	{
+		if(self.siren_time < time)
+		{
+			sound(world, CHAN_AUTO, kh_sound_alarm, 1, ATTN_NORM);  // play a simple alarm
+			self.siren_time = time + 2.5;  // repeat every 2.5 seconds
+		}
+
 		entity key;
 		vector p;
 		p = self.owner.origin;
@@ -522,7 +587,7 @@
 	self.nextthink = time + 0.05;
 }
 
-void kh_WinnerTeam(float teem)
+void kh_WinnerTeam(float teem)  // runs when a team wins
 {
 	// all key carriers get some points
 	vector firstorigin, lastorigin, midpoint;
@@ -569,13 +634,13 @@
 		te_lightning2(world, lastorigin, firstorigin);
 	}
 	midpoint = midpoint * (1 / kh_teams);
-	te_customflash(midpoint, 1000, 1, TeamColor(teem) * 0.5 + '0.5 0.5 0.5'); // make the color >=0.5 in each component
+	te_customflash(midpoint, 1000, 1, TeamColor(teem) * 0.5 + '0.5 0.5 0.5');  // make the color >=0.5 in each component
 
 	sound(world, CHAN_AUTO, kh_sound_capture, 1, ATTN_NONE);
 	kh_FinishRound();
 }
 
-void kh_LoserTeam(float teem, entity lostkey)
+void kh_LoserTeam(float teem, entity lostkey)  // runs when a player pushes a flag carrier off the map
 {
 	entity player, key, attacker;
 	float players;
@@ -655,7 +720,7 @@
 	kh_FinishRound();
 }
 
-void kh_FinishRound()
+void kh_FinishRound()  // runs when a team captures the keys
 {
 	// prepare next round
 	kh_interferemsg_time = 0;
@@ -666,7 +731,7 @@
 	kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_round"), "Round starts in ", kh_StartRound);
 }
 
-string kh_CheckEnoughPlayers()
+string kh_CheckEnoughPlayers()  // checks enough player are present, runs after every completed round
 {
 	float i, players, teem;
 	entity player;
@@ -693,7 +758,7 @@
 	return result;
 }
 
-void kh_WaitForPlayers()
+void kh_WaitForPlayers()  // delay start of the round until enough players are present
 {
 	string teams_missing;
 	teams_missing = kh_CheckEnoughPlayers();
@@ -703,7 +768,7 @@
 		kh_Controller_SetThink(1, strcat("Waiting for players to join...\n\nNeed active players for: ", teams_missing), kh_WaitForPlayers);
 }
 
-void kh_StartRound()
+void kh_StartRound()  // runs at the start of each round
 {
 	string teams_missing;
 	float i, players, teem;
@@ -743,12 +808,12 @@
 	kh_Controller_SetThink(cvar("g_balance_keyhunt_delay_tracking"), "Scanning frequency range...", kh_EnableTrackingDevice);
 }
 
-void kh_setstatus()
+void kh_setstatus()  // runs all the time
 {
 	if(kh_teams)
 	{
 		float kh_KEY;
-		kh_KEY = (IT_RED_FLAG_TAKEN | IT_RED_FLAG_LOST | IT_BLUE_FLAG_TAKEN | IT_BLUE_FLAG_LOST); // the one impossible combination
+		kh_KEY = (IT_RED_FLAG_TAKEN | IT_RED_FLAG_LOST | IT_BLUE_FLAG_TAKEN | IT_BLUE_FLAG_LOST);  // the one impossible combination
 		if(self.kh_next)
 			self.items = self.items | kh_KEY;
 		else
@@ -756,7 +821,7 @@
 	}
 }
 
-void kh_EnableTrackingDevice()
+void kh_EnableTrackingDevice()  // runs after each round
 {
 	entity player;
 
@@ -767,7 +832,7 @@
 	kh_tracking_enabled = TRUE;
 }
 
-float kh_Key_waypointsprite_for_player(entity e)
+float kh_Key_waypointsprite_for_player(entity e) // ??
 {
 	if(!kh_tracking_enabled)
 		return 0;
@@ -775,10 +840,10 @@
 		return kh_sprite_dropped;
 	if(!self.owner.owner)
 		return kh_sprite_dropped;
-	return 0; // draw only when key is not owned
+	return 0;  // draw only when key is not owned
 }
 
-float kh_KeyCarrier_waypointsprite_for_player(entity e)
+float kh_KeyCarrier_waypointsprite_for_player(entity e)  // runs all the time
 {
 	if(e.classname != "player" || self.team != e.team)
 		if(!kh_tracking_enabled)
@@ -800,7 +865,7 @@
 	return kh_GetCarrierSprite(self.team, e.team);
 }
 
-float kh_HandleFrags(entity attacker, entity targ, float f)
+float kh_HandleFrags(entity attacker, entity targ, float f)  // adds to the player score
 {
 	if(attacker == targ)
 		return f;
@@ -825,12 +890,13 @@
 	return f;
 }
 
-void kh_init()
+void kh_init()  // sets up th KH environment
 {
 	precache_sound(kh_sound_capture);
 	precache_sound(kh_sound_destroy);
 	precache_sound(kh_sound_drop);
 	precache_sound(kh_sound_collect);
+	precache_sound(kh_sound_alarm);  // the new siren
 
 	precache_model("models/sprites/key-dropped.sp2");
 	precache_model("models/sprites/keycarrier-finish.sp2");
@@ -883,6 +949,8 @@
 	setmodel(kh_controller, "models/sprites/keycarrier-yellow.sp2");
 	kh_sprite_yellow = kh_controller.modelindex;
 	setmodel(kh_controller, "");
+
+	addstat(STAT_KH_KEYS, AS_INT, kh_state);
 }
 
 void kh_finalize()
@@ -892,3 +960,24 @@
 	remove(kh_controller);
 	kh_controller = world;
 }
+
+/**
+ * kh_show_temp originally by victim.
+ * changed it to use the kh_state stat var
+ * Updates the general key stat bits for each player
+ */
+void kh_show_temp()
+{
+	entity player;
+	float i, j;
+
+	j = 0;  // reset/blank j
+	for(i=1; i<17; ++i)  // replace 17 with cvar("maxplayers"); !!!!!!!!!
+		j += test[i];
+
+	test[0] = j;
+
+	j *= 256;
+	FOR_EACH_PLAYER(player)
+		player.kh_state = j + (player.kh_state & 255); // update the general key bits
+}

Modified: branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/keyhunt.qh	2008-07-21 14:44:04 UTC (rev 3868)
@@ -25,6 +25,8 @@
 float kh_HandleFrags(entity attacker, entity targ, float f);
 float kh_Key_AllOwnedByWhichTeam();
 
+void kh_show_temp();  // added by victim
+
 #define STR_ITEM_KH_KEY "item_kh_key"
 typedef void(void) kh_Think_t;
 var kh_Think_t kh_Controller_Thinkfunc;

Modified: branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/miscfunctions.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -3,6 +3,7 @@
 string ColoredTeamName(float t);
 
 float RandomSelection_totalweight;
+float RandomSelection_best_priority;
 entity RandomSelection_chosen_ent;
 float RandomSelection_chosen_float;
 void RandomSelection_Init()
@@ -10,15 +11,26 @@
 	RandomSelection_totalweight = 0;
 	RandomSelection_chosen_ent = world;
 	RandomSelection_chosen_float = 0;
+	RandomSelection_best_priority = -1;
 }
-void RandomSelection_Add(entity e, float f, float weight)
+void RandomSelection_Add(entity e, float f, float weight, float priority)
 {
-	RandomSelection_totalweight += weight;
-	if(random() * RandomSelection_totalweight <= weight)
+	if(priority > RandomSelection_best_priority)
 	{
+		RandomSelection_best_priority = priority;
 		RandomSelection_chosen_ent = e;
 		RandomSelection_chosen_float = f;
+		RandomSelection_totalweight = weight;
 	}
+	else if(priority == RandomSelection_best_priority)
+	{
+		RandomSelection_totalweight += weight;
+		if(random() * RandomSelection_totalweight <= weight)
+		{
+			RandomSelection_chosen_ent = e;
+			RandomSelection_chosen_float = f;
+		}
+	}
 }
 
 float DistributeEvenly_amount;
@@ -769,6 +781,8 @@
 	g_tourney = cvar("g_tourney");
 	sv_maxidle = cvar("sv_maxidle");
 	sv_maxidle_spectatorsareidle = cvar("sv_maxidle_spectatorsareidle");
+	sv_pogostick = cvar("sv_pogostick");
+	sv_doublejump = cvar("sv_doublejump");
 
 	g_pickup_shells                    = cvar("g_pickup_shells");
 	g_pickup_shells_max                = cvar("g_pickup_shells_max");

Modified: branches/nexuiz-2.0/data/qcsrc/server/progs.src
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/progs.src	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/progs.src	2008-07-21 14:44:04 UTC (rev 3868)
@@ -8,6 +8,9 @@
 
 extensions.qh
 
+//// tZork Turrets ////
+tturrets/include/turret_tturrets_early.qh
+
 campaign.qh
 ../common/campaign_common.qh
 ../common/util.qh
@@ -75,6 +78,8 @@
 //g_tetris.qc
 cl_impulse.qc
 
+ent_cs.qc
+
 cl_player.qc
 cl_client.qc
 t_plats.qc
@@ -112,3 +117,7 @@
 t_quake3.qc
 t_halflife.qc
 t_quake.qc
+
+
+//// tZork Turrets ////
+tturrets/include/turret_tturrets.qh
\ No newline at end of file

Copied: branches/nexuiz-2.0/data/qcsrc/server/server.cbp (from rev 3866, trunk/data/qcsrc/server/server.cbp)
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/server.cbp	                        (rev 0)
+++ branches/nexuiz-2.0/data/qcsrc/server/server.cbp	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<CodeBlocks_project_file>
+	<FileVersion major="1" minor="6" />
+	<Project>
+		<Option title="server" />
+		<Option pch_mode="2" />
+		<Option compiler="quakec" />
+		<Build>
+			<Target title="Standard">
+				<Option output="bin\Debug\server" prefix_auto="1" extension_auto="1" />
+				<Option object_output="obj\Debug\" />
+				<Option type="1" />
+				<Option compiler="quakec" />
+				<Compiler>
+					<Add option="-g" />
+				</Compiler>
+			</Target>
+		</Build>
+		<Compiler>
+			<Add option="-Wall" />
+		</Compiler>
+		<Extensions>
+			<code_completion />
+			<envvars />
+			<debugger />
+			<lib_finder disable_auto="1" />
+		</Extensions>
+	</Project>
+</CodeBlocks_project_file>

Modified: branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/sv_main.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -137,6 +137,19 @@
 }
 
 
+void BroadcastPings()
+{
+	entity pl;
+	WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
+	WriteByte(MSG_BROADCAST, TE_CSQC_PING);
+	FOR_EACH_CLIENT(pl)
+	{
+		WriteByte(MSG_BROADCAST, num_for_edict(pl));
+		WriteShort(MSG_BROADCAST, pl.ping);
+	}
+	WriteByte(MSG_BROADCAST, 0);
+}
+
 /*
 =============
 StartFrame
@@ -180,8 +193,14 @@
 	{
 		RandomSelection_Init();
 		for(self = world; (self = find(self, classname, "player")); )
-			RandomSelection_Add(self, 0, 1);
+			RandomSelection_Add(self, 0, 1, 0);
 		self = RandomSelection_chosen_ent;
 		SelectSpawnPoint(0);
 	}
+
+	if(next_pingtime < time)
+	{
+		BroadcastPings();
+		next_pingtime = time + 10;
+	}
 }

Modified: branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/t_plats.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -673,6 +673,9 @@
 	if (!self.lip)
 		self.lip = 4;
 
+    if(self.noise != "")
+        precache_sound(self.noise);
+
 	self.state = STATE_BOTTOM;
 
 	self.pos1 = self.origin;

Modified: branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/teamplay.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -25,6 +25,10 @@
 
 void TeamchangeFrags(entity e)
 {
+	if(g_ctf)
+	{
+		e.captures = 0;
+	}
 	if(e.classname == "player")
 	{
 		// reduce frags during a team change
@@ -75,6 +79,7 @@
 void ctf_init();
 void runematch_init();
 void tdm_init();
+void entcs_init();
 
 void LogTeamchange(entity pl)
 {
@@ -116,7 +121,7 @@
 
 void InitGameplayMode()
 {
-	float fraglimit_override, timelimit_override;
+	float fraglimit_override, timelimit_override, capturelimit_override;
 
 	VoteReset();
 
@@ -130,6 +135,7 @@
 	// set both here, gamemode can override it later
 	timelimit_override = cvar("timelimit_override");
 	fraglimit_override = cvar("fraglimit_override");
+	capturelimit_override = cvar("capturelimit_override");
 
 	if(game == GAME_DOMINATION || cvar("g_domination"))
 	{
@@ -153,6 +159,7 @@
 		ActivateTeamplay();
 
 		fraglimit_override = cvar("g_ctf_capture_limit");
+		//no capture limit override here
 
 		gamemode_name = "Capture the Flag";
 		teams_matter = 1;
@@ -258,22 +265,12 @@
 	{
 		// we can only assume...
 		ResetGameCvars();
+		game = GAME_DEATHMATCH;
 		cvar_set("g_dm", "1");
 		gamemode_name = "Deathmatch";
 		teams_matter = 0;
 	}
-/*	else if(game == GAME_TEAM_DEATHMATCH)
-	{
-		if(!cvar("deathmatch"))
-			cvar_set("deathmatch", "1");
 
-		//if(!cvar("teamplay"))
-		//	cvar_set("teamplay", "3");
-		ActivateTeamplay();
-
-		fraglimit_override = cvar("fraglimit_override");
-	}*/
-
 	// those mutators rule each other out
 	if(cvar("g_minstagib"))
 	{
@@ -313,6 +310,8 @@
 			cvar_set("fraglimit", ftos(fraglimit_override));
 		if(timelimit_override >= 0)
 			cvar_set("timelimit", ftos(timelimit_override));
+		if(capturelimit_override >= 0)
+			cvar_set("capturelimit", ftos(capturelimit_override));
 	}
 
 	if (game == GAME_DOMINATION)//cvar("g_domination"))
@@ -325,6 +324,8 @@
 		tdm_init();
 	else if (game == GAME_KEYHUNT)//cvar("g_keyhunt"))
 		kh_init();
+	else if (game == GAME_ONSLAUGHT)
+		entcs_init();
 }
 
 string GetClientVersionMessage(float v) {
@@ -918,7 +919,7 @@
 	return smallest;
 }
 
-
+//void() ctf_playerchanged;
 void SV_ChangeTeam(float _color)
 {
 	float scolor, dcolor, steam, dteam, dbotcount, scount, dcount;
@@ -1047,6 +1048,7 @@
 		if(self.deadflag == DEAD_NO)
 			Damage(self, self, self, 100000, DEATH_TEAMCHANGE, self.origin, '0 0 0');
 	}
+	//ctf_playerchanged();
 }
 
 void ShufflePlayerOutOfTeam (float source_team)

Copied: branches/nexuiz-2.0/data/qcsrc/server/tturrets (from rev 3866, trunk/data/qcsrc/server/tturrets)

Modified: branches/nexuiz-2.0/data/qcsrc/server/vote.qc
===================================================================
--- branches/nexuiz-2.0/data/qcsrc/server/vote.qc	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/qcsrc/server/vote.qc	2008-07-21 14:44:04 UTC (rev 3868)
@@ -402,7 +402,7 @@
 	vote = argv(2);
 	while(argv(index) != "") {
 		vote = strcat(vote, " ", argv(index));
-		index++;
+		++index;
 	}
 
 	return vote;
@@ -416,7 +416,7 @@
 		if(votecommand == argv(index)) {
 			return TRUE;
 		}
-		index++;
+		++index;
 	}
 	return FALSE;
 }
@@ -548,23 +548,23 @@
 	FOR_EACH_REALCLIENT(player)
 	{
 		if(player.vote_vote == -1) {
-			nocount++;
+			++nocount;
 		} else if(player.vote_vote == 1) {
-			yescount++;
+			++yescount;
 		} else if(player.vote_vote == -2) {
-			abstaincount++;
+			++abstaincount;
 		}
-		playercount++;
+		++playercount;
 		//do the same for real players
 		if(player.classname == "player") {
 			if(player.vote_vote == -1) {
-				realplayernocount++;
+				++realplayernocount;
 			} else if(player.vote_vote == 1) {
-				realplayeryescount++;
+				++realplayeryescount;
 			} else if(player.vote_vote == -2) {
-				realplayerabstaincount++;
+				++realplayerabstaincount;
 			}
-			realplayercount++;
+			++realplayercount;
 		}
 	}
 

Modified: branches/nexuiz-2.0/data/scripts/entities.def
===================================================================
--- branches/nexuiz-2.0/data/scripts/entities.def	2008-07-21 14:34:16 UTC (rev 3867)
+++ branches/nexuiz-2.0/data/scripts/entities.def	2008-07-21 14:44:04 UTC (rev 3868)
@@ -222,6 +222,7 @@
 /*QUAKED info_player_attacker (1 0.5 0) (-16 -16 -24) (16 16 45) 
 Attacking team's player spawning location in Assault. Should touch the floor, but not the walls, and should point where the player should look when he spawns there.
 -------- KEYS --------
+target: this should point to a target_objective to decide when this spawning point is active.
 cnt: weight of spawn point for random selection. Set to a lower value if you have many spawn points close together. Default value is 1.
 */
 
@@ -235,6 +236,7 @@
 /*QUAKED info_player_defender (.5 .5 .5) (-16 -16 -24) (16 16 45) 
 Defending team's player spawning location in Assault. Should touch the floor, but not the walls, and should point where the player should look when he spawns there.
 -------- KEYS --------
+target: this should point to a target_objective to decide when this spawning point is active.
 cnt: weight of spawn point for random selection. Set to a lower value if you have many spawn points close together. Default value is 1.
 */
 
@@ -687,9 +689,11 @@
 "dampener field": just set strength to a value from 0 to 1. Entering the field will slow down to this factor.
 "accelerator field": just set strength to a value from 1 to infinity. Entering the field will accelerate by this factor.
 "wind field": set strength to the amount of velocity to add per second, and target a target_position. The field will apply force in the direction from its own origin to the target (use an origin brush to specify its own origin, or this will fail) when touched.
+"gravity field": set strength to the amount of velocity to add per second at the center, and set radius to the radius of the field. Set falloff to the desired falloff characteristics.
 -------- KEYS --------
 target: "wind field": points to the target_position to which the player will get pushed.
-strength: "wind field": amount of force per second to apply in direction from origin to target. "dampener/accelerator field": slowdown/speedup factor.
+strength: "wind field", "gravity field": amount of force per second to apply. "dampener/accelerator field": slowdown/speedup factor.
+falloff: "gravity field": 0 means no falloff, 1 means linear falloff (zero at the outside), 2 means inverted linear falloff (zero at the inside)
 */
 
 /*QUAKED trigger_multiple (.5 .5 .5) ? NOTOUCH

Copied: branches/nexuiz-2.0/data/scripts/turrets.def (from rev 3866, trunk/data/scripts/turrets.def)
===================================================================
--- branches/nexuiz-2.0/data/scripts/turrets.def	                        (rev 0)
+++ branches/nexuiz-2.0/data/scripts/turrets.def	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,194 @@
+/*QUAKED turret_machinegun (1 0 0) (-32 -32 0) (32 32 50) - PILLAR
+Fast firing moderate damage bullet (hitscan) turret.
+-------- KEYS --------
+turret_scale_damage: 2 = double damage, 0.5 = half
+turret_scale_range: 2 = double range, 0.5 = half
+turret_scale_refire: 2 = double refire (SLOWER!), 0.5 = half (FASTER!)
+turret_scale_ammo: 2 = double ammo carry & regen, 0.5 = half ammo carry & regen
+turret_scale_aim: 2 = aim twice as fast, 0,5 = aim at half speed
+turret_scale_health: 2 = double health, 0.5 = half
+master_name: This turret controls what all turrets with master_nameof set to this aim at
+master_nameof: Dont select own targets, use the target of the turret with this master_name
+target: Defend the position of this entity
+team: 5=red, 14=blue
+-------- SPAWNFLAGS --------
+PILLAR: Adds a supporting pillar under this turret, for turrets on terrain/uneven surfaces. (only for visuals)
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/turrets/radiant/mg.md3"
+*/
+
+/*QUAKED turret_plasma (1 0 0) (-32 -32 0) (32 32 50) - PILLAR
+-------- KEYS --------
+turret_scale_damage: 2 = double damage, 0.5 = half
+turret_scale_range: 2 = double range, 0.5 = half
+turret_scale_refire: 2 = double refire (SLOWER!), 0.5 = half (FASTER!)
+turret_scale_ammo: 2 = double ammo carry & regen, 0.5 = half ammo carry & regen
+turret_scale_aim: 2 = aim twice as fast, 0,5 = aim at half speed
+turret_scale_health: 2 = double health, 0.5 = half
+master_name: This turret controls what all turrets with master_nameof set to this aim at
+master_nameof: Dont select own targets, use the target of the turret with this master_name
+target: Defend the position of this entity
+team: 5=red, 14=blue
+-------- SPAWNFLAGS --------
+PILLAR: Adds a supporting pillar under this turret, for turrets on terrain/uneven surfaces. (only for visuals)
+---------NOTES----------
+Basic energy cannon
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/turrets/radiant/plasma.md3"
+*/
+
+/*QUAKED turret_plasma_dual (1 0 0) (-32 -32 0) (32 32 50) - PILLAR
+basic energy cannon * 2
+-------- KEYS --------
+turret_scale_damage: 2 = double damage, 0.5 = half
+turret_scale_range: 2 = double range, 0.5 = half
+turret_scale_refire: 2 = double refire (SLOWER!), 0.5 = half (FASTER!)
+turret_scale_ammo: 2 = double ammo carry & regen, 0.5 = half ammo carry & regen
+turret_scale_aim: 2 = aim twice as fast, 0,5 = aim at half speed
+turret_scale_health: 2 = double health, 0.5 = half
+master_name: This turret controls what all turrets with master_nameof set to this aim at
+master_nameof: Dont select own targets, use the target of the turret with this master_name
+target: Defend the position of this entity
+team: 5=red, 14=blue
+-------- SPAWNFLAGS --------
+PILLAR: Adds a supporting pillar under this turret, for turrets on terrain/uneven surfaces. (only for visuals)
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/turrets/radiant/plasma2.md3"
+*/
+
+/*QUAKED turret_flac (1 0 0) (-32 -32 0) (32 32 50) - PILLAR
+Only kills missiles, rockets, grenadelauncher & electro secondaries to be precise.
+-------- KEYS --------
+turret_scale_damage: 2 = double damage, 0.5 = half
+turret_scale_range: 2 = double range, 0.5 = half
+turret_scale_refire: 2 = double refire (SLOWER!), 0.5 = half (FASTER!)
+turret_scale_ammo: 2 = double ammo carry & regen, 0.5 = half ammo carry & regen
+turret_scale_aim: 2 = aim twice as fast, 0,5 = aim at half speed
+turret_scale_health: 2 = double health, 0.5 = half
+master_name: This turret controls what all turrets with master_nameof set to this aim at
+master_nameof: Dont select own targets, use the target of the turret with this master_name
+target: Defend the position of this entity
+team: 5=red, 14=blue
+-------- SPAWNFLAGS --------
+PILLAR: Adds a supporting pillar under this turret, for turrets on terrain/uneven surfaces. (only for visuals)
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/turrets/radiant/flac.md3"
+*/
+
+/*QUAKED turret_mlrs (1 0 0) (-32 -32 0) (32 32 50)
+6 unguided rockers fired in a rapid burst.
+-------- KEYS --------
+turret_scale_damage: 2 = double damage, 0.5 = half
+turret_scale_range: 2 = double range, 0.5 = half
+turret_scale_refire: 2 = double refire (SLOWER!), 0.5 = half (FASTER!)
+turret_scale_ammo: 2 = double ammo carry & regen, 0.5 = half ammo carry & regen
+turret_scale_aim: 2 = aim twice as fast, 0,5 = aim at half speed
+turret_scale_health: 2 = double health, 0.5 = half
+master_name: This turret controls what all turrets with master_nameof set to this aim at
+master_nameof: Dont select own targets, use the target of the turret with this master_name
+target: Defend the position of this entity
+team: 5=red, 14=blue
+-------- SPAWNFLAGS --------
+PILLAR: Adds a supporting pillar under this turret, for turrets on terrain/uneven surfaces. (only for visuals)
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/turrets/radiant/mlrs.md3"
+*/
+
+/*QUAKED turret_hellion (1 0 0) (-32 -32 0) (32 32 50)
+2 guided moderate damage accelerating rockets 
+-------- KEYS --------
+turret_scale_damage: 2 = double damage, 0.5 = half
+turret_scale_range: 2 = double range, 0.5 = half
+turret_scale_refire: 2 = double refire (SLOWER!), 0.5 = half (FASTER!)
+turret_scale_ammo: 2 = double ammo carry & regen, 0.5 = half ammo carry & regen
+turret_scale_aim: 2 = aim twice as fast, 0,5 = aim at half speed
+turret_scale_health: 2 = double health, 0.5 = half
+master_name: This turret controls what all turrets with master_nameof set to this aim at
+master_nameof: Dont select own targets, use the target of the turret with this master_name
+target: Defend the position of this entity
+team: 5=red, 14=blue
+-------- SPAWNFLAGS --------
+PILLAR: Adds a supporting pillar under this turret, for turrets on terrain/uneven surfaces. (only for visuals)
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/turrets/radiant/hellion.md3"
+*/
+
+
+/*QUAKED turret_hk (1 0 0) (-32 -32 0) (32 32 50)
+Single powerful rocket with the ability to evade obstacles to find its target. Varied speed.
+-------- KEYS --------
+turret_scale_damage: 2 = double damage, 0.5 = half
+turret_scale_range: 2 = double range, 0.5 = half
+turret_scale_refire: 2 = double refire (SLOWER!), 0.5 = half (FASTER!)
+turret_scale_ammo: 2 = double ammo carry & regen, 0.5 = half ammo carry & regen
+turret_scale_aim: 2 = aim twice as fast, 0,5 = aim at half speed
+turret_scale_health: 2 = double health, 0.5 = half
+master_name: This turret controls what all turrets with master_nameof set to this aim at
+master_nameof: Dont select own targets, use the target of the turret with this master_name
+target: Defend the position of this entity
+team: 5=red, 14=blue
+-------- SPAWNFLAGS --------
+PILLAR: Adds a supporting pillar under this turret, for turrets on terrain/uneven surfaces. (only for visuals)
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/turrets/radiant/hk.md3"
+*/
+
+/*QUAKED turret_tesla (1 0 0) (-32 -32 0) (32 32 50)
+Fires a lightning bolt that will jump to up to 10 targets if they are close enough to each other. Missiles included.
+-------- KEYS --------
+turret_scale_damage: 2 = double damage, 0.5 = half
+turret_scale_range: 2 = double range, 0.5 = half
+turret_scale_refire: 2 = double refire (SLOWER!), 0.5 = half (FASTER!)
+turret_scale_ammo: 2 = double ammo carry & regen, 0.5 = half ammo carry & regen
+turret_scale_aim: 2 = aim twice as fast, 0,5 = aim at half speed
+turret_scale_health: 2 = double health, 0.5 = half
+master_name: This turret controls what all turrets with master_nameof set to this aim at
+master_nameof: Dont select own targets, use the target of the turret with this master_name
+target: Defend the position of this entity
+team: 5=red, 14=blue
+-------- SPAWNFLAGS --------
+PILLAR: Adds a supporting pillar under this turret, for turrets on terrain/uneven surfaces. (only for visuals)
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/turrets/radiant/tesla.md3"
+*/
+
+/*QUAKED turret_phaser (1 0 0) (-32 -32 0) (32 32 50)
+Constant beam weapon that will considerably slow its target down while dealing low but constant damage.
+-------- KEYS --------
+turret_scale_damage: 2 = double damage, 0.5 = half
+turret_scale_range: 2 = double range, 0.5 = half
+turret_scale_refire: 2 = double refire (SLOWER!), 0.5 = half (FASTER!)
+turret_scale_ammo: 2 = double ammo carry & regen, 0.5 = half ammo carry & regen
+turret_scale_aim: 2 = aim twice as fast, 0,5 = aim at half speed
+turret_scale_health: 2 = double health, 0.5 = half
+master_name: This turret controls what all turrets with master_nameof set to this aim at
+master_nameof: Dont select own targets, use the target of the turret with this master_name
+target: Defend the position of this entity
+team: 5=red, 14=blue
+-------- SPAWNFLAGS --------
+PILLAR: Adds a supporting pillar under this turret, for turrets on terrain/uneven surfaces. (only for visuals)
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/turrets/radiant/phaser.md3"
+*/
+
+
+/*QUAKED turret_fusionreactor (1 0 0) (-32 -32 0) (32 32 50)
+-------- KEYS --------
+turret_scale_damage: 2 = double damage, 0.5 = half
+turret_scale_range: 2 = double range, 0.5 = half
+turret_scale_refire: 2 = double refire (SLOWER!), 0.5 = half (FASTER!)
+turret_scale_ammo: 2 = double ammo carry & regen, 0.5 = half ammo carry & regen
+turret_scale_aim: 2 = aim twice as fast, 0,5 = aim at half speed
+turret_scale_health: 2 = double health, 0.5 = half
+team: 5=red, 14=blue
+-------- SPAWNFLAGS --------
+PILLAR: Adds a supporting pillar under this turret, for turrets on terrain/uneven surfaces. (only for visuals)
+---------NOTES----------
+Supplies neerby energy based turrets with more power so they can fire more often.
+-------- MODEL FOR RADIANT ONLY - DO NOT SET THIS AS A KEY --------
+model="models/turrets/radiant/reactor.md3"
+*/
+
+/*QUAKED turret_targettrigger (.5 .5 .5) ?
+Used to feed turrets capable of it with remote target info. currently only turret_hk supports this.
+*/

Copied: branches/nexuiz-2.0/data/scripts/turrets.shader (from rev 3866, trunk/data/scripts/turrets.shader)
===================================================================
--- branches/nexuiz-2.0/data/scripts/turrets.shader	                        (rev 0)
+++ branches/nexuiz-2.0/data/scripts/turrets.shader	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,41 @@
+models/turrets/tesla_chrome
+{
+
+	qer_editorimage models/turrets/chrome.tga
+
+	//dp_reflect 0 0.75 0.75 1 0.5	
+	{
+		map models/turrets/chrome.tga	
+		rgbGen vertex
+		tcGen environment 
+		tcMod scale 2 2
+		
+	}
+}
+
+models/turrets/phaser_beam
+{
+	surfaceparm trans
+	cull none
+	nopicmip
+
+	qer_editorimage models/turrets/phaser_beam
+	{		
+		map models/turrets/phaser_beam
+		blendFunc add
+	}
+
+}
+
+models/turrets/reactor_beams
+{
+	surfaceparm trans
+	cull none
+
+	qer_editorimage models/turrets/reactor
+	{		
+		map models/turrets/reactor
+		blendFunc add
+	}
+}
+

Copied: branches/nexuiz-2.0/data/sound/turrets (from rev 3866, trunk/data/sound/turrets)

Copied: branches/nexuiz-2.0/data/textures/evil1_floors/floortile1bbrown.jpg (from rev 3866, trunk/data/textures/evil1_floors/floortile1bbrown.jpg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil1_floors/floortile1bbrown_bump.jpg (from rev 3866, trunk/data/textures/evil1_floors/floortile1bbrown_bump.jpg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil3_misc/b_rock.jpg (from rev 3866, trunk/data/textures/evil3_misc/b_rock.jpg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanel_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_dpanel_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelb_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_dpanelb_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelc_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_dpanelc_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrn_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrn_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrnb2_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrnb2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrnb_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrnb_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrnbgrt_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_dpanelwrnbgrt_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_lightboard_glow_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_lightboard_glow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_lightboard_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_lightboard_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_mpanel_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_mpanel_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtl_mpanelgrt_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtl_mpanelgrt_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtlsupport_alpha_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtlsupport_alpha_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_drkmtlsupport_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_drkmtlsupport_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_lighttechdoor_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_lighttechdoor_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_shinymtlsupport_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_shinymtlsupport_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall2_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_drkwall2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_b_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_drkwall_b_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_cutl_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_drkwall_cutl_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_cutr_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_drkwall_cutr_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_drkwall_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_seam2_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_drkwall_seam2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwall_seam_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_drkwall_seam_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_drkwll_pnltek_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_drkwll_pnltek_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2_fx_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dw2_fx_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2_glow_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dw2_glow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dw2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2g_glow_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dw2g_glow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2g_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dw2g_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw2gb_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dw2gb_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dw_grate_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dw_grate_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_2g_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dwb_2g_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_2gsign_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dwb_2gsign_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_light_glow.jpg (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dwb_light_glow.jpg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_light_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dwb_light_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dwb_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwb_sign_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dwb_sign_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dws_grate_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dws_grate_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_dwteky_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_dwteky_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall2_huge_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_wall2_huge_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_dlight_glow.jpg (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_wall_dlight_glow.jpg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_dlight_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_wall_dlight_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_drkm2_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_wall_drkm2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_drkm_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_wall_drkm_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_drkmpanel_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_wall_drkmpanel_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_wall_grll_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_wall_grll_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_window.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_window.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_window_gloss.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_window_gloss.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_d_techwalls/d_tech_window_norm.tga (from rev 3866, trunk/data/textures/evil4_d_techwalls/d_tech_window_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/drkmtlsupport_light_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/drkmtlsupport_light_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/dwtrim_llight_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/dwtrim_llight_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/l_light_b_glow_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/l_light_b_glow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/l_light_b_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/l_light_b_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/l_light_g_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/l_light_g_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/l_light_r_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/l_light_r_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/l_light_w_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/l_light_w_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/llight_s_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/llight_s_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/mtl_l1_fx_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/mtl_l1_fx_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/mtl_l1_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/mtl_l1_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/mtl_lightsmll_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/mtl_lightsmll_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/s_bluelight_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/s_bluelight_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/s_light_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/s_light_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/steplight_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/steplight_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/t_mtllight_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/t_mtllight_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_lights/trimtl_grlbtm_light_norm.tga (from rev 3866, trunk/data/textures/evil4_lights/trimtl_grlbtm_light_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/defaultmetal_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/defaultmetal_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/drkmtl_default_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/drkmtl_default_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/drkmtl_grlpltmech_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/drkmtl_grlpltmech_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/eshinytin_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/eshinytin_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/flrgrate_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/flrgrate_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/hexametal_drk_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/hexametal_drk_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/hexametal_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/hexametal_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mediummtl_default_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mediummtl_default_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtl2grt_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtl2grt_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlb_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlb_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlbrushed_env_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlbrushed_env_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlbrushed_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlbrushed_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtldoor_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtldoor_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlflrslots_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlflrslots_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtloverlaprwll_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtloverlaprwll_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_d_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlpanel_d_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlpanel_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_ow_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlpanel_ow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_wrnstripe_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlpanel_wrnstripe_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_wrnstripe_ow2_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlpanel_wrnstripe_ow2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanel_wrnstripe_ow_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlpanel_wrnstripe_ow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanelsmll_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlpanelsmll_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanelsmll_ow2_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlpanelsmll_ow2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlpanelsmll_ow_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlpanelsmll_ow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlslots_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlslots_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlslots_ow_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlslots_ow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlslotsrivts_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlslotsrivts_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlslotsrivts_ow_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlslotsrivts_ow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlsportal_fx3_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlsportal_fx3_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlsportal_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlsportal_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtltechwall_128_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtltechwall_128_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtltechwall_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtltechwall_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtltekfloor_fx2_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtltekfloor_fx2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtltekfloor_fx_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtltekfloor_fx_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtltekfloor_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtltekfloor_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlwrndoor2_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlwrndoor2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/mtlwrndoor_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/mtlwrndoor_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/step_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/step_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/stepgrl_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/stepgrl_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti2_0000_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti2_0000_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti2_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti2_wrn_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti2_wrn_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_lights_blend_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti_lights_blend_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrn2_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti_wrn2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrn2hfx_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti_wrn2hfx_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrn_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti_wrn_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrnb_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti_wrnb_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrnlights2_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti_wrnlights2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/tekwallmulti_wrnlights_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/tekwallmulti_wrnlights_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/trim_wrnrivets_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/trim_wrnrivets_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/trimtl_grlbtm_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/trimtl_grlbtm_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/whitemtl_default_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/whitemtl_default_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_metals/wrnjumppad_norm.tga (from rev 3866, trunk/data/textures/evil4_metals/wrnjumppad_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor2_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloor2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor2b_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloor2b_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor3_huge_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloor3_huge_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor3_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloor3_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor4_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloor4_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor4plain_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloor4plain_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloor_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor_rndholes_drty_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloor_rndholes_drty_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloor_rndholes_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloor_rndholes_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloorhex_big_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloorhex_big_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tfloorhex_smll_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tfloorhex_smll_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techfloors/tflooroddtile_norm.tga (from rev 3866, trunk/data/textures/evil4_techfloors/tflooroddtile_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/cleantrimmulti_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/cleantrimmulti_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/drkmtl_oddtrim_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/drkmtl_oddtrim_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/drttrimmulti_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/drttrimmulti_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/dw_combo_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/dw_combo_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_bevel_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/dwtrim_bevel_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_bevelslite_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/dwtrim_bevelslite_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_fade2_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/dwtrim_fade2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_fade_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/dwtrim_fade_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_grill_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/dwtrim_grill_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_grt_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/dwtrim_grt_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_panel2_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/dwtrim_panel2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/dwtrim_panel_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/dwtrim_panel_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/medmtl_oddtrim_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/medmtl_oddtrim_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techtrims/misc_grill_norm.tga (from rev 3866, trunk/data/textures/evil4_techtrims/misc_grill_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanel_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_dpanel_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanel_ow_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_dpanel_ow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelb_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_dpanelb_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelc_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_dpanelc_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelwrn_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_dpanelwrn_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelwrnb2_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_dpanelwrnb2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelwrnb_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_dpanelwrnb_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_dpanelwrnbgrt_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_dpanelwrnbgrt_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_lightboard_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_lightboard_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_mpanel_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_mpanel_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtl_mpanelgrt_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtl_mpanelgrt_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtlsupport_alpha_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtlsupport_alpha_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/drkmtlsupport_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/drkmtlsupport_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/lighttechdoor_drty_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/lighttechdoor_drty_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/lighttechdoor_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/lighttechdoor_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/mechanical_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/mechanical_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/mechanical_old_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/mechanical_old_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/mechanicalx128_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/mechanicalx128_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/mechanicalx128_old_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/mechanicalx128_old_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/shinymtlsupport_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/shinymtlsupport_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall2_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_drkwall2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_b_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_drkwall_b_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_cutl_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_drkwall_cutl_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_cutr_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_drkwall_cutr_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_drkwall_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_seam2_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_drkwall_seam2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwall_seam_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_drkwall_seam_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_drkwll_pnltek_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_drkwll_pnltek_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dw2_fx_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dw2_fx_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dw2_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dw2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dw2g_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dw2g_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dw2gb_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dw2gb_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dw_grate_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dw_grate_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwb_2g_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dwb_2g_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwb_2gsign_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dwb_2gsign_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwb_light_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dwb_light_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwb_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dwb_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwb_sign_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dwb_sign_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dws_grate_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dws_grate_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwteky_glow_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dwteky_glow_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_dwteky_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_dwteky_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall2_huge_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_wall2_huge_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_dlight_glow.jpg (from rev 3866, trunk/data/textures/evil4_techwalls/tech_wall_dlight_glow.jpg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_dlight_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_wall_dlight_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_drkm2_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_wall_drkm2_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_drkm_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_wall_drkm_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_drkmpanel_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_wall_drkmpanel_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_wall_grll_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_wall_grll_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_window.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_window.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_window_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_window_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil4_techwalls/tech_windowmask_norm.tga (from rev 3866, trunk/data/textures/evil4_techwalls/tech_windowmask_norm.tga)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil8_floor/e8clangfloor04warn2red.jpg (from rev 3866, trunk/data/textures/evil8_floor/e8clangfloor04warn2red.jpg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil8_lights/e8_rlighty.jpg (from rev 3866, trunk/data/textures/evil8_lights/e8_rlighty.jpg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/textures/evil8_lights/e8_rlighty_glow.jpg (from rev 3866, trunk/data/textures/evil8_lights/e8_rlighty_glow.jpg)
===================================================================
(Binary files differ)

Copied: branches/nexuiz-2.0/data/turrets.cfg (from rev 3866, trunk/data/turrets.cfg)
===================================================================
--- branches/nexuiz-2.0/data/turrets.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/turrets.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,19 @@
+set g_turrets 1
+set g_turrets_reloadcvars 0
+set g_turrets_nofire 0
+
+exec unit_hk.cfg
+exec unit_plasma.cfg
+exec unit_plasma2.cfg
+exec unit_fusreac.cfg	
+exec unit_mlrs.cfg
+exec unit_hellion.cfg
+//exec unit_gauss.cfg
+exec unit_flac.cfg
+exec unit_minigun.cfg
+exec unit_tesla.cfg
+exec unit_walker.cfg
+exec unit_machinegun.cfg
+exec unit_phaser.cfg
+
+set g_turrets_reloadcvars 1

Copied: branches/nexuiz-2.0/data/unit_flac.cfg (from rev 3866, trunk/data/unit_flac.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_flac.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_flac.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,38 @@
+set g_turrets_unit_flac_std_health 700	
+set g_turrets_unit_flac_std_respawntime 90
+
+set g_turrets_unit_flac_std_shot_dmg 75
+set g_turrets_unit_flac_std_shot_refire 0.19
+set g_turrets_unit_flac_std_shot_radius 250
+set g_turrets_unit_flac_std_shot_speed 4000
+set g_turrets_unit_flac_std_shot_spread 0.07
+set g_turrets_unit_flac_std_shot_force 50
+set g_turrets_unit_flac_std_shot_volly 0
+set g_turrets_unit_flac_std_shot_volly_refire 0.5
+
+set g_turrets_unit_flac_std_target_range 5000
+set g_turrets_unit_flac_std_target_range_min 500
+set g_turrets_unit_flac_std_target_range_fire 5000
+set g_turrets_unit_flac_std_target_range_optimal 2500
+
+set g_turrets_unit_flac_std_target_select_rangebias 0.25
+set g_turrets_unit_flac_std_target_select_samebias 0.25
+set g_turrets_unit_flac_std_target_select_anglebias 0.5
+set g_turrets_unit_flac_std_target_select_playerbias 0
+set g_turrets_unit_flac_std_target_select_missilebias 1
+
+set g_turrets_unit_flac_std_ammo_max 1000
+set g_turrets_unit_flac_std_ammo 500
+set g_turrets_unit_flac_std_ammo_recharge 100
+
+set g_turrets_unit_flac_std_aim_firetolerance_dist 200
+set g_turrets_unit_flac_std_aim_firetolerance_angle 5
+set g_turrets_unit_flac_std_aim_speed 200
+set g_turrets_unit_flac_std_aim_maxrot 360
+set g_turrets_unit_flac_std_aim_maxpitch 35
+
+set g_turrets_unit_flac_std_track_type 3
+set g_turrets_unit_flac_std_track_accel_pitch 0.45
+set g_turrets_unit_flac_std_track_accel_rot 0.65
+set g_turrets_unit_flac_std_track_blendrate 0.15
+

Copied: branches/nexuiz-2.0/data/unit_fusreac.cfg (from rev 3866, trunk/data/unit_fusreac.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_fusreac.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_fusreac.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,13 @@
+set g_turrets_unit_fusreac_std_health 700
+set g_turrets_unit_fusreac_std_respawntime 90
+
+set g_turrets_unit_fusreac_std_shot_dmg 50
+set g_turrets_unit_fusreac_std_shot_refire 0.1
+
+set g_turrets_unit_fusreac_std_target_range 1024
+set g_turrets_unit_fusreac_std_target_range_min 1
+set g_turrets_unit_fusreac_std_target_range_fire 1024
+
+set g_turrets_unit_fusreac_std_ammo_max 250
+set g_turrets_unit_fusreac_std_ammo 0
+set g_turrets_unit_fusreac_std_ammo_recharge 250

Copied: branches/nexuiz-2.0/data/unit_hellion.cfg (from rev 3866, trunk/data/unit_hellion.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_hellion.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_hellion.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,42 @@
+set g_turrets_unit_hellion_std_health 500	
+set g_turrets_unit_hellion_std_respawntime 90
+
+set g_turrets_unit_hellion_std_shot_dmg 50
+set g_turrets_unit_hellion_std_shot_refire 0.15
+set g_turrets_unit_hellion_std_shot_radius 100
+
+set g_turrets_unit_hellion_std_shot_speed 750
+set g_turrets_unit_hellion_std_shot_speed_max 2500
+set g_turrets_unit_hellion_std_shot_speed_gain 1.05
+
+set g_turrets_unit_hellion_std_shot_spread 0.08
+set g_turrets_unit_hellion_std_shot_force 250
+set g_turrets_unit_hellion_std_shot_volly 2
+set g_turrets_unit_hellion_std_shot_volly_refire 4
+
+set g_turrets_unit_hellion_std_target_range 5120
+set g_turrets_unit_hellion_std_target_range_min 256
+set g_turrets_unit_hellion_std_target_range_fire 4096
+set g_turrets_unit_hellion_std_target_range_optimal 3072
+
+set g_turrets_unit_hellion_std_target_select_rangebias 0.7
+set g_turrets_unit_hellion_std_target_select_samebias 0.15
+set g_turrets_unit_hellion_std_target_select_anglebias 0.15
+set g_turrets_unit_hellion_std_target_select_playerbias 1
+set g_turrets_unit_hellion_std_target_select_missilebias 0
+
+set g_turrets_unit_hellion_std_ammo_max 700
+set g_turrets_unit_hellion_std_ammo 300
+set g_turrets_unit_hellion_std_ammo_recharge 50
+
+set g_turrets_unit_hellion_std_aim_firetolerance_dist 200
+set g_turrets_unit_hellion_std_aim_firetolerance_angle 25
+set g_turrets_unit_hellion_std_aim_speed 96
+set g_turrets_unit_hellion_std_aim_maxrot 360
+set g_turrets_unit_hellion_std_aim_maxpitch 15
+
+set g_turrets_unit_hellion_std_track_type 3
+set g_turrets_unit_hellion_std_track_accel_pitch 0.25
+set g_turrets_unit_hellion_std_track_accel_rot 0.25
+set g_turrets_unit_hellion_std_track_blendrate 0.75
+

Copied: branches/nexuiz-2.0/data/unit_hk.cfg (from rev 3866, trunk/data/unit_hk.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_hk.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_hk.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,45 @@
+set g_turrets_unit_hk_std_health 500	
+set g_turrets_unit_hk_std_respawntime 90
+
+set g_turrets_unit_hk_std_shot_dmg 120
+set g_turrets_unit_hk_std_shot_refire 5
+set g_turrets_unit_hk_std_shot_radius 200
+
+set g_turrets_unit_hk_std_shot_speed 500
+set g_turrets_unit_hk_std_shot_speed_max 850
+set g_turrets_unit_hk_std_shot_speed_accel 1.05
+set g_turrets_unit_hk_std_shot_speed_accel2 1.1
+set g_turrets_unit_hk_std_shot_speed_decel 0.9
+set g_turrets_unit_hk_std_shot_speed_turnrate 0.2
+
+set g_turrets_unit_hk_std_shot_spread 0
+set g_turrets_unit_hk_std_shot_force 800
+set g_turrets_unit_hk_std_shot_volly 1
+set g_turrets_unit_hk_std_shot_volly_refire 5
+
+set g_turrets_unit_hk_std_target_range 5120
+set g_turrets_unit_hk_std_target_range_min 256
+set g_turrets_unit_hk_std_target_range_fire 4096
+set g_turrets_unit_hk_std_target_range_optimal 4096
+
+set g_turrets_unit_hk_std_target_select_rangebias 0.5
+set g_turrets_unit_hk_std_target_select_samebias 0
+set g_turrets_unit_hk_std_target_select_anglebias 0.5
+set g_turrets_unit_hk_std_target_select_playerbias 1
+set g_turrets_unit_hk_std_target_select_missilebias 0
+
+set g_turrets_unit_hk_std_ammo_max 240
+set g_turrets_unit_hk_std_ammo 120
+set g_turrets_unit_hk_std_ammo_recharge 16
+
+set g_turrets_unit_hk_std_aim_firetolerance_dist 250
+set g_turrets_unit_hk_std_aim_firetolerance_angle 25
+set g_turrets_unit_hk_std_aim_speed 50
+set g_turrets_unit_hk_std_aim_maxrot 360
+set g_turrets_unit_hk_std_aim_maxpitch 10	
+
+set g_turrets_unit_hk_std_track_type 2
+set g_turrets_unit_hk_std_track_accel_pitch 0.45
+set g_turrets_unit_hk_std_track_accel_rot 0.6
+set g_turrets_unit_hk_std_track_blendrate 0.5
+

Copied: branches/nexuiz-2.0/data/unit_machinegun.cfg (from rev 3866, trunk/data/unit_machinegun.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_machinegun.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_machinegun.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,39 @@
+set g_turrets_unit_machinegun_std_health 256	
+set g_turrets_unit_machinegun_std_respawntime 60
+
+set g_turrets_unit_machinegun_std_shot_dmg 20
+set g_turrets_unit_machinegun_std_shot_refire 0.15
+set g_turrets_unit_machinegun_std_shot_spread 0.015
+set g_turrets_unit_machinegun_std_shot_force 45
+set g_turrets_unit_machinegun_std_shot_radius 0
+set g_turrets_unit_machinegun_std_shot_speed 0
+set g_turrets_unit_machinegun_std_shot_volly 5
+set g_turrets_unit_machinegun_std_shot_volly_refire 0.45
+
+set g_turrets_unit_machinegun_std_target_range 4000
+set g_turrets_unit_machinegun_std_target_range_min 2
+set g_turrets_unit_machinegun_std_target_range_fire 3000
+set g_turrets_unit_machinegun_std_target_range_optimal 1500
+
+set g_turrets_unit_machinegun_std_target_select_rangebias 0.25
+set g_turrets_unit_machinegun_std_target_select_samebias 0.25
+set g_turrets_unit_machinegun_std_target_select_anglebias 0.5
+set g_turrets_unit_machinegun_std_target_select_playerbias 1
+set g_turrets_unit_machinegun_std_target_select_missilebias 0
+
+set g_turrets_unit_machinegun_std_ammo_max 2000
+set g_turrets_unit_machinegun_std_ammo 200
+set g_turrets_unit_machinegun_std_ammo_recharge 95
+
+set g_turrets_unit_machinegun_std_aim_firetolerance_dist 75
+set g_turrets_unit_machinegun_std_aim_firetolerance_angle 16
+set g_turrets_unit_machinegun_std_aim_speed 100
+set g_turrets_unit_machinegun_std_aim_maxrot 400
+set g_turrets_unit_machinegun_std_aim_maxpitch 25
+
+set g_turrets_unit_machinegun_std_track_type 3
+set g_turrets_unit_machinegun_std_track_accel_pitch 0.25
+set g_turrets_unit_machinegun_std_track_accel_rot 0.75
+set g_turrets_unit_machinegun_std_track_blendrate 0.25
+
+

Copied: branches/nexuiz-2.0/data/unit_minigun.cfg (from rev 3866, trunk/data/unit_minigun.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_minigun.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_minigun.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,41 @@
+set g_turrets_unit_minigun_std_health 256	
+set g_turrets_unit_minigun_std_respawntime 60
+
+set g_turrets_unit_minigun_std_spin_up_time 2.5
+
+set g_turrets_unit_minigun_std_shot_dmg 10
+set g_turrets_unit_minigun_std_shot_refire 0.05
+set g_turrets_unit_minigun_std_shot_spread 0.032
+set g_turrets_unit_minigun_std_shot_force 64
+set g_turrets_unit_minigun_std_shot_radius 0
+set g_turrets_unit_minigun_std_shot_speed 0
+set g_turrets_unit_minigun_std_shot_volly 10
+set g_turrets_unit_minigun_std_shot_volly_refire 0.5
+
+set g_turrets_unit_minigun_std_target_range 4000
+set g_turrets_unit_minigun_std_target_range_min 2
+set g_turrets_unit_minigun_std_target_range_fire 3000
+set g_turrets_unit_minigun_std_target_range_optimal 512
+
+set g_turrets_unit_minigun_std_target_select_rangebias 0.25
+set g_turrets_unit_minigun_std_target_select_samebias 0.25
+set g_turrets_unit_minigun_std_target_select_anglebias 0.5
+set g_turrets_unit_minigun_std_target_select_playerbias 1
+set g_turrets_unit_minigun_std_target_select_missilebias 0
+
+set g_turrets_unit_minigun_std_ammo_max 4000
+set g_turrets_unit_minigun_std_ammo 500
+set g_turrets_unit_minigun_std_ammo_recharge 100
+
+set g_turrets_unit_minigun_std_aim_firetolerance_dist 128
+set g_turrets_unit_minigun_std_aim_firetolerance_angle 16
+set g_turrets_unit_minigun_std_aim_speed 32
+set g_turrets_unit_minigun_std_aim_maxrot 400
+set g_turrets_unit_minigun_std_aim_maxpitch 25
+
+set g_turrets_unit_minigun_std_track_type 1
+set g_turrets_unit_minigun_std_track_accel_pitch 0.25
+set g_turrets_unit_minigun_std_track_accel_rot 0.75
+set g_turrets_unit_minigun_std_track_blendrate 0.25
+
+

Copied: branches/nexuiz-2.0/data/unit_mlrs.cfg (from rev 3866, trunk/data/unit_mlrs.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_mlrs.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_mlrs.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,37 @@
+set g_turrets_unit_mlrs_std_health 350	
+set g_turrets_unit_mlrs_std_respawntime 60
+
+set g_turrets_unit_mlrs_std_shot_dmg 50
+set g_turrets_unit_mlrs_std_shot_refire 0.2
+set g_turrets_unit_mlrs_std_shot_radius 250
+set g_turrets_unit_mlrs_std_shot_speed 2000
+set g_turrets_unit_mlrs_std_shot_spread 0.05
+set g_turrets_unit_mlrs_std_shot_force 150
+set g_turrets_unit_mlrs_std_shot_volly 6
+set g_turrets_unit_mlrs_std_shot_volly_refire 5
+
+set g_turrets_unit_mlrs_std_target_range 4000
+set g_turrets_unit_mlrs_std_target_range_min 500
+set g_turrets_unit_mlrs_std_target_range_fire 3000
+set g_turrets_unit_mlrs_std_target_range_optimal 2000
+
+set g_turrets_unit_mlrs_std_target_select_rangebias 0.25
+set g_turrets_unit_mlrs_std_target_select_samebias 0.25
+set g_turrets_unit_mlrs_std_target_select_anglebias 0.5
+set g_turrets_unit_mlrs_std_target_select_playerbias 1
+set g_turrets_unit_mlrs_std_target_select_missilebias 0
+
+set g_turrets_unit_mlrs_std_ammo_max 350
+set g_turrets_unit_mlrs_std_ammo 310
+set g_turrets_unit_mlrs_std_ammo_recharge 60
+
+set g_turrets_unit_mlrs_std_aim_firetolerance_dist 200
+set g_turrets_unit_mlrs_std_aim_firetolerance_angle 15
+set g_turrets_unit_mlrs_std_aim_speed 100
+set g_turrets_unit_mlrs_std_aim_maxrot 360
+set g_turrets_unit_mlrs_std_aim_maxpitch 15
+
+set g_turrets_unit_mlrs_std_track_type 3
+set g_turrets_unit_mlrs_std_track_accel_pitch 0.25
+set g_turrets_unit_mlrs_std_track_accel_rot 0.75
+set g_turrets_unit_mlrs_std_track_blendrate 0.25
\ No newline at end of file

Copied: branches/nexuiz-2.0/data/unit_phaser.cfg (from rev 3866, trunk/data/unit_phaser.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_phaser.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_phaser.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,40 @@
+set g_turrets_unit_phaser_std_health 500
+
+set g_turrets_unit_phaser_std_respawntime 90
+
+set g_turrets_unit_phaser_std_shot_dmg 100
+set g_turrets_unit_phaser_std_shot_refire 4
+set g_turrets_unit_phaser_std_shot_radius 8
+set g_turrets_unit_phaser_std_shot_speed 4 // Used for how long to sustain the beam for this turret (seconds)
+set g_turrets_unit_phaser_std_shot_spread 0
+set g_turrets_unit_phaser_std_shot_force 5
+set g_turrets_unit_phaser_std_shot_volly 0
+set g_turrets_unit_phaser_std_shot_volly_refire 5
+
+set g_turrets_unit_phaser_std_target_range 3000
+set g_turrets_unit_phaser_std_target_range_min 0
+set g_turrets_unit_phaser_std_target_range_fire 3000
+set g_turrets_unit_phaser_std_target_range_optimal 1500
+
+set g_turrets_unit_phaser_std_target_select_rangebias 0.85
+set g_turrets_unit_phaser_std_target_select_samebias 0
+set g_turrets_unit_phaser_std_target_select_anglebias 0.25
+set g_turrets_unit_phaser_std_target_select_playerbias 1
+set g_turrets_unit_phaser_std_target_select_missilebias 0
+
+set g_turrets_unit_phaser_std_ammo_max 2000
+set g_turrets_unit_phaser_std_ammo 1000
+set g_turrets_unit_phaser_std_ammo_recharge 100
+
+set g_turrets_unit_phaser_std_aim_firetolerance_dist 100
+set g_turrets_unit_phaser_std_aim_firetolerance_angle 20
+
+set g_turrets_unit_phaser_std_aim_speed 100
+set g_turrets_unit_phaser_std_aim_maxrot 360
+set g_turrets_unit_phaser_std_aim_maxpitch 30
+
+set g_turrets_unit_phaser_std_track_type 3
+set g_turrets_unit_phaser_std_track_accel_pitch 0.5
+set g_turrets_unit_phaser_std_track_accel_rot 0.9
+set g_turrets_unit_phaser_std_track_blendrate 0.1
+

Copied: branches/nexuiz-2.0/data/unit_plasma.cfg (from rev 3866, trunk/data/unit_plasma.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_plasma.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_plasma.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,68 @@
+set g_turrets_unit_plasma_std_health 500	
+set g_turrets_unit_plasma_std_respawntime 60
+
+// Do this mutch damage
+set g_turrets_unit_plasma_std_shot_dmg 60
+//This often
+set g_turrets_unit_plasma_std_shot_refire 0.7
+//Over this mutch area
+set g_turrets_unit_plasma_std_shot_radius 150
+//Traveling at this speed
+set g_turrets_unit_plasma_std_shot_speed 6000
+//With a random direction of
+set g_turrets_unit_plasma_std_shot_spread 0.0125
+//Pushing things this hard
+set g_turrets_unit_plasma_std_shot_force 100
+//Each volly is this many shots
+set g_turrets_unit_plasma_std_shot_volly 1
+// Refire upon compleated volly
+set g_turrets_unit_plasma_std_shot_volly_refire 0.7
+
+// Scan for targets within this range
+set g_turrets_unit_plasma_std_target_range 4000
+// But no close then this
+set g_turrets_unit_plasma_std_target_range_min 240
+// If thise or closer, fire
+set g_turrets_unit_plasma_std_target_range_fire 3800
+// If we have a choise, prefer the ones closer to this distance
+set g_turrets_unit_plasma_std_target_range_optimal 2000
+
+
+// Targetselect is made for each turret based on range, angle (turrets needs to turn to aim at), if its a player / missile
+// scale range score this mucth
+set g_turrets_unit_plasma_std_target_select_rangebias 0.25
+// scale 'same' score this mutch (stick with same target)
+set g_turrets_unit_plasma_std_target_select_samebias 0.25
+// and so on
+set g_turrets_unit_plasma_std_target_select_anglebias 0.5
+set g_turrets_unit_plasma_std_target_select_playerbias 1
+set g_turrets_unit_plasma_std_target_select_missilebias 0
+
+// Can catty this mutch ammo. one dmg = one ammo
+set g_turrets_unit_plasma_std_ammo_max 600
+// Start with this mutch ammo
+set g_turrets_unit_plasma_std_ammo 300
+// Regain ammo this fast (per sec)
+set g_turrets_unit_plasma_std_ammo_recharge 30
+
+// If predicted emeypos is this or closer to predicted impact, fire is ok
+set g_turrets_unit_plasma_std_aim_firetolerance_dist 256
+// If angle ofset to predicted emeypos is this or less, fire is ok
+set g_turrets_unit_plasma_std_aim_firetolerance_angle 10
+// Aim how fast (for g_turrets_unit_plasma_std_track_type=1 this is dgr/sec, for 2 & 3 its the maximum force added each sec)
+set g_turrets_unit_plasma_std_aim_speed 250
+// Max rottation of head
+set g_turrets_unit_plasma_std_aim_maxrot 360
+// Max tilt of head
+set g_turrets_unit_plasma_std_aim_maxpitch 25
+
+// How the head turns. 
+//   1 = hard steps, good for aiming preformace, bad for visuals. 
+//   2 = smooth w/o inertia
+//   3 = smmoth with simulated inertia
+set g_turrets_unit_plasma_std_track_type 3
+// Following controls how _track_type = 3 works.
+set g_turrets_unit_plasma_std_track_accel_pitch 0.4
+set g_turrets_unit_plasma_std_track_accel_rot 0.4
+set g_turrets_unit_plasma_std_track_blendrate 0.35
+

Copied: branches/nexuiz-2.0/data/unit_plasma2.cfg (from rev 3866, trunk/data/unit_plasma2.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_plasma2.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_plasma2.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,40 @@
+set g_turrets_unit_plasma_dual_health 500	
+set g_turrets_unit_plasma_dual_respawntime 60
+
+set g_turrets_unit_plasma_dual_shot_dmg 50
+set g_turrets_unit_plasma_dual_shot_refire 0.3
+set g_turrets_unit_plasma_dual_shot_radius 100
+set g_turrets_unit_plasma_dual_shot_speed 5000
+set g_turrets_unit_plasma_dual_shot_spread 0.015
+set g_turrets_unit_plasma_dual_shot_force 100
+
+set g_turrets_unit_plasma_dual_shot_volly 0
+set g_turrets_unit_plasma_dual_shot_volly_refire 0.5
+
+set g_turrets_unit_plasma_dual_target_range 4000
+set g_turrets_unit_plasma_dual_target_range_min 100
+set g_turrets_unit_plasma_dual_target_range_fire 3000
+set g_turrets_unit_plasma_dual_target_range_optimal 1600
+
+set g_turrets_unit_plasma_dual_target_select_rangebias 0.25
+set g_turrets_unit_plasma_dual_target_select_samebias 0.25
+set g_turrets_unit_plasma_dual_target_select_anglebias 0.5
+set g_turrets_unit_plasma_dual_target_select_playerbias 1
+set g_turrets_unit_plasma_dual_target_select_missilebias 0
+
+set g_turrets_unit_plasma_dual_ammo_max 500
+set g_turrets_unit_plasma_dual_ammo 250
+set g_turrets_unit_plasma_dual_ammo_recharge 50
+
+set g_turrets_unit_plasma_dual_aim_firetolerance_dist 150
+set g_turrets_unit_plasma_dual_aim_firetolerance_angle 16
+
+set g_turrets_unit_plasma_dual_aim_speed 50
+set g_turrets_unit_plasma_dual_aim_maxrot 360
+set g_turrets_unit_plasma_dual_aim_maxpitch 15
+
+set g_turrets_unit_plasma_dual_track_type 3
+set g_turrets_unit_plasma_dual_track_accel_pitch 0.25
+set g_turrets_unit_plasma_dual_track_accel_rot 0.75
+set g_turrets_unit_plasma_dual_track_blendrate 0.5
+

Copied: branches/nexuiz-2.0/data/unit_tesla.cfg (from rev 3866, trunk/data/unit_tesla.cfg)
===================================================================
--- branches/nexuiz-2.0/data/unit_tesla.cfg	                        (rev 0)
+++ branches/nexuiz-2.0/data/unit_tesla.cfg	2008-07-21 14:44:04 UTC (rev 3868)
@@ -0,0 +1,18 @@
+set g_turrets_unit_tesla_std_health 1000	
+set g_turrets_unit_tesla_std_respawntime 120
+
+set g_turrets_unit_tesla_std_shot_dmg 100
+set g_turrets_unit_tesla_std_shot_refire 0.5
+set g_turrets_unit_tesla_std_shot_force 400
+
+set g_turrets_unit_tesla_std_shot_volly 1
+set g_turrets_unit_tesla_std_shot_volly_refire 2.5
+
+set g_turrets_unit_tesla_std_target_range 1024
+
+set g_turrets_unit_tesla_std_target_select_playerbias 1
+set g_turrets_unit_tesla_std_target_select_missilebias 1
+
+set g_turrets_unit_tesla_std_ammo_max 5000
+set g_turrets_unit_tesla_std_ammo 2500
+set g_turrets_unit_tesla_std_ammo_recharge 100




More information about the nexuiz-commits mailing list