]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/client/View.qc
fix warnings
[xonotic/xonotic-data.pk3dir.git] / qcsrc / client / View.qc
index 0226b0c35bb2e3b9af0f03c5e61c09616c9bde5f..8198639a4c686174d763eb284ccc8a2f17c48bb4 100644 (file)
-#define spider_rocket_icon "gfx/vehicles/rocket_ico.tga"\r
-#define spider_rocket_targ "gfx/vehicles/target.tga"\r
-#define SPIDER_CROSS "textures/spiderbot/cross.tga"\r
-#define rkt_size 32\r
-#define rld_size_x 256\r
-#define rld_size_y 16\r
-\r
-void CSQC_WAKIZASHI_HUD();\r
-\r
-entity porto;\r
-vector polyline[16];\r
-float trace_dphitcontents;\r
-float trace_networkentity;\r
-float Q3SURFACEFLAG_SLICK = 2; // low friction surface\r
-float DPCONTENTS_SOLID = 1; // blocks player movement\r
-float DPCONTENTS_BODY = 32; // blocks player movement\r
-float DPCONTENTS_CORPSE = 64; // blocks player movement\r
-float DPCONTENTS_PLAYERCLIP = 256; // blocks player movement\r
-void Porto_Draw()\r
-{\r
-       vector p, dir, ang, q, nextdir;\r
-       float idx, portal_number, portal1_idx;\r
-\r
-       if(activeweapon != WEP_PORTO || spectatee_status || gametype == GAME_NEXBALL)\r
-               return;\r
-       if(intermission == 1)\r
-               return;\r
-       if(intermission == 2)\r
-               return;\r
-       if (getstati(STAT_HEALTH) <= 0)\r
-               return;\r
-\r
-       dir = view_forward;\r
-\r
-       if(angles_held_status)\r
-       {\r
-               makevectors(angles_held);\r
-               dir = v_forward;\r
-       }\r
-\r
-       p = view_origin;\r
-\r
-       polyline[0] = p;\r
-       idx = 1;\r
-       portal_number = 0;\r
-       nextdir = dir;\r
-\r
-       for(;;)\r
-       {\r
-               dir = nextdir;\r
-               traceline(p, p + 65536 * dir, TRUE, porto);\r
-               if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)\r
-                       return;\r
-               nextdir = dir - 2 * (dir * trace_plane_normal) * trace_plane_normal; // mirror dir at trace_plane_normal\r
-               p = trace_endpos;\r
-               polyline[idx] = p;\r
-               ++idx;\r
-               if(idx >= 16)\r
-                       return;\r
-               if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP)\r
-                       continue;\r
-               ++portal_number;\r
-               ang = vectoangles2(trace_plane_normal, dir);\r
-               ang_x = -ang_x;\r
-               makevectors(ang);\r
-               if(!CheckWireframeBox(porto, p - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward))\r
-                       return;\r
-               if(portal_number == 1)\r
-                       portal1_idx = idx;\r
-               if(portal_number >= 2)\r
-                       break;\r
-       }\r
-\r
-       while(idx >= 2)\r
-       {\r
-               p = polyline[idx-2];\r
-               q = polyline[idx-1];\r
-               if(idx == 2)\r
-                       p = p - view_up * 16;\r
-               if(idx-1 >= portal1_idx)\r
-               {\r
-                       Draw_CylindricLine(p, q, 4, "", 1, 0, '0 0 1', 0.5, DRAWFLAG_NORMAL);\r
-               }\r
-               else\r
-               {\r
-                       Draw_CylindricLine(p, q, 4, "", 1, 0, '1 0 0', 0.5, DRAWFLAG_NORMAL);\r
-               }\r
-               --idx;\r
-       }\r
-}\r
-\r
-/**\r
- * Checks whether the server initiated a map restart (stat_game_starttime changed)\r
- *\r
- * TODO: Use a better solution where a common shared entitiy is used that contains\r
- * timelimit, fraglimit and game_starttime! Requires engine changes (remove STAT_TIMELIMIT\r
- * and STAT_FRAGLIMIT to be auto-sent)\r
- */\r
-void CheckForGamestartChange() {\r
-       float startTime;\r
-       startTime = getstatf(STAT_GAMESTARTTIME);\r
-       if (previous_game_starttime != startTime) {\r
-               if ((time + 5.0) < startTime) {\r
-                       //if connecting to server while restart was active don't always play prepareforbattle\r
-                       sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/prepareforbattle.wav"), VOL_BASEVOICE, ATTN_NONE);\r
-               }\r
-               if (time < startTime) {\r
-                       restartAnnouncer = spawn();\r
-                       restartAnnouncer.think = restartAnnouncer_Think;\r
-                       restartAnnouncer.nextthink = startTime - floor(startTime - time); //synchronize nextthink to startTime\r
-               }\r
-       }\r
-       previous_game_starttime = startTime;\r
-}\r
-\r
-void Porto_Init()\r
-{\r
-       porto = spawn();\r
-       porto.classname = "porto";\r
-       porto.draw = Porto_Draw;\r
-       porto.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;\r
-}\r
-\r
-float drawtime;\r
-float avgspeed;\r
-vector GetCurrentFov(float fov)\r
-{\r
-       float zoomsensitivity, zoomspeed, zoomfactor, zoomdir, velocityzoom;\r
-\r
-       zoomsensitivity = cvar("cl_zoomsensitivity");\r
-       zoomfactor = cvar("cl_zoomfactor");\r
-       if(zoomfactor < 1 || zoomfactor > 16)\r
-               zoomfactor = 2.5;\r
-       zoomspeed = cvar("cl_zoomspeed");\r
-       if(zoomspeed >= 0)\r
-               if(zoomspeed < 0.5 || zoomspeed > 16)\r
-                       zoomspeed = 3.5;\r
-\r
-       zoomdir = button_zoom;\r
-       if(getstati(STAT_ACTIVEWEAPON) == WEP_NEX) // do NOT use switchweapon here\r
-               zoomdir += button_attack2;\r
-       if(spectatee_status > 0 || isdemo())\r
-       {\r
-               if(spectatorbutton_zoom)\r
-                       zoomdir = 0 + !zoomdir;\r
-               // do not even THINK about removing this 0\r
-               // _I_ know what I am doing\r
-               // fteqcc does not\r
-       }\r
-\r
-       if(zoomdir)\r
-               zoomin_effect = 0;\r
-\r
-       if(zoomin_effect || camera_active)\r
-       {\r
-               current_viewzoom = min(1, current_viewzoom + drawframetime);\r
-       }\r
-       else\r
-       {\r
-               if(zoomspeed < 0) // instant zoom\r
-               {\r
-                       if(zoomdir)\r
-                               current_viewzoom = 1 / zoomfactor;\r
-                       else\r
-                               current_viewzoom = 1;\r
-               }\r
-               else\r
-               {\r
-                       if(zoomdir)\r
-                               current_viewzoom = 1 / bound(1, 1 / current_viewzoom + drawframetime * zoomspeed * (zoomfactor - 1), zoomfactor);\r
-                       else\r
-                               current_viewzoom = bound(1 / zoomfactor, current_viewzoom + drawframetime * zoomspeed * (1 - 1 / zoomfactor), 1);\r
-               }\r
-       }\r
-\r
-       if(almost_equals(current_viewzoom, 1))\r
-               current_zoomfraction = 0;\r
-       else if(almost_equals(current_viewzoom, 1/zoomfactor))\r
-               current_zoomfraction = 1;\r
-       else\r
-               current_zoomfraction = (current_viewzoom - 1) / (1/zoomfactor - 1);\r
-\r
-       if(zoomsensitivity < 1)\r
-               setsensitivityscale(pow(current_viewzoom, 1 - zoomsensitivity));\r
-       else\r
-               setsensitivityscale(1);\r
-\r
-       velocityzoom = bound(0, drawframetime / max(0.000000001, cvar_or("cl_velocityzoomtime", 0.3)), 1);\r
-       avgspeed = avgspeed * (1 - velocityzoom) + (vlen(pmove_vel) / 1000) * velocityzoom;\r
-       velocityzoom = exp(float2range11(avgspeed * -cvar_or("cl_velocityzoom", 0) / 1) * 1);\r
-\r
-       //print(ftos(avgspeed), " avgspeed, ", ftos(cvar_or("cl_velocityzoom", 0)), " cvar, ", ftos(velocityzoom), " return\n"); // for debugging\r
-\r
-       float frustumx, frustumy, fovx, fovy;\r
-       frustumy = tan(fov * M_PI / 360.0) * 0.75 * current_viewzoom * velocityzoom;\r
-       frustumx = frustumy * vid_width / vid_height / vid_pixelheight;\r
-       fovx = atan2(frustumx, 1) / M_PI * 360.0;\r
-       fovy = atan2(frustumy, 1) / M_PI * 360.0;\r
-\r
-       return '1 0 0' * fovx + '0 1 0' * fovy;\r
-}\r
-\r
-// this function must match W_SetupShot!\r
-float zoomscript_caught;\r
-\r
-vector wcross_origin;\r
-float wcross_scale_prev, wcross_alpha_prev;\r
-vector wcross_color_prev;\r
-float wcross_scale_goal_prev, wcross_alpha_goal_prev;\r
-vector wcross_color_goal_prev;\r
-float wcross_changedonetime;\r
-\r
-string wcross_name_goal_prev, wcross_name_goal_prev_prev;\r
-float wcross_resolution_goal_prev, wcross_resolution_goal_prev_prev;\r
-float wcross_name_changestarttime, wcross_name_changedonetime;\r
-float wcross_name_alpha_goal_prev, wcross_name_alpha_goal_prev_prev;\r
-entity trueaim;\r
-entity trueaim_rifle;\r
-\r
-#define SHOTTYPE_HITTEAM 1\r
-#define SHOTTYPE_HITOBSTRUCTION 2\r
-#define SHOTTYPE_HITWORLD 3\r
-#define SHOTTYPE_HITENEMY 4\r
-\r
-void TrueAim_Init()\r
-{\r
-       trueaim = spawn();\r
-       trueaim.classname = "trueaim";\r
-       trueaim.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;\r
-       trueaim_rifle = spawn();\r
-       trueaim_rifle.classname = "trueaim_rifle";\r
-       trueaim_rifle.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE;\r
-}\r
-\r
-float EnemyHitCheck()\r
-{\r
-       float t;\r
-       wcross_origin = project_3d_to_2d(trace_endpos);\r
-       wcross_origin_z = 0;\r
-       if(trace_networkentity < 1)\r
-               return SHOTTYPE_HITWORLD;\r
-       if(trace_networkentity > maxclients)\r
-               return SHOTTYPE_HITWORLD;\r
-       t = GetPlayerColor(trace_networkentity - 1);\r
-       if(teamplay)\r
-               if(t == myteam)\r
-                       return SHOTTYPE_HITTEAM;\r
-       if(t == COLOR_SPECTATOR)\r
-               return SHOTTYPE_HITWORLD;\r
-       return SHOTTYPE_HITENEMY;\r
-}\r
-\r
-float TrueAimCheck()\r
-{\r
-       float nudge = 1; // added to traceline target and subtracted from result\r
-       vector vecs, trueaimpoint, w_shotorg;\r
-       vector mi, ma, dv;\r
-       float shottype;\r
-       entity ta;\r
-       float mv;\r
-\r
-       mi = ma = '0 0 0';\r
-       ta = trueaim;\r
-       mv = MOVE_NOMONSTERS;\r
-\r
-       switch(activeweapon)\r
-       {\r
-               case WEP_TUBA: // no aim\r
-               case WEP_PORTO: // shoots from eye\r
-               case WEP_HOOK: // no trueaim\r
-               case WEP_GRENADE_LAUNCHER: // toss curve\r
-                       return SHOTTYPE_HITWORLD;\r
-               case WEP_NEX:\r
-               case WEP_MINSTANEX:\r
-                       mv = MOVE_NORMAL;\r
-                       break;\r
-               case WEP_CAMPINGRIFLE:\r
-                       ta = trueaim_rifle;\r
-                       mv = MOVE_NORMAL;\r
-                       if(zoomscript_caught)\r
-                       {\r
-                               tracebox(view_origin, '0 0 0', '0 0 0', view_origin + view_forward * MAX_SHOT_DISTANCE, mv, ta);\r
-                               return EnemyHitCheck();\r
-                       }\r
-                       break;\r
-               case WEP_ROCKET_LAUNCHER: // projectile has a size!\r
-                       mi = '-3 -3 -3';\r
-                       ma = '3 3 3';\r
-                       break;\r
-               case WEP_FIREBALL: // projectile has a size!\r
-                       mi = '-16 -16 -16';\r
-                       ma = '16 16 16';\r
-                       break;\r
-               case WEP_ELECTRO: // projectile has a size!\r
-                       mi = '0 0 -3';\r
-                       ma = '0 0 -3';\r
-                       break;\r
-       }\r
-\r
-       vecs = decompressShotOrigin(getstati(STAT_SHOTORG));\r
-\r
-       traceline(view_origin, view_origin + view_forward * MAX_SHOT_DISTANCE, mv, ta);\r
-       trueaimpoint = trace_endpos;\r
-\r
-       if(vecs_x > 0)\r
-               vecs_y = -vecs_y;\r
-       else\r
-               vecs = '0 0 0';\r
-\r
-       dv = view_right * vecs_y + view_up * vecs_z;\r
-       w_shotorg = view_origin + dv;\r
-\r
-       // now move the vecs forward as much as requested if possible\r
-       tracebox(w_shotorg, mi, ma, w_shotorg + view_forward * (vecs_x + nudge), MOVE_NORMAL, ta); // FIXME this MOVE_NORMAL part will misbehave a little in csqc\r
-       w_shotorg = trace_endpos - view_forward * nudge;\r
-\r
-       tracebox(w_shotorg, mi, ma, trueaimpoint, MOVE_NORMAL, ta);\r
-       shottype = EnemyHitCheck();\r
-       if(shottype != SHOTTYPE_HITWORLD)\r
-               return shottype;\r
-\r
-#if 0\r
-       // FIXME WHY DOES THIS NOT WORK FOR THE ROCKET LAUNCHER?\r
-       // or rather, I know why, but see no fix\r
-       if(vlen(trace_endpos - trueaimpoint) > vlen(ma) + vlen(mi) + 1)\r
-               // yes, this is an ugly hack... but it seems good enough to find out whether the test hits the same place as the initial trace\r
-               return SHOTTYPE_HITOBSTRUCTION;\r
-#endif\r
-\r
-       return SHOTTYPE_HITWORLD;\r
-}\r
-\r
-void CSQC_common_hud(void);\r
-\r
-void CSQC_kh_hud(void);\r
-void CSQC_ctf_hud(void);\r
-void PostInit(void);\r
-void CSQC_Demo_Camera();\r
-float Sbar_WouldDrawScoreboard ();\r
-float view_set;\r
-float camera_mode;\r
-string NextFrameCommand;\r
-void CSQC_SPIDER_HUD();\r
-void CSQC_RAPTOR_HUD();\r
-\r
-void CSQC_UpdateView(float w, float h)\r
-{\r
-       entity e;\r
-       float fov;\r
-       float f, i, j;\r
-       vector v, vo;\r
-\r
-       WaypointSprite_Load();\r
-\r
-       if(spectatee_status)\r
-               myteam = GetPlayerColor(spectatee_status - 1);\r
-       else\r
-               myteam = GetPlayerColor(player_localentnum - 1);\r
-\r
-       ticrate = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);\r
-       vo = '0 0 1' * getstati(STAT_VIEWHEIGHT);\r
-\r
-       warpzone_fixview_origin = pmove_org + vo;\r
-       warpzone_fixview_angles = input_angles;\r
-       WarpZone_FixView();\r
-       pmove_org = warpzone_fixview_origin - vo;\r
-       input_angles = warpzone_fixview_angles;\r
-\r
-       // Render the Scene\r
-       if(!intermission || !view_set)\r
-       {\r
-               view_origin = pmove_org + vo;\r
-               view_angles = input_angles;\r
-               makevectors(view_angles);\r
-               view_forward = v_forward;\r
-               view_right = v_right;\r
-               view_up = v_up;\r
-               view_set = 1;\r
-       }\r
-\r
-       vid_width = w;\r
-       vid_height = h;\r
-\r
-#ifdef BLURTEST\r
-       if(time > blurtest_time0 && time < blurtest_time1)\r
-       {\r
-               float r, t;\r
-\r
-               t = (time - blurtest_time0) / (blurtest_time1 - blurtest_time0);\r
-               r = t * blurtest_radius;\r
-               f = 1 / pow(t, blurtest_power) - 1;\r
-\r
-               cvar_set("r_glsl_postprocess", "1");\r
-               cvar_set("r_glsl_postprocess_uservec1", strcat(ftos(r), " ", ftos(f), " 0 0"));\r
-       }\r
-       else\r
-       {\r
-               cvar_set("r_glsl_postprocess", "0");\r
-               cvar_set("r_glsl_postprocess_uservec1", "0 0 0 0");\r
-       }\r
-#endif\r
-\r
-       Fog_Force();\r
-\r
-       drawframetime = max(0.000001, time - drawtime);\r
-       drawtime = time;\r
-\r
-       // watch for gametype changes here...\r
-       // in ParseStuffCMD the cmd isn't executed yet :/\r
-       // might even be better to add the gametype to TE_CSQC_INIT...?\r
-       if(!postinit)\r
-               PostInit();\r
-\r
-       if(intermission && !isdemo() && !(calledhooks & HOOK_END))\r
-               if(calledhooks & HOOK_START)\r
-               {\r
-                       localcmd("\ncl_hook_gameend;");\r
-                       calledhooks |= HOOK_END;\r
-               }\r
-\r
-       CheckForGamestartChange();\r
-       serverAnnouncer();\r
-       maptimeAnnouncer();\r
-       carrierAnnouncer();\r
-\r
-       fov = cvar("fov");\r
-       if(button_zoom || fov <= 59.5)\r
-       {\r
-               if(!zoomscript_caught)\r
-               {\r
-                       localcmd("+button4\n");\r
-                       zoomscript_caught = 1;\r
-                       ignore_plus_zoom += 1;\r
-               }\r
-       }\r
-       else\r
-       {\r
-               if(zoomscript_caught)\r
-               {\r
-                       localcmd("-button4\n");\r
-                       zoomscript_caught = 0;\r
-                       ignore_minus_zoom += 1;\r
-               }\r
-       }\r
-\r
-       sbar_alpha_fg = cvar("sbar_alpha_fg" ) * (1 - cvar("_menu_alpha"));\r
-       sbar_currentammo = cvar("sbar_showcurrentammo");\r
-       sbar_hudselector = cvar("sbar_hudselector");\r
-       sbar_accuracy_hud = cvar_or("sbar_accuracy_hud", 1);\r
-       ColorTranslateMode = cvar("cl_stripcolorcodes");\r
-       activeweapon = getstati(STAT_SWITCHWEAPON);\r
-       f = cvar("teamplay");\r
-       if(f != teamplay)\r
-       {\r
-               teamplay = f;\r
-               Sbar_InitScores();\r
-       }\r
-\r
-       if(last_weapon != activeweapon) {\r
-               weapontime = time;\r
-               last_weapon = activeweapon;\r
-       }\r
-\r
-       // ALWAYS Clear Current Scene First\r
-       R_ClearScene();\r
-\r
-       // Assign Standard Viewflags\r
-       // Draw the World (and sky)\r
-       R_SetView(VF_DRAWWORLD, 1);\r
-\r
-       // Set the console size vars\r
-       vid_conwidth = cvar("vid_conwidth");\r
-       vid_conheight = cvar("vid_conheight");\r
-       vid_pixelheight = cvar("vid_pixelheight");\r
-\r
-       R_SetView(VF_FOV, GetCurrentFov(fov));\r
-\r
-       // Camera for demo playback\r
-       if(camera_active)\r
-       {\r
-               if(cvar("camera_enable"))\r
-                       CSQC_Demo_Camera();\r
-               else\r
-               {\r
-                       cvar_set("chase_active", ftos(chase_active_backup));\r
-                       cvar_set("cl_demo_mousegrab", "0");\r
-                       camera_active = FALSE;\r
-               }\r
-       }\r
-#ifdef CAMERATEST\r
-       else if(cvar("camera_enable"))\r
-#else\r
-       else if(cvar("camera_enable") && isdemo())\r
-#endif\r
-       {\r
-               // Enable required Darkplaces cvars\r
-               chase_active_backup = cvar("chase_active");\r
-               cvar_set("chase_active", "2");\r
-               cvar_set("cl_demo_mousegrab", "1");\r
-               camera_active = TRUE;\r
-               camera_mode = FALSE;\r
-       }\r
-\r
-       // Draw the Crosshair\r
-       float scoreboard_active;\r
-       scoreboard_active = Sbar_WouldDrawScoreboard();\r
-       R_SetView(VF_DRAWCROSSHAIR, 0); //Make sure engine crosshairs are always hidden\r
-\r
-       // Draw the Engine Status Bar (the default Quake HUD)\r
-       R_SetView(VF_DRAWENGINESBAR, 0);\r
-\r
-       // fetch this one only once per frame\r
-       sbar_showbinds = cvar("sbar_showbinds");\r
-       sbar_showbinds_limit = cvar("sbar_showbinds_limit");\r
-\r
-       // Update the mouse position\r
-       /*\r
-          mousepos_x = vid_conwidth;\r
-          mousepos_y = vid_conheight;\r
-          mousepos = mousepos*0.5 + getmousepos();\r
-        */\r
-\r
-       e = self;\r
-       for(self = world; (self = nextent(self)); )\r
-               if(self.draw)\r
-                       self.draw();\r
-       self = e;\r
-\r
-       R_AddEntities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);\r
-       R_RenderScene();\r
-\r
-       // now switch to 2D drawing mode by calling a 2D drawing function\r
-       // then polygon drawing will draw as 2D stuff, and NOT get queued until the\r
-       // next R_RenderScene call\r
-       drawstring('0 0 0', "", '1 1 0', '1 1 1', 0, 0);\r
-\r
-       // Draw the mouse cursor\r
-       // NOTE: drawpic must happen after R_RenderScene for some reason\r
-       //drawpic(getmousepos(), "gfx/cursor.tga", '11 14 0', '1 1 1', 1, 0);\r
-       //drawstring('50 50', ftos(game), '10 10 0', '1 1 1', 1, 0);\r
-       //self = edict_num(player_localnum);\r
-       //drawstring('0 0', vtos(pmove_org), '8 8 0', '1 1 1', 1, 0);\r
-       //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);\r
-       // as long as the ctf part isn't in, this is useless\r
-       if(menu_visible)\r
-               menu_show();\r
-\r
-       /*if(gametype == GAME_CTF)\r
-         {\r
-         ctf_view();\r
-         } else */\r
-\r
-       // draw 2D entities\r
-       e = self;\r
-       for(self = world; (self = nextent(self)); )\r
-               if(self.draw2d)\r
-                       self.draw2d();\r
-       self = e;\r
-\r
-       // draw radar\r
-       if(\r
-                       ons_showmap\r
-                       ||\r
-                       (\r
-                        !scoreboard_active\r
-                        &&\r
-                        cvar_string("cl_teamradar") != "0"\r
-                        &&\r
-                        (\r
-                         cvar("cl_teamradar") == 2\r
-                         ||\r
-                         teamplay\r
-                        )\r
-                       )\r
-         )\r
-               teamradar_view();\r
-\r
-       // draw sbar\r
-       if(cvar("r_letterbox") == 0) {\r
-               if (cvar("cl_showpressedkeys")) { // draw pressed keys when spectating and playing\r
-                       if(spectatee_status > 0 || cvar("cl_showpressedkeys") >= 2)\r
-                               Sbar_DrawPressedKeys();\r
-               }\r
-\r
-               if (cvar("cl_showspeed"))\r
-                       Sbar_ShowSpeed();\r
-               if (cvar("cl_showacceleration"))\r
-                       Sbar_ShowAcceleration();\r
-\r
-               Sbar_DrawCenterPrint(); // draw centerprint messages even if viewsize >= 120\r
-       }\r
-\r
-       float hud;\r
-       hud = getstati(STAT_HUD);\r
-       if(hud == HUD_SPIDERBOT)\r
-       {\r
-               CSQC_SPIDER_HUD();\r
-       }\r
-       else if(hud == HUD_WAKIZASHI)\r
-        CSQC_WAKIZASHI_HUD();\r
-    else if(hud == HUD_RAPTOR)\r
-        CSQC_RAPTOR_HUD();\r
-       else\r
-       {\r
-               if(cvar("r_letterbox") == 0)\r
-                       if(cvar("viewsize") < 120)\r
-                               CSQC_common_hud();\r
-\r
-               // crosshair goes VERY LAST\r
-               if(!scoreboard_active && !ons_showmap && !camera_active) {\r
-                       // TrueAim check\r
-                       float shottype;\r
-                       float bullets, ring_scale;\r
-                       // wcross_origin = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;\r
-                       wcross_origin = project_3d_to_2d(view_origin + MAX_SHOT_DISTANCE * view_forward);\r
-                       wcross_origin_z = 0;\r
-                       if(cvar("crosshair_hittest"))\r
-                       {\r
-                               vector wcross_oldorigin;\r
-                               wcross_oldorigin = wcross_origin;\r
-                               shottype = TrueAimCheck();\r
-                               if(shottype == SHOTTYPE_HITWORLD)\r
-                               {\r
-                                       v = wcross_origin - wcross_oldorigin;\r
-                                       v_x /= vid_conwidth;\r
-                                       v_y /= vid_conheight;\r
-                                       if(vlen(v) > 0.01)\r
-                                               shottype = SHOTTYPE_HITOBSTRUCTION;\r
-                               }\r
-                               if(!cvar("crosshair_hittest_showimpact"))\r
-                                       wcross_origin = wcross_oldorigin;\r
-                       }\r
-                       else\r
-                               shottype = SHOTTYPE_HITWORLD;\r
-\r
-                       string wcross_style;\r
-                       wcross_style = cvar_string("crosshair");\r
-\r
-                       if (wcross_style != "0") {\r
-                               vector wcross_color, wcross_size;\r
-                               string wcross_wep, wcross_name;\r
-                               float wcross_alpha, wcross_scale, wcross_blur, wcross_resolution;\r
-\r
-                               wcross_color_x = cvar("crosshair_color_red");\r
-                               wcross_color_y = cvar("crosshair_color_green");\r
-                               wcross_color_z = cvar("crosshair_color_blue");\r
-                               wcross_alpha = cvar("crosshair_color_alpha");\r
-                               wcross_resolution = cvar("crosshair_size");\r
-                               if (cvar("crosshair_per_weapon")) {\r
-                                       e = get_weaponinfo(activeweapon);\r
-                                       if (e && e.netname != "")\r
-                                       {\r
-                                               wcross_wep = e.netname;\r
-                                               wcross_style = cvar_string(strcat("crosshair_", wcross_wep));\r
-                                               if(wcross_style == "")\r
-                                                       wcross_style = e.netname;\r
-\r
-                                               if(!cvar("crosshair_color_override"))\r
-                                               {\r
-                                                       wcross_color_x = cvar(strcat("crosshair_", wcross_wep, "_color_red"));\r
-                                                       wcross_color_y = cvar(strcat("crosshair_", wcross_wep, "_color_green"));\r
-                                                       wcross_color_z = cvar(strcat("crosshair_", wcross_wep, "_color_blue"));\r
-                                               }\r
-\r
-                                               wcross_alpha *= cvar(strcat("crosshair_", wcross_wep, "_color_alpha"));\r
-                                               wcross_resolution *= cvar(strcat("crosshair_", wcross_wep, "_size"));\r
-                                       }\r
-                               }\r
-\r
-                               wcross_name = strcat("gfx/crosshair", wcross_style);\r
-\r
-                               if(cvar("crosshair_effect_scalefade"))\r
-                               {\r
-                                       wcross_scale = wcross_resolution;\r
-                                       wcross_resolution = 1;\r
-                               }\r
-                               else\r
-                               {\r
-                                       wcross_scale = 1;\r
-                               }\r
-\r
-                               if(shottype == SHOTTYPE_HITENEMY)\r
-                                       wcross_scale *= cvar("crosshair_hittest"); // is not queried if hittest is 0\r
-                               if(shottype == SHOTTYPE_HITTEAM)\r
-                                       wcross_scale /= cvar("crosshair_hittest"); // is not queried if hittest is 0\r
-\r
-                               f = cvar("crosshair_effect_speed");\r
-                               if(f < 0)\r
-                                       f *= -2 * g_weaponswitchdelay;\r
-                               if(wcross_scale != wcross_scale_goal_prev || wcross_alpha != wcross_alpha_goal_prev || wcross_color != wcross_color_goal_prev)\r
-                               {\r
-                                       wcross_changedonetime = time + f;\r
-                               }\r
-                               if(wcross_name != wcross_name_goal_prev || wcross_resolution != wcross_resolution_goal_prev)\r
-                               {\r
-                                       wcross_name_changestarttime = time;\r
-                                       wcross_name_changedonetime = time + f;\r
-                                       if(wcross_name_goal_prev_prev)\r
-                                               strunzone(wcross_name_goal_prev_prev);\r
-                                       wcross_name_goal_prev_prev = wcross_name_goal_prev;\r
-                                       wcross_name_goal_prev = strzone(wcross_name);\r
-                                       wcross_name_alpha_goal_prev_prev = wcross_name_alpha_goal_prev;\r
-                                       wcross_resolution_goal_prev_prev = wcross_resolution_goal_prev;\r
-                                       wcross_resolution_goal_prev = wcross_resolution;\r
-                               }\r
-\r
-                               wcross_scale_goal_prev = wcross_scale;\r
-                               wcross_alpha_goal_prev = wcross_alpha;\r
-                               wcross_color_goal_prev = wcross_color;\r
-\r
-                               if(shottype == SHOTTYPE_HITTEAM || (shottype == SHOTTYPE_HITOBSTRUCTION && cvar("crosshair_hittest_blur") && !cvar("chase_active")))\r
-                               {\r
-                                       wcross_blur = 1;\r
-                                       wcross_alpha *= 0.75;\r
-                               }\r
-                               else\r
-                                       wcross_blur = 0;\r
-                               // *_prev is at time-frametime\r
-                               // * is at wcross_changedonetime+f\r
-                               // what do we have at time?\r
-                               if(time < wcross_changedonetime)\r
-                               {\r
-                                       f = frametime / (wcross_changedonetime - time + frametime);\r
-                                       wcross_scale = f * wcross_scale + (1 - f) * wcross_scale_prev;\r
-                                       wcross_alpha = f * wcross_alpha + (1 - f) * wcross_alpha_prev;\r
-                                       wcross_color = f * wcross_color + (1 - f) * wcross_color_prev;\r
-                               }\r
-\r
-                               wcross_scale_prev = wcross_scale;\r
-                               wcross_alpha_prev = wcross_alpha;\r
-                               wcross_color_prev = wcross_color;\r
-\r
-                               wcross_scale *= 1 - cvar("_menu_alpha");\r
-                               wcross_alpha *= 1 - cvar("_menu_alpha");\r
-\r
-                               // ring around crosshair representing bullets left in camping rifle clip\r
-                               if (activeweapon == WEP_CAMPINGRIFLE)\r
-                               {\r
-                                       ring_scale = cvar("crosshair_campingrifle_ring_size");\r
-                                       bullets = bound(0, getstati(STAT_BULLETS_LOADED), 8);\r
-                               }\r
-                               else\r
-                                       bullets = 0;\r
-\r
-#define CROSSHAIR_DRAW_RING(i,j,sz,wcross_name,wcross_alpha) \\r
-                               drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size_x * ring_scale + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size_y * ring_scale + j * wcross_blur)), strcat("gfx/hud/rifle_ring_", ftos(bullets)), sz * wcross_size * ring_scale, wcross_color, wcross_alpha, DRAWFLAG_NORMAL)\r
-\r
-#define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \\r
-                               do \\r
-                               { \\r
-                                       if(wcross_blur > 0) \\r
-                                       { \\r
-                                               for(i = -2; i <= 2; ++i) \\r
-                                                       for(j = -2; j <= 2; ++j) \\r
-                                                               M(i,j,sz,wcross_name,wcross_alpha*0.04); \\r
-                                       } \\r
-                                       else \\r
-                                       { \\r
-                                               M(0,0,sz,wcross_name,wcross_alpha); \\r
-                                       } \\r
-                               } \\r
-                               while(0)\r
-\r
-#define CROSSHAIR_DRAW_SINGLE(i,j,sz,wcross_name,wcross_alpha) \\r
-                               drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size_x + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size_y + j * wcross_blur)), wcross_name, sz * wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL)\r
-\r
-#define CROSSHAIR_DRAW(sz,wcross_name,wcross_alpha) \\r
-                               CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_SINGLE,sz,wcross_name,wcross_alpha)\r
-\r
-                               if(time < wcross_name_changedonetime && wcross_name != wcross_name_goal_prev_prev && wcross_name_goal_prev_prev)\r
-                               {\r
-                                       f = (wcross_name_changedonetime - time) / (wcross_name_changedonetime - wcross_name_changestarttime);\r
-                                       wcross_size = drawgetimagesize(wcross_name_goal_prev_prev) * wcross_scale;\r
-                                       CROSSHAIR_DRAW(wcross_resolution_goal_prev_prev, wcross_name_goal_prev_prev, wcross_alpha * f * wcross_name_alpha_goal_prev_prev);\r
-                                       f = 1 - f;\r
-                               }\r
-                               else\r
-                               {\r
-                                       f = 1;\r
-                               }\r
-\r
-                               wcross_size = drawgetimagesize(wcross_name) * wcross_scale;\r
-                               if(bullets)\r
-                               {\r
-                                       CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_RING, wcross_resolution, wcross_name, wcross_alpha);\r
-                               }\r
-                               CROSSHAIR_DRAW(wcross_resolution, wcross_name, wcross_alpha * f);\r
-                               wcross_name_alpha_goal_prev = f;\r
-                       }\r
-               }\r
-               else\r
-               {\r
-                       wcross_scale_prev = 0;\r
-                       wcross_alpha_prev = 0;\r
-                       wcross_scale_goal_prev = 0;\r
-                       wcross_alpha_goal_prev = 0;\r
-                       wcross_changedonetime = 0;\r
-                       if(wcross_name_goal_prev)\r
-                               strunzone(wcross_name_goal_prev);\r
-                       wcross_name_goal_prev = string_null;\r
-                       if(wcross_name_goal_prev_prev)\r
-                               strunzone(wcross_name_goal_prev_prev);\r
-                       wcross_name_goal_prev_prev = string_null;\r
-                       wcross_name_changestarttime = 0;\r
-                       wcross_name_changedonetime = 0;\r
-                       wcross_name_alpha_goal_prev = 0;\r
-                       wcross_name_alpha_goal_prev_prev = 0;\r
-                       wcross_resolution_goal_prev = 0;\r
-                       wcross_resolution_goal_prev_prev = 0;\r
-               }\r
-       }\r
-\r
-       if(NextFrameCommand)\r
-       {\r
-               localcmd("\n", NextFrameCommand, "\n");\r
-               NextFrameCommand = string_null;\r
-       }\r
-\r
-       // we must do this check AFTER a frame was rendered, or it won't work\r
-       if(cs_project_is_b0rked == 0)\r
-       {\r
-               string w0, h0;\r
-               w0 = cvar_string("vid_conwidth");\r
-               h0 = cvar_string("vid_conheight");\r
-               //R_SetView(VF_VIEWPORT, '0 0 0', '640 480 0');\r
-               //R_SetView(VF_FOV, '90 90 0');\r
-               R_SetView(VF_ORIGIN, '0 0 0');\r
-               R_SetView(VF_ANGLES, '0 0 0');\r
-               R_SetView(VF_PERSPECTIVE, 1);\r
-               makevectors('0 0 0');\r
-               vector v1, v2;\r
-               cvar_set("vid_conwidth", "800");\r
-               cvar_set("vid_conheight", "600");\r
-               v1 = cs_project(v_forward);\r
-               cvar_set("vid_conwidth", "640");\r
-               cvar_set("vid_conheight", "480");\r
-               v2 = cs_project(v_forward);\r
-               if(v1 == v2)\r
-                       cs_project_is_b0rked = 1;\r
-               else\r
-                       cs_project_is_b0rked = -1;\r
-               cvar_set("vid_conwidth", w0);\r
-               cvar_set("vid_conheight", h0);\r
-       }\r
-\r
-       // be safe against triggerbots until everyone has the fixed engine\r
-       // this call is meant to overwrite the trace globals by something\r
-       // unsuspicious\r
-       traceline('0 0 0', '0 0 0', MOVE_WORLDONLY, world);\r
-}\r
-\r
-void Sbar_Draw();\r
-#define spider_h "gfx/vehicles/hud_bg.tga"\r
-#define spider_b "gfx/vehicles/sbot.tga"\r
-#define spider_r "gfx/vehicles/sbot_rpods.tga"\r
-#define spider_g "gfx/vehicles/sbot_mguns.tga"\r
-#define spider_s "gfx/vehicles/shiled.tga"\r
-\r
-#define spider_a1 "gfx/hud/sb_rocket.tga"\r
-#define spider_a2 "gfx/sb_bullets.tga"\r
-\r
-void CSQC_SPIDER_HUD()\r
-{\r
-       float rockets, reload, heat, hp, shield;\r
-       vector picsize, hudloc;\r
-\r
-    // Fetch health & ammo stats\r
-    hp      = bound(0,getstatf(STAT_VEHICLESTAT_HEALTH), 1);\r
-       shield  = bound(0,getstatf(STAT_VEHICLESTAT_SHIELD), 1);\r
-       heat    = min(getstatf(STAT_VEHICLESTAT_RELOAD1), 2);\r
-       rockets =     getstati(STAT_VEHICLESTAT_AMMO2);\r
-       reload  = min(getstatf(STAT_VEHICLESTAT_RELOAD2), 1);\r
-\r
-    // Draw the crosshairs\r
-    picsize = drawgetimagesize(SPIDER_CROSS);\r
-    picsize_x *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);\r
-    picsize_y *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);\r
-    drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), SPIDER_CROSS, picsize, '1 1 1', cvar_or("cl_vehicle_spiderbot_cross_alpha",0.6), DRAWFLAG_NORMAL);\r
-\r
-    hudloc_y =  4;\r
-    hudloc_x = 4;\r
-\r
-    picsize = drawgetimagesize(spider_h) * 0.5;\r
-    drawpic(hudloc, spider_h, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-\r
-    picsize = drawgetimagesize(spider_a2) * 0.5;\r
-    drawpic(hudloc + '120 96  0', spider_a2, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-\r
-    drawstring(hudloc + '145 19  0', strcat(ftos(rint(hp * 100)), "%"),'15 15 0','0 1 0', 1, DRAWFLAG_NORMAL);\r
-    drawstring(hudloc + '175 34  0', strcat(ftos(rint(shield * 100)), "%"),'15 15 0','0 0 1', 1, DRAWFLAG_NORMAL);\r
-    drawstring(hudloc + '136 102  0', strcat(ftos(100 - rint(heat * 100)), "%"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);\r
-\r
-    picsize = drawgetimagesize(spider_a1) * 0.85;\r
-    if(rockets == 9)\r
-    {\r
-        drawpic(hudloc + '132 54  0', spider_a1, picsize, '-1 -1 -1', 1, DRAWFLAG_NORMAL);\r
-        drawstring(hudloc + '179 69 0', strcat(ftos(rint(reload * 100)), "%"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);\r
-    }\r
-    else\r
-    {\r
-        drawpic(hudloc + '132 54  0', spider_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-        drawstring(hudloc + '179 69  0', strcat(ftos(9 - rockets), "/8"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);\r
-    }\r
-\r
-    picsize = drawgetimagesize(spider_b) * 0.5;\r
-    hudloc_y = 10.5;\r
-    hudloc_x = 10.5;\r
-\r
-    drawpic(hudloc, spider_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);\r
-    drawpic(hudloc, spider_b, picsize, '0 1 0' * hp + '1 0 0' * (1 - hp), 1, DRAWFLAG_NORMAL);\r
-    drawpic(hudloc, spider_r, picsize, '1 1 1' * reload + '1 0 0' * (1 - reload), 1, DRAWFLAG_NORMAL);\r
-    drawpic(hudloc, spider_g, picsize, '1 1 1' * (1 - heat) + '1 0 0' *  heat, 1, DRAWFLAG_NORMAL);\r
-\r
-\r
-       /*\r
-       // Draw health bar\r
-       p = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));\r
-       p = p + '0 1 0' * vid_conheight - '0 32 0';\r
-       //pp = ('0 1 0' * hp) + ('1 0 0' * (1-hp));\r
-       drawfill(p, '256 0 0' * shield + '0 8 0' , '0.5 0.5 1', 0.75, DRAWFLAG_NORMAL);\r
-       p_y += 8;\r
-       drawfill(p, '256 0 0' * hp + '0 8 0' , '0 1 0', 0.75, DRAWFLAG_NORMAL);\r
-       p_x += 256 * hp;\r
-       drawfill(p, '256 0 0' * (1-hp) + '0 8 0' , '0 0 0', 0.75, DRAWFLAG_NORMAL);\r
-\r
-       // Draw minigun heat indicator\r
-       p = '0.5 0 0' * (vid_conwidth - 256);\r
-       p = p + '0 1 0' * vid_conheight - '0 34  0';\r
-       drawfill(p, '256 0 0' * (1-heat) + '0 2 0' ,'0 0 1', 0.5, DRAWFLAG_NORMAL);\r
-       p_x += 256 * (1-heat);\r
-       drawfill(p, '256 0 0' * heat  + '0 2 0' , '1 0 0', 0.5, DRAWFLAG_NORMAL);\r
-\r
-\r
-       // Draw rocket icons for loaded/empty tubes.\r
-       pp = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));\r
-       pp += '0 1 0' * vid_conheight - '0 64 0';\r
-       for(i = 0; i < 8; ++i)\r
-       {\r
-               p = pp + '1 0 0' * (rkt_size * i);\r
-               if(rockets == 8)\r
-               {\r
-                       if(floor(reload * 8) == i)\r
-                       {\r
-                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '1 0 0' + '0 1 0' * ((reload*8)-i), 0.75 , DRAWFLAG_NORMAL);\r
-                       }\r
-                       else if(i < reload * 8)\r
-                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '1 1 0', 0.75 , DRAWFLAG_NORMAL);\r
-                       else\r
-                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0.5 0.5 0.5', 0.75, DRAWFLAG_NORMAL);\r
-               }\r
-               else\r
-               {\r
-                       if(i < rockets)\r
-                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0 0 0', 0.25, DRAWFLAG_NORMAL);\r
-                       else\r
-                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0 1 0' * reload, 0.75, DRAWFLAG_NORMAL);\r
-               }\r
-       }\r
-       */\r
-\r
-       if (sb_showscores)\r
-       {\r
-               Sbar_DrawScoreboard();\r
-               Sbar_DrawCenterPrint();\r
-       }\r
-\r
-}\r
-\r
-#define raptor_h "gfx/vehicles/hud_bg.tga"\r
-#define raptor_b "gfx/vehicles/raptor.tga"\r
-#define raptor_g1 "gfx/vehicles/raptor_guns.tga"\r
-#define raptor_g2 "gfx/vehicles/raptor_bombs.tga"\r
-#define raptor_s "gfx/vehicles/shiled.tga"\r
-\r
-#define spider_a1 "gfx/hud/sb_rocket.tga"\r
-#define spider_a2 "gfx/sb_bullets.tga"\r
-\r
-void CSQC_RAPTOR_HUD()\r
-{\r
-       float rockets, reload, heat, hp, shield, energy;\r
-       vector picsize, hudloc;\r
-\r
-    // Fetch health & ammo stats\r
-    hp      = bound(0,getstatf(STAT_VEHICLESTAT_HEALTH), 1);\r
-       shield  = bound(0,getstatf(STAT_VEHICLESTAT_SHIELD), 1);\r
-       reload  = min(getstatf(STAT_VEHICLESTAT_RELOAD1), 1);\r
-       energy  = min(getstatf(STAT_VEHICLESTAT_ENERGY),  1);\r
-\r
-    // Draw the crosshairs\r
-    picsize = drawgetimagesize(SPIDER_CROSS);\r
-    picsize_x *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);\r
-    picsize_y *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);\r
-    drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), SPIDER_CROSS, picsize, '1 1 1', cvar_or("cl_vehicle_spiderbot_cross_alpha",0.6), DRAWFLAG_NORMAL);\r
-\r
-    hudloc_y =  4;\r
-    hudloc_x = 4;\r
-\r
-    picsize = drawgetimagesize(raptor_h) * 0.5;\r
-    drawpic(hudloc, raptor_h, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-\r
-    picsize = drawgetimagesize(spider_a2) * 0.5;\r
-    drawpic(hudloc + '120 96  0', spider_a2, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-\r
-    drawstring(hudloc + '145 19  0', strcat(ftos(rint(hp * 100)), "%"),'15 15 0','0 1 0', 1, DRAWFLAG_NORMAL);\r
-    drawstring(hudloc + '175 34  0', strcat(ftos(rint(shield * 100)), "%"),'15 15 0','0 0 1', 1, DRAWFLAG_NORMAL);\r
-    drawstring(hudloc + '136 102 0', strcat(ftos(rint(energy * 100)), "%"),'15 15 0','0.5 0.5 1', 1, DRAWFLAG_NORMAL);\r
-\r
-\r
-    picsize = drawgetimagesize(spider_a1) * 0.85;\r
-    if(reload == 1)\r
-    {\r
-        drawpic(hudloc + '132 54  0', spider_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-        drawstring(hudloc + '179 69  0', strcat(ftos(rint(reload * 100)), "%"),'14 14 0','0 1 0', 0.5, DRAWFLAG_NORMAL);\r
-    }\r
-    else\r
-    {\r
-        drawpic(hudloc + '132 54  0', spider_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-        drawstring(hudloc + '179 69  0', strcat(ftos(rint(reload * 100)), "%"),'14 14 0','0 0 1', 1, DRAWFLAG_NORMAL);\r
-    }\r
-\r
-    picsize = drawgetimagesize(raptor_b) * 0.5;\r
-    hudloc_y = 10.5;\r
-    hudloc_x = 10.5;\r
-\r
-    drawpic(hudloc, raptor_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);\r
-    drawpic(hudloc, raptor_b, picsize, '0 1 0' * hp + '1 0 0' * (1 - hp), 1, DRAWFLAG_NORMAL);\r
-    drawpic(hudloc, raptor_g1, picsize, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL);\r
-    drawpic(hudloc, raptor_g2, picsize, '1 1 1' * reload + '1 0 0' *  (1 - reload), 1, DRAWFLAG_NORMAL);\r
-\r
-\r
-       if (sb_showscores)\r
-       {\r
-               Sbar_DrawScoreboard();\r
-               Sbar_DrawCenterPrint();\r
-       }\r
-\r
-}\r
-\r
-#define waki_h "gfx/vehicles/hud_bg.tga"\r
-#define waki_b "gfx/vehicles/waki.tga"\r
-#define waki_e "gfx/vehicles/waki_e.tga"\r
-#define waki_g "gfx/vehicles/waki_guns.tga"\r
-#define waki_r "gfx/vehicles/waki_rockets.tga"\r
-#define waki_s "gfx/vehicles/shiled.tga"\r
-\r
-#define waki_a1 "gfx/hud/sb_rocket.tga"\r
-#define waki_a2 "gfx/sb_cells.tga"\r
-\r
-void CSQC_WAKIZASHI_HUD()\r
-{\r
-       // 0--1 floats. 1 = 100%, 0.6 = 50%.\r
-       float health, shield, energy, rockets;\r
-       vector picsize, hudloc;\r
-\r
-    picsize = drawgetimagesize(SPIDER_CROSS);\r
-    picsize_x *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);\r
-    picsize_y *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);\r
-    drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), SPIDER_CROSS, picsize, '1 1 1', cvar_or("cl_vehicle_spiderbot_cross_alpha",0.6), DRAWFLAG_NORMAL);\r
-\r
-/*\r
-const float STAT_VEHICLESTAT_HEALTH  = 60;\r
-const float STAT_VEHICLESTAT_SHIELD  = 61;\r
-const float STAT_VEHICLESTAT_ENERGY  = 62;\r
-const float STAT_VEHICLESTAT_AMMO1   = 63;\r
-const float STAT_VEHICLESTAT_RELAOD1 = 64;\r
-const float STAT_VEHICLESTAT_AMMO2   = 65;\r
-const float STAT_VEHICLESTAT_RELOAD2 = 66;\r
-*/\r
-    health  = min(getstatf(STAT_VEHICLESTAT_HEALTH),  1);\r
-       shield  = min(getstatf(STAT_VEHICLESTAT_SHIELD),  1);\r
-       energy  = min(getstatf(STAT_VEHICLESTAT_ENERGY),  1);\r
-       rockets = bound(0,getstatf(STAT_VEHICLESTAT_RELOAD1), 1);\r
-\r
-    hudloc_y =  4;\r
-    hudloc_x = 4;\r
-\r
-    picsize = drawgetimagesize(waki_h) * 0.5;\r
-    drawpic(hudloc, waki_h, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-\r
-    picsize = drawgetimagesize(waki_a2) * 0.7;\r
-    drawpic(hudloc + '116 92  0', waki_a2, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-\r
-\r
-    drawstring(hudloc + '145 19  0', strcat(ftos(rint(health * 100)), "%"),'15 15 0','0 1 0', 1, DRAWFLAG_NORMAL);\r
-    drawstring(hudloc + '175 34  0', strcat(ftos(rint(shield * 100)), "%"),'15 15 0','0 0 1', 1, DRAWFLAG_NORMAL);\r
-\r
-    drawstring(hudloc + '136 102  0', strcat(ftos(rint(energy * 100)), "%"),'14 14 0','1 1 1', 1, DRAWFLAG_NORMAL);\r
-\r
-    picsize = drawgetimagesize(waki_a1) * 0.75;\r
-    if(rockets == 1)\r
-    {\r
-        drawpic(hudloc + '140 55  0', waki_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-        drawpic(hudloc + '144 59  0', waki_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);\r
-    }\r
-    else\r
-    {\r
-        drawpic(hudloc + '140 55  0', waki_a1, picsize, '-1 -1 -1', 1, DRAWFLAG_NORMAL);\r
-        drawpic(hudloc + '144 59  0', waki_a1, picsize, '-1 -1 -1', 1, DRAWFLAG_NORMAL);\r
-        drawstring(hudloc + '165 69 0', strcat(ftos(rint(rockets * 100)), "%"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);\r
-    }\r
-\r
-    picsize = drawgetimagesize(waki_b) * 0.5;\r
-    hudloc_y = 10.5;\r
-    hudloc_x = 10.5;\r
-\r
-    drawpic(hudloc, waki_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);\r
-    drawpic(hudloc, waki_b, picsize, '0 1 0' * health + '1 0 0' * (1 - health), 1, DRAWFLAG_NORMAL);\r
-    drawpic(hudloc, waki_r, picsize, '1 1 1' * rockets + '1 0 0' * (1 - rockets), 1, DRAWFLAG_NORMAL);\r
-    drawpic(hudloc, waki_e, picsize, '1 1 1' * energy + '1 0 0' *  (1 - energy), 1, DRAWFLAG_NORMAL);\r
-\r
-\r
-\r
-       /*\r
-       p = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));\r
-       p = p + '0 1 0' * vid_conheight - '0 32 0';\r
-\r
-       // Draw health bar\r
-       p_y += 8;\r
-       drawfill(p, '256 0 0' * health + '0 8 0' , '0 0.7 0', 0.75, DRAWFLAG_NORMAL);\r
-       p_x += 256 * health;\r
-       drawfill(p, '256 0 0' * (1 - health) + '0 8 0' , '0 0 0', 0.75, DRAWFLAG_NORMAL);\r
-\r
-       // Draw shiled bar\r
-       p_x -= 256 * health;\r
-       p_y += 4;\r
-       drawfill(p, '256 0 0' * shield + '0 4 0' , '0.25 0.25 1', 0.5, DRAWFLAG_NORMAL);\r
-\r
-       // Draw energy\r
-       //p_x -= 256 * health;\r
-       p_y -= 8;\r
-       drawfill(p, '256 0 0' * energy + '0 4 0' , '1 1 1', 0.75, DRAWFLAG_NORMAL);\r
-\r
-       // Draw rockets bar\r
-       p_y += 12;\r
-       drawfill(p, '256 0 0' * rockets + '0 4 0' , '1 0 0', 0.75, DRAWFLAG_NORMAL);\r
-       */\r
-\r
-\r
-\r
-\r
-       if (sb_showscores)\r
-       {\r
-               Sbar_DrawScoreboard();\r
-               Sbar_DrawCenterPrint();\r
-       }\r
-\r
-}\r
-\r
-\r
-void CSQC_common_hud(void)\r
-{\r
-       // Sbar_SortFrags(); done in Sbar_Draw\r
-       float hud;\r
-       hud = getstati(STAT_HUD);\r
-\r
-       //hud = 10;\r
-       switch(hud)\r
-       {\r
-               case HUD_NORMAL:\r
-                       Sbar_Draw();\r
-                       break;\r
-\r
-               case HUD_SPIDERBOT:\r
-                       CSQC_SPIDER_HUD();\r
-                       break;\r
-\r
-               case HUD_WAKIZASHI:\r
-                       CSQC_WAKIZASHI_HUD();\r
-                       break;\r
-       }\r
-}\r
-\r
-\r
-// following vectors must be global to allow seamless switching between camera modes\r
-vector camera_offset, current_camera_offset, mouse_angles, current_angles, current_origin, current_position;\r
-void CSQC_Demo_Camera()\r
-{\r
-       float speed, attenuation, dimensions;\r
-       vector tmp, delta;\r
-\r
-       if( cvar("camera_reset") || !camera_mode )\r
-       {\r
-               camera_offset = '0 0 0';\r
-               current_angles = '0 0 0';\r
-               camera_direction = '0 0 0';\r
-               camera_offset_z += 30;\r
-               camera_offset_x += 30 * -cos(current_angles_y * DEG2RAD);\r
-               camera_offset_y += 30 * -sin(current_angles_y * DEG2RAD);\r
-               current_origin = view_origin;\r
-               current_camera_offset  = camera_offset;\r
-               cvar_set("camera_reset", "0");\r
-               camera_mode = CAMERA_CHASE;\r
-       }\r
-\r
-       // Camera angles\r
-       if( camera_roll )\r
-               mouse_angles_z += camera_roll * cvar("camera_speed_roll");\r
-\r
-       if(cvar("camera_look_player"))\r
-       {\r
-               local vector dir;\r
-               local float n;\r
-\r
-               dir = normalize(view_origin - current_position);\r
-               n = mouse_angles_z;\r
-               mouse_angles = vectoangles(dir);\r
-               mouse_angles_x = mouse_angles_x * -1;\r
-               mouse_angles_z = n;\r
-       }\r
-       else\r
-       {\r
-               tmp = getmousepos() * 0.1;\r
-               if(vlen(tmp)>cvar("camera_mouse_treshold"))\r
-               {\r
-                       mouse_angles_x += tmp_y * cos(mouse_angles_z * DEG2RAD) + (tmp_x * sin(mouse_angles_z * DEG2RAD));\r
-                       mouse_angles_y -= tmp_x * cos(mouse_angles_z * DEG2RAD) + (tmp_y * -sin(mouse_angles_z * DEG2RAD));\r
-               }\r
-       }\r
-\r
-       while (mouse_angles_x < -180) mouse_angles_x = mouse_angles_x + 360;\r
-       while (mouse_angles_x > 180) mouse_angles_x = mouse_angles_x - 360;\r
-       while (mouse_angles_y < -180) mouse_angles_y = mouse_angles_y + 360;\r
-       while (mouse_angles_y > 180) mouse_angles_y = mouse_angles_y - 360;\r
-\r
-       // Fix difference when angles don't have the same sign\r
-       delta = '0 0 0';\r
-       if(mouse_angles_y < -60 && current_angles_y > 60)\r
-               delta = '0 360 0';\r
-       if(mouse_angles_y > 60 && current_angles_y < -60)\r
-               delta = '0 -360 0';\r
-\r
-       if(cvar("camera_look_player"))\r
-               attenuation = cvar("camera_look_attenuation");\r
-       else\r
-               attenuation = cvar("camera_speed_attenuation");\r
-\r
-       attenuation = 1 / max(1, attenuation);\r
-       current_angles += (mouse_angles - current_angles + delta) * attenuation;\r
-\r
-       while (current_angles_x < -180) current_angles_x = current_angles_x + 360;\r
-       while (current_angles_x > 180) current_angles_x = current_angles_x - 360;\r
-       while (current_angles_y < -180) current_angles_y = current_angles_y + 360;\r
-       while (current_angles_y > 180) current_angles_y = current_angles_y - 360;\r
-\r
-       // Camera position\r
-       tmp = '0 0 0';\r
-       dimensions = 0;\r
-\r
-       if( camera_direction_x )\r
-       {\r
-               tmp_x = camera_direction_x * cos(current_angles_y * DEG2RAD);\r
-               tmp_y = camera_direction_x * sin(current_angles_y * DEG2RAD);\r
-               if( cvar("camera_forward_follows") && !cvar("camera_look_player") )\r
-                       tmp_z = camera_direction_x * -sin(current_angles_x * DEG2RAD);\r
-               ++dimensions;\r
-       }\r
-\r
-       if( camera_direction_y )\r
-       {\r
-               tmp_x += camera_direction_y * -sin(current_angles_y * DEG2RAD);\r
-               tmp_y += camera_direction_y * cos(current_angles_y * DEG2RAD) * cos(current_angles_z * DEG2RAD);\r
-               tmp_z += camera_direction_y * sin(current_angles_z * DEG2RAD);\r
-               ++dimensions;\r
-       }\r
-\r
-       if( camera_direction_z )\r
-       {\r
-               tmp_z += camera_direction_z * cos(current_angles_z * DEG2RAD);\r
-               ++dimensions;\r
-       }\r
-\r
-       if(cvar("camera_free"))\r
-               speed = cvar("camera_speed_free");\r
-       else\r
-               speed = cvar("camera_speed_chase");\r
-\r
-       if(dimensions)\r
-       {\r
-               speed = speed * sqrt(1 / dimensions);\r
-               camera_offset += tmp * speed;\r
-       }\r
-\r
-       current_camera_offset += (camera_offset - current_camera_offset) * attenuation;\r
-\r
-       // Camera modes\r
-       if( cvar("camera_free") )\r
-       {\r
-               if ( camera_mode == CAMERA_CHASE )\r
-               {\r
-                       current_camera_offset = current_origin + current_camera_offset;\r
-                       camera_offset = current_origin + camera_offset;\r
-               }\r
-\r
-               camera_mode = CAMERA_FREE;\r
-               current_position = current_camera_offset;\r
-       }\r
-       else\r
-       {\r
-               if ( camera_mode == CAMERA_FREE )\r
-               {\r
-                       current_origin = view_origin;\r
-                       camera_offset = camera_offset - current_origin;\r
-                       current_camera_offset = current_camera_offset - current_origin;\r
-               }\r
-\r
-               camera_mode = CAMERA_CHASE;\r
-\r
-               if(cvar("camera_chase_smoothly"))\r
-                       current_origin += (view_origin - current_origin) * attenuation;\r
-               else\r
-                       current_origin = view_origin;\r
-\r
-               current_position = current_origin + current_camera_offset;\r
-       }\r
-\r
-       R_SetView(VF_ANGLES, current_angles);\r
-       R_SetView(VF_ORIGIN, current_position);\r
-}\r
+#define spider_rocket_icon "gfx/vehicles/rocket_ico.tga"
+#define spider_rocket_targ "gfx/vehicles/target.tga"
+#define SPIDER_CROSS "textures/spiderbot/cross.tga"
+#define rkt_size 32
+#define rld_size_x 256
+#define rld_size_y 16
+
+void CSQC_WAKIZASHI_HUD();
+
+entity porto;
+vector polyline[16];
+float trace_dphitcontents;
+float trace_networkentity;
+float Q3SURFACEFLAG_SLICK = 2; // low friction surface
+float DPCONTENTS_SOLID = 1; // blocks player movement
+float DPCONTENTS_BODY = 32; // blocks player movement
+float DPCONTENTS_CORPSE = 64; // blocks player movement
+float DPCONTENTS_PLAYERCLIP = 256; // blocks player movement
+void Porto_Draw()
+{
+       vector p, dir, ang, q, nextdir;
+       float idx, portal_number, portal1_idx;
+
+       if(activeweapon != WEP_PORTO || spectatee_status || gametype == GAME_NEXBALL)
+               return;
+       if(intermission == 1)
+               return;
+       if(intermission == 2)
+               return;
+       if (getstati(STAT_HEALTH) <= 0)
+               return;
+
+       dir = view_forward;
+
+       if(angles_held_status)
+       {
+               makevectors(angles_held);
+               dir = v_forward;
+       }
+
+       p = view_origin;
+
+       polyline[0] = p;
+       idx = 1;
+       portal_number = 0;
+       nextdir = dir;
+
+       for(;;)
+       {
+               dir = nextdir;
+               traceline(p, p + 65536 * dir, TRUE, porto);
+               if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
+                       return;
+               nextdir = dir - 2 * (dir * trace_plane_normal) * trace_plane_normal; // mirror dir at trace_plane_normal
+               p = trace_endpos;
+               polyline[idx] = p;
+               ++idx;
+               if(idx >= 16)
+                       return;
+               if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP)
+                       continue;
+               ++portal_number;
+               ang = vectoangles2(trace_plane_normal, dir);
+               ang_x = -ang_x;
+               makevectors(ang);
+               if(!CheckWireframeBox(porto, p - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward))
+                       return;
+               if(portal_number == 1)
+                       portal1_idx = idx;
+               if(portal_number >= 2)
+                       break;
+       }
+
+       while(idx >= 2)
+       {
+               p = polyline[idx-2];
+               q = polyline[idx-1];
+               if(idx == 2)
+                       p = p - view_up * 16;
+               if(idx-1 >= portal1_idx)
+               {
+                       Draw_CylindricLine(p, q, 4, "", 1, 0, '0 0 1', 0.5, DRAWFLAG_NORMAL);
+               }
+               else
+               {
+                       Draw_CylindricLine(p, q, 4, "", 1, 0, '1 0 0', 0.5, DRAWFLAG_NORMAL);
+               }
+               --idx;
+       }
+}
+
+/**
+ * Checks whether the server initiated a map restart (stat_game_starttime changed)
+ *
+ * TODO: Use a better solution where a common shared entitiy is used that contains
+ * timelimit, fraglimit and game_starttime! Requires engine changes (remove STAT_TIMELIMIT
+ * and STAT_FRAGLIMIT to be auto-sent)
+ */
+void CheckForGamestartChange() {
+       float startTime;
+       startTime = getstatf(STAT_GAMESTARTTIME);
+       if (previous_game_starttime != startTime) {
+               if ((time + 5.0) < startTime) {
+                       //if connecting to server while restart was active don't always play prepareforbattle
+                       sound(self, CHAN_VOICE, strcat("announcer/", cvar_string("cl_announcer"), "/prepareforbattle.wav"), VOL_BASEVOICE, ATTN_NONE);
+               }
+               if (time < startTime) {
+                       restartAnnouncer = spawn();
+                       restartAnnouncer.think = restartAnnouncer_Think;
+                       restartAnnouncer.nextthink = startTime - floor(startTime - time); //synchronize nextthink to startTime
+               }
+       }
+       previous_game_starttime = startTime;
+}
+
+void Porto_Init()
+{
+       porto = spawn();
+       porto.classname = "porto";
+       porto.draw = Porto_Draw;
+       porto.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP;
+}
+
+float drawtime;
+float avgspeed;
+vector GetCurrentFov(float fov)
+{
+       float zoomsensitivity, zoomspeed, zoomfactor, zoomdir, velocityzoom;
+
+       zoomsensitivity = cvar("cl_zoomsensitivity");
+       zoomfactor = cvar("cl_zoomfactor");
+       if(zoomfactor < 1 || zoomfactor > 16)
+               zoomfactor = 2.5;
+       zoomspeed = cvar("cl_zoomspeed");
+       if(zoomspeed >= 0)
+               if(zoomspeed < 0.5 || zoomspeed > 16)
+                       zoomspeed = 3.5;
+
+       zoomdir = button_zoom;
+       if(getstati(STAT_ACTIVEWEAPON) == WEP_NEX) // do NOT use switchweapon here
+               zoomdir += button_attack2;
+       if(spectatee_status > 0 || isdemo())
+       {
+               if(spectatorbutton_zoom)
+                       zoomdir = 0 + !zoomdir;
+               // do not even THINK about removing this 0
+               // _I_ know what I am doing
+               // fteqcc does not
+       }
+
+       if(zoomdir)
+               zoomin_effect = 0;
+
+       if(zoomin_effect || camera_active)
+       {
+               current_viewzoom = min(1, current_viewzoom + drawframetime);
+       }
+       else
+       {
+               if(zoomspeed < 0) // instant zoom
+               {
+                       if(zoomdir)
+                               current_viewzoom = 1 / zoomfactor;
+                       else
+                               current_viewzoom = 1;
+               }
+               else
+               {
+                       if(zoomdir)
+                               current_viewzoom = 1 / bound(1, 1 / current_viewzoom + drawframetime * zoomspeed * (zoomfactor - 1), zoomfactor);
+                       else
+                               current_viewzoom = bound(1 / zoomfactor, current_viewzoom + drawframetime * zoomspeed * (1 - 1 / zoomfactor), 1);
+               }
+       }
+
+       if(almost_equals(current_viewzoom, 1))
+               current_zoomfraction = 0;
+       else if(almost_equals(current_viewzoom, 1/zoomfactor))
+               current_zoomfraction = 1;
+       else
+               current_zoomfraction = (current_viewzoom - 1) / (1/zoomfactor - 1);
+
+       if(zoomsensitivity < 1)
+               setsensitivityscale(pow(current_viewzoom, 1 - zoomsensitivity));
+       else
+               setsensitivityscale(1);
+
+       velocityzoom = bound(0, drawframetime / max(0.000000001, cvar_or("cl_velocityzoomtime", 0.3)), 1);
+       avgspeed = avgspeed * (1 - velocityzoom) + (vlen(pmove_vel) / 1000) * velocityzoom;
+       velocityzoom = exp(float2range11(avgspeed * -cvar_or("cl_velocityzoom", 0) / 1) * 1);
+
+       //print(ftos(avgspeed), " avgspeed, ", ftos(cvar_or("cl_velocityzoom", 0)), " cvar, ", ftos(velocityzoom), " return\n"); // for debugging
+
+       float frustumx, frustumy, fovx, fovy;
+       frustumy = tan(fov * M_PI / 360.0) * 0.75 * current_viewzoom * velocityzoom;
+       frustumx = frustumy * vid_width / vid_height / vid_pixelheight;
+       fovx = atan2(frustumx, 1) / M_PI * 360.0;
+       fovy = atan2(frustumy, 1) / M_PI * 360.0;
+
+       return '1 0 0' * fovx + '0 1 0' * fovy;
+}
+
+// this function must match W_SetupShot!
+float zoomscript_caught;
+
+vector wcross_origin;
+float wcross_scale_prev, wcross_alpha_prev;
+vector wcross_color_prev;
+float wcross_scale_goal_prev, wcross_alpha_goal_prev;
+vector wcross_color_goal_prev;
+float wcross_changedonetime;
+
+string wcross_name_goal_prev, wcross_name_goal_prev_prev;
+float wcross_resolution_goal_prev, wcross_resolution_goal_prev_prev;
+float wcross_name_changestarttime, wcross_name_changedonetime;
+float wcross_name_alpha_goal_prev, wcross_name_alpha_goal_prev_prev;
+entity trueaim;
+entity trueaim_rifle;
+
+#define SHOTTYPE_HITTEAM 1
+#define SHOTTYPE_HITOBSTRUCTION 2
+#define SHOTTYPE_HITWORLD 3
+#define SHOTTYPE_HITENEMY 4
+
+void TrueAim_Init()
+{
+       trueaim = spawn();
+       trueaim.classname = "trueaim";
+       trueaim.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE;
+       trueaim_rifle = spawn();
+       trueaim_rifle.classname = "trueaim_rifle";
+       trueaim_rifle.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_CORPSE;
+}
+
+float EnemyHitCheck()
+{
+       float t;
+       wcross_origin = project_3d_to_2d(trace_endpos);
+       wcross_origin_z = 0;
+       if(trace_networkentity < 1)
+               return SHOTTYPE_HITWORLD;
+       if(trace_networkentity > maxclients)
+               return SHOTTYPE_HITWORLD;
+       t = GetPlayerColor(trace_networkentity - 1);
+       if(teamplay)
+               if(t == myteam)
+                       return SHOTTYPE_HITTEAM;
+       if(t == COLOR_SPECTATOR)
+               return SHOTTYPE_HITWORLD;
+       return SHOTTYPE_HITENEMY;
+}
+
+float TrueAimCheck()
+{
+       float nudge = 1; // added to traceline target and subtracted from result
+       vector vecs, trueaimpoint, w_shotorg;
+       vector mi, ma, dv;
+       float shottype;
+       entity ta;
+       float mv;
+
+       mi = ma = '0 0 0';
+       ta = trueaim;
+       mv = MOVE_NOMONSTERS;
+
+       switch(activeweapon)
+       {
+               case WEP_TUBA: // no aim
+               case WEP_PORTO: // shoots from eye
+               case WEP_HOOK: // no trueaim
+               case WEP_GRENADE_LAUNCHER: // toss curve
+                       return SHOTTYPE_HITWORLD;
+               case WEP_NEX:
+               case WEP_MINSTANEX:
+                       mv = MOVE_NORMAL;
+                       break;
+               case WEP_CAMPINGRIFLE:
+                       ta = trueaim_rifle;
+                       mv = MOVE_NORMAL;
+                       if(zoomscript_caught)
+                       {
+                               tracebox(view_origin, '0 0 0', '0 0 0', view_origin + view_forward * MAX_SHOT_DISTANCE, mv, ta);
+                               return EnemyHitCheck();
+                       }
+                       break;
+               case WEP_ROCKET_LAUNCHER: // projectile has a size!
+                       mi = '-3 -3 -3';
+                       ma = '3 3 3';
+                       break;
+               case WEP_FIREBALL: // projectile has a size!
+                       mi = '-16 -16 -16';
+                       ma = '16 16 16';
+                       break;
+               case WEP_SEEKER: // projectile has a size!
+                       mi = '-2 -2 -2';
+                       ma = '2 2 2';
+                       break;
+               case WEP_ELECTRO: // projectile has a size!
+                       mi = '0 0 -3';
+                       ma = '0 0 -3';
+                       break;
+       }
+
+       vecs = decompressShotOrigin(getstati(STAT_SHOTORG));
+
+       traceline(view_origin, view_origin + view_forward * MAX_SHOT_DISTANCE, mv, ta);
+       trueaimpoint = trace_endpos;
+
+       if(vecs_x > 0)
+               vecs_y = -vecs_y;
+       else
+               vecs = '0 0 0';
+
+       dv = view_right * vecs_y + view_up * vecs_z;
+       w_shotorg = view_origin + dv;
+
+       // now move the vecs forward as much as requested if possible
+       tracebox(w_shotorg, mi, ma, w_shotorg + view_forward * (vecs_x + nudge), MOVE_NORMAL, ta); // FIXME this MOVE_NORMAL part will misbehave a little in csqc
+       w_shotorg = trace_endpos - view_forward * nudge;
+
+       tracebox(w_shotorg, mi, ma, trueaimpoint, MOVE_NORMAL, ta);
+       shottype = EnemyHitCheck();
+       if(shottype != SHOTTYPE_HITWORLD)
+               return shottype;
+
+#if 0
+       // FIXME WHY DOES THIS NOT WORK FOR THE ROCKET LAUNCHER?
+       // or rather, I know why, but see no fix
+       if(vlen(trace_endpos - trueaimpoint) > vlen(ma) + vlen(mi) + 1)
+               // yes, this is an ugly hack... but it seems good enough to find out whether the test hits the same place as the initial trace
+               return SHOTTYPE_HITOBSTRUCTION;
+#endif
+
+       return SHOTTYPE_HITWORLD;
+}
+
+void CSQC_common_hud(void);
+
+void PostInit(void);
+void CSQC_Demo_Camera();
+float HUD_WouldDrawScoreboard ();
+float view_set;
+float camera_mode;
+string NextFrameCommand;
+void CSQC_SPIDER_HUD();
+void CSQC_RAPTOR_HUD();
+
+vector freeze_pmove_org, freeze_input_angles;
+
+void CSQC_UpdateView(float w, float h)
+{
+       entity e;
+       float fov;
+       float f, i, j;
+       vector v, vo;
+
+       WaypointSprite_Load();
+
+       if(spectatee_status)
+               myteam = GetPlayerColor(spectatee_status - 1);
+       else
+               myteam = GetPlayerColor(player_localentnum - 1);
+
+       ticrate = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
+       vo = '0 0 1' * getstati(STAT_VIEWHEIGHT);
+
+       warpzone_fixview_origin = pmove_org + vo;
+       warpzone_fixview_cl_viewangles = input_angles;
+       warpzone_fixview_angles = view_angles;
+       WarpZone_FixView();
+       pmove_org = warpzone_fixview_origin - vo;
+       input_angles = warpzone_fixview_cl_viewangles;
+       view_angles = warpzone_fixview_angles;
+
+       if(cvar("cl_lockview"))
+       {
+               pmove_org = freeze_pmove_org;
+               input_angles = view_angles = freeze_input_angles;
+               R_SetView(VF_ORIGIN, pmove_org + vo);
+               R_SetView(VF_ANGLES, view_angles);
+               //R_SetView(VF_CL_VIEWANGLES, input_angles);
+       }
+       freeze_pmove_org = pmove_org;
+       freeze_input_angles = input_angles;
+
+       // Render the Scene
+       if(!intermission || !view_set)
+       {
+               view_origin = pmove_org + vo;
+               view_angles = input_angles;
+               makevectors(view_angles);
+               view_forward = v_forward;
+               view_right = v_right;
+               view_up = v_up;
+               view_set = 1;
+       }
+
+       hudconf_active = cvar("_hud_configure");
+       if(hudconf_active)
+               R_SetView(VF_ANGLES, self.angles); // TODO: this should freeze the view as it is, not change it to '0 0 0' or whatever it currently does...
+
+       vid_width = w;
+       vid_height = h;
+
+#ifdef BLURTEST
+       if(time > blurtest_time0 && time < blurtest_time1)
+       {
+               float r, t;
+
+               t = (time - blurtest_time0) / (blurtest_time1 - blurtest_time0);
+               r = t * blurtest_radius;
+               f = 1 / pow(t, blurtest_power) - 1;
+
+               cvar_set("r_glsl_postprocess", "1");
+               cvar_set("r_glsl_postprocess_uservec1", strcat(ftos(r), " ", ftos(f), " 0 0"));
+       }
+       else
+       {
+               cvar_set("r_glsl_postprocess", "0");
+               cvar_set("r_glsl_postprocess_uservec1", "0 0 0 0");
+       }
+#endif
+
+       TargetMusic_Advance();
+       Fog_Force();
+
+       drawframetime = max(0.000001, time - drawtime);
+       drawtime = time;
+
+       // watch for gametype changes here...
+       // in ParseStuffCMD the cmd isn't executed yet :/
+       // might even be better to add the gametype to TE_CSQC_INIT...?
+       if(!postinit)
+               PostInit();
+
+       if(intermission && !isdemo() && !(calledhooks & HOOK_END))
+               if(calledhooks & HOOK_START)
+               {
+                       localcmd("\ncl_hook_gameend;");
+                       calledhooks |= HOOK_END;
+               }
+
+       CheckForGamestartChange();
+       serverAnnouncer();
+       maptimeAnnouncer();
+       carrierAnnouncer();
+
+       fov = cvar("fov");
+       if(button_zoom || fov <= 59.5)
+       {
+               if(!zoomscript_caught)
+               {
+                       localcmd("+button4\n");
+                       zoomscript_caught = 1;
+                       ignore_plus_zoom += 1;
+               }
+       }
+       else
+       {
+               if(zoomscript_caught)
+               {
+                       localcmd("-button4\n");
+                       zoomscript_caught = 0;
+                       ignore_minus_zoom += 1;
+               }
+       }
+
+       hud_alpha_fg = cvar_or("hud_fg_alpha", 1) * (1 - cvar("_menu_alpha"));
+       hud_accuracy_hud = cvar_or("hud_accuracy_hud", 1);
+       ColorTranslateMode = cvar("cl_stripcolorcodes");
+       activeweapon = getstati(STAT_SWITCHWEAPON);
+       f = cvar("teamplay");
+       if(f != teamplay)
+       {
+               teamplay = f;
+               HUD_InitScores();
+       }
+
+       if(last_weapon != activeweapon) {
+               weapontime = time;
+               last_weapon = activeweapon;
+       }
+
+       // ALWAYS Clear Current Scene First
+       R_ClearScene();
+
+       // Assign Standard Viewflags
+       // Draw the World (and sky)
+       R_SetView(VF_DRAWWORLD, 1);
+
+       // Set the console size vars
+       vid_conwidth = cvar("vid_conwidth");
+       vid_conheight = cvar("vid_conheight");
+       vid_pixelheight = cvar("vid_pixelheight");
+
+       R_SetView(VF_FOV, GetCurrentFov(fov));
+
+       // Camera for demo playback
+       if(camera_active)
+       {
+               if(cvar("camera_enable"))
+                       CSQC_Demo_Camera();
+               else
+               {
+                       cvar_set("chase_active", ftos(chase_active_backup));
+                       cvar_set("cl_demo_mousegrab", "0");
+                       camera_active = FALSE;
+               }
+       }
+#ifdef CAMERATEST
+       else if(cvar("camera_enable"))
+#else
+       else if(cvar("camera_enable") && isdemo())
+#endif
+       {
+               // Enable required Darkplaces cvars
+               chase_active_backup = cvar("chase_active");
+               cvar_set("chase_active", "2");
+               cvar_set("cl_demo_mousegrab", "1");
+               camera_active = TRUE;
+               camera_mode = FALSE;
+       }
+
+       // Draw the Crosshair
+       float scoreboard_active;
+       scoreboard_active = HUD_WouldDrawScoreboard();
+       R_SetView(VF_DRAWCROSSHAIR, 0); //Make sure engine crosshairs are always hidden
+
+       // Draw the Engine Status Bar (the default Quake HUD)
+       R_SetView(VF_DRAWENGINEHUD, 0);
+
+       // fetch this one only once per frame
+       hud_showbinds = cvar("hud_showbinds");
+       hud_showbinds_limit = cvar("hud_showbinds_limit");
+
+       // Update the mouse position
+       /*
+          mousepos_x = vid_conwidth;
+          mousepos_y = vid_conheight;
+          mousepos = mousepos*0.5 + getmousepos();
+        */
+
+       e = self;
+       for(self = world; (self = nextent(self)); )
+               if(self.draw)
+                       self.draw();
+       self = e;
+
+       R_AddEntities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);
+       R_RenderScene();
+
+       // now switch to 2D drawing mode by calling a 2D drawing function
+       // then polygon drawing will draw as 2D stuff, and NOT get queued until the
+       // next R_RenderScene call
+       drawstring('0 0 0', "", '1 1 0', '1 1 1', 0, 0);
+
+       // Draw the mouse cursor
+       // NOTE: drawpic must happen after R_RenderScene for some reason
+       //drawpic(getmousepos(), "gfx/cursor.tga", '11 14 0', '1 1 1', 1, 0);
+       //drawstring('50 50', ftos(game), '10 10 0', '1 1 1', 1, 0);
+       //self = edict_num(player_localnum);
+       //drawstring('0 0', vtos(pmove_org), '8 8 0', '1 1 1', 1, 0);
+       //drawstring('0 8', strcat("ORG: ", vtos(self.origin), " state: ", ftos(self.ctf_state), " HP: ", ftos(self.health)), '8 8 0', '1 1 1', 1, 0);
+       // as long as the ctf part isn't in, this is useless
+       if(menu_visible)
+               menu_show();
+
+       /*if(gametype == GAME_CTF)
+         {
+         ctf_view();
+         } else */
+
+       // draw 2D entities
+       e = self;
+       for(self = world; (self = nextent(self)); )
+               if(self.draw2d)
+                       self.draw2d();
+       self = e;
+
+       // draw hud
+       if(cvar("r_letterbox") == 0) {
+               HUD_DrawCenterPrint(); // draw centerprint messages even if viewsize >= 120
+       }
+
+       float hud;
+       hud = getstati(STAT_HUD);
+       if(hud == HUD_SPIDERBOT)
+       {
+               CSQC_SPIDER_HUD();
+       }
+       else if(hud == HUD_WAKIZASHI)
+        CSQC_WAKIZASHI_HUD();
+    else if(hud == HUD_RAPTOR)
+        CSQC_RAPTOR_HUD();
+       else
+       {
+               if(cvar("r_letterbox") == 0)
+                       if(cvar("viewsize") < 120)
+                               CSQC_common_hud();
+
+               // crosshair goes VERY LAST
+               if(!scoreboard_active && !camera_active && !hudconf_active) {
+                       // TrueAim check
+                       float shottype;
+                       float bullets, ring_scale;
+                       // wcross_origin = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;
+                       wcross_origin = project_3d_to_2d(view_origin + MAX_SHOT_DISTANCE * view_forward);
+                       wcross_origin_z = 0;
+                       if(cvar("crosshair_hittest"))
+                       {
+                               vector wcross_oldorigin;
+                               wcross_oldorigin = wcross_origin;
+                               shottype = TrueAimCheck();
+                               if(shottype == SHOTTYPE_HITWORLD)
+                               {
+                                       v = wcross_origin - wcross_oldorigin;
+                                       v_x /= vid_conwidth;
+                                       v_y /= vid_conheight;
+                                       if(vlen(v) > 0.01)
+                                               shottype = SHOTTYPE_HITOBSTRUCTION;
+                               }
+                               if(!cvar("crosshair_hittest_showimpact"))
+                                       wcross_origin = wcross_oldorigin;
+                       }
+                       else
+                               shottype = SHOTTYPE_HITWORLD;
+
+                       string wcross_style;
+                       wcross_style = cvar_string("crosshair");
+
+                       if (wcross_style != "0") {
+                               vector wcross_color, wcross_size;
+                               string wcross_wep, wcross_name;
+                               float wcross_alpha, wcross_scale, wcross_blur, wcross_resolution;
+
+                               wcross_color_x = cvar("crosshair_color_red");
+                               wcross_color_y = cvar("crosshair_color_green");
+                               wcross_color_z = cvar("crosshair_color_blue");
+                               wcross_alpha = cvar("crosshair_color_alpha");
+                               wcross_resolution = cvar("crosshair_size");
+                               if (cvar("crosshair_per_weapon")) {
+                                       e = get_weaponinfo(activeweapon);
+                                       if (e && e.netname != "")
+                                       {
+                                               wcross_wep = e.netname;
+                                               wcross_style = cvar_string(strcat("crosshair_", wcross_wep));
+                                               if(wcross_style == "")
+                                                       wcross_style = e.netname;
+
+                                               if(!cvar("crosshair_color_override"))
+                                               {
+                                                       wcross_color_x = cvar(strcat("crosshair_", wcross_wep, "_color_red"));
+                                                       wcross_color_y = cvar(strcat("crosshair_", wcross_wep, "_color_green"));
+                                                       wcross_color_z = cvar(strcat("crosshair_", wcross_wep, "_color_blue"));
+                                               }
+
+                                               wcross_alpha *= cvar(strcat("crosshair_", wcross_wep, "_color_alpha"));
+                                               wcross_resolution *= cvar(strcat("crosshair_", wcross_wep, "_size"));
+                                       }
+                               }
+
+                               wcross_name = strcat("gfx/crosshair", wcross_style);
+
+                               if(cvar("crosshair_effect_scalefade"))
+                               {
+                                       wcross_scale = wcross_resolution;
+                                       wcross_resolution = 1;
+                               }
+                               else
+                               {
+                                       wcross_scale = 1;
+                               }
+
+                               if(shottype == SHOTTYPE_HITENEMY)
+                                       wcross_scale *= cvar("crosshair_hittest"); // is not queried if hittest is 0
+                               if(shottype == SHOTTYPE_HITTEAM)
+                                       wcross_scale /= cvar("crosshair_hittest"); // is not queried if hittest is 0
+
+                               f = cvar("crosshair_effect_speed");
+                               if(f < 0)
+                                       f *= -2 * g_weaponswitchdelay;
+                               if(wcross_scale != wcross_scale_goal_prev || wcross_alpha != wcross_alpha_goal_prev || wcross_color != wcross_color_goal_prev)
+                               {
+                                       wcross_changedonetime = time + f;
+                               }
+                               if(wcross_name != wcross_name_goal_prev || wcross_resolution != wcross_resolution_goal_prev)
+                               {
+                                       wcross_name_changestarttime = time;
+                                       wcross_name_changedonetime = time + f;
+                                       if(wcross_name_goal_prev_prev)
+                                               strunzone(wcross_name_goal_prev_prev);
+                                       wcross_name_goal_prev_prev = wcross_name_goal_prev;
+                                       wcross_name_goal_prev = strzone(wcross_name);
+                                       wcross_name_alpha_goal_prev_prev = wcross_name_alpha_goal_prev;
+                                       wcross_resolution_goal_prev_prev = wcross_resolution_goal_prev;
+                                       wcross_resolution_goal_prev = wcross_resolution;
+                               }
+
+                               wcross_scale_goal_prev = wcross_scale;
+                               wcross_alpha_goal_prev = wcross_alpha;
+                               wcross_color_goal_prev = wcross_color;
+
+                               if(shottype == SHOTTYPE_HITTEAM || (shottype == SHOTTYPE_HITOBSTRUCTION && cvar("crosshair_hittest_blur") && !cvar("chase_active")))
+                               {
+                                       wcross_blur = 1;
+                                       wcross_alpha *= 0.75;
+                               }
+                               else
+                                       wcross_blur = 0;
+                               // *_prev is at time-frametime
+                               // * is at wcross_changedonetime+f
+                               // what do we have at time?
+                               if(time < wcross_changedonetime)
+                               {
+                                       f = frametime / (wcross_changedonetime - time + frametime);
+                                       wcross_scale = f * wcross_scale + (1 - f) * wcross_scale_prev;
+                                       wcross_alpha = f * wcross_alpha + (1 - f) * wcross_alpha_prev;
+                                       wcross_color = f * wcross_color + (1 - f) * wcross_color_prev;
+                               }
+
+                               wcross_scale_prev = wcross_scale;
+                               wcross_alpha_prev = wcross_alpha;
+                               wcross_color_prev = wcross_color;
+
+                               wcross_scale *= 1 - cvar("_menu_alpha");
+                               wcross_alpha *= 1 - cvar("_menu_alpha");
+
+                               // ring around crosshair representing bullets left in camping rifle clip
+                               if (activeweapon == WEP_CAMPINGRIFLE)
+                               {
+                                       ring_scale = cvar("crosshair_campingrifle_ring_size");
+                                       bullets = bound(0, getstati(STAT_BULLETS_LOADED), 8);
+                               }
+                               else
+                                       bullets = 0;
+
+#define CROSSHAIR_DRAW_RING(i,j,sz,wcross_name,wcross_alpha) \
+                               drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size_x * ring_scale + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size_y * ring_scale + j * wcross_blur)), strcat("gfx/hud/rifle_ring_", ftos(bullets)), sz * wcross_size * ring_scale, wcross_color, wcross_alpha, DRAWFLAG_NORMAL)
+
+#define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \
+                               do \
+                               { \
+                                       if(wcross_blur > 0) \
+                                       { \
+                                               for(i = -2; i <= 2; ++i) \
+                                                       for(j = -2; j <= 2; ++j) \
+                                                               M(i,j,sz,wcross_name,wcross_alpha*0.04); \
+                                       } \
+                                       else \
+                                       { \
+                                               M(0,0,sz,wcross_name,wcross_alpha); \
+                                       } \
+                               } \
+                               while(0)
+
+#define CROSSHAIR_DRAW_SINGLE(i,j,sz,wcross_name,wcross_alpha) \
+                               drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size_x + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size_y + j * wcross_blur)), wcross_name, sz * wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL)
+
+#define CROSSHAIR_DRAW(sz,wcross_name,wcross_alpha) \
+                               CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_SINGLE,sz,wcross_name,wcross_alpha)
+
+                               if(time < wcross_name_changedonetime && wcross_name != wcross_name_goal_prev_prev && wcross_name_goal_prev_prev)
+                               {
+                                       f = (wcross_name_changedonetime - time) / (wcross_name_changedonetime - wcross_name_changestarttime);
+                                       wcross_size = drawgetimagesize(wcross_name_goal_prev_prev) * wcross_scale;
+                                       CROSSHAIR_DRAW(wcross_resolution_goal_prev_prev, wcross_name_goal_prev_prev, wcross_alpha * f * wcross_name_alpha_goal_prev_prev);
+                                       f = 1 - f;
+                               }
+                               else
+                               {
+                                       f = 1;
+                               }
+
+                               wcross_size = drawgetimagesize(wcross_name) * wcross_scale;
+                               if(bullets)
+                               {
+                                       CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_RING, wcross_resolution, wcross_name, wcross_alpha);
+                               }
+                               CROSSHAIR_DRAW(wcross_resolution, wcross_name, wcross_alpha * f);
+                               wcross_name_alpha_goal_prev = f;
+                       }
+               }
+               else
+               {
+                       wcross_scale_prev = 0;
+                       wcross_alpha_prev = 0;
+                       wcross_scale_goal_prev = 0;
+                       wcross_alpha_goal_prev = 0;
+                       wcross_changedonetime = 0;
+                       if(wcross_name_goal_prev)
+                               strunzone(wcross_name_goal_prev);
+                       wcross_name_goal_prev = string_null;
+                       if(wcross_name_goal_prev_prev)
+                               strunzone(wcross_name_goal_prev_prev);
+                       wcross_name_goal_prev_prev = string_null;
+                       wcross_name_changestarttime = 0;
+                       wcross_name_changedonetime = 0;
+                       wcross_name_alpha_goal_prev = 0;
+                       wcross_name_alpha_goal_prev_prev = 0;
+                       wcross_resolution_goal_prev = 0;
+                       wcross_resolution_goal_prev_prev = 0;
+               }
+       }
+
+       if(NextFrameCommand)
+       {
+               localcmd("\n", NextFrameCommand, "\n");
+               NextFrameCommand = string_null;
+       }
+
+       // we must do this check AFTER a frame was rendered, or it won't work
+       if(cs_project_is_b0rked == 0)
+       {
+               string w0, h0;
+               w0 = cvar_string("vid_conwidth");
+               h0 = cvar_string("vid_conheight");
+               //R_SetView(VF_VIEWPORT, '0 0 0', '640 480 0');
+               //R_SetView(VF_FOV, '90 90 0');
+               R_SetView(VF_ORIGIN, '0 0 0');
+               R_SetView(VF_ANGLES, '0 0 0');
+               R_SetView(VF_PERSPECTIVE, 1);
+               makevectors('0 0 0');
+               vector v1, v2;
+               cvar_set("vid_conwidth", "800");
+               cvar_set("vid_conheight", "600");
+               v1 = cs_project(v_forward);
+               cvar_set("vid_conwidth", "640");
+               cvar_set("vid_conheight", "480");
+               v2 = cs_project(v_forward);
+               if(v1 == v2)
+                       cs_project_is_b0rked = 1;
+               else
+                       cs_project_is_b0rked = -1;
+               cvar_set("vid_conwidth", w0);
+               cvar_set("vid_conheight", h0);
+       }
+
+       if(hudconf_active)
+               HUD_Panel_Mouse();
+       // be safe against triggerbots until everyone has the fixed engine
+       // this call is meant to overwrite the trace globals by something
+       // unsuspicious
+       traceline('0 0 0', '0 0 0', MOVE_WORLDONLY, world);
+}
+
+#define spider_h "gfx/vehicles/hud_bg.tga"
+#define spider_b "gfx/vehicles/sbot.tga"
+#define spider_r "gfx/vehicles/sbot_rpods.tga"
+#define spider_g "gfx/vehicles/sbot_mguns.tga"
+#define spider_s "gfx/vehicles/shiled.tga"
+#define spider_a1 "gfx/hud/sb_rocket.tga"
+#define spider_a2 "gfx/sb_bullets.tga"
+
+void CSQC_SPIDER_HUD()
+{
+       float rockets, reload, heat, hp, shield;
+       vector picsize, hudloc;
+
+    // Fetch health & ammo stats
+    hp      = bound(0,getstatf(STAT_VEHICLESTAT_HEALTH), 1);
+       shield  = bound(0,getstatf(STAT_VEHICLESTAT_SHIELD), 1);
+       heat    = min(getstatf(STAT_VEHICLESTAT_RELOAD1), 2);
+       rockets =     getstati(STAT_VEHICLESTAT_AMMO2);
+       reload  = min(getstatf(STAT_VEHICLESTAT_RELOAD2), 1);
+
+    // Draw the crosshairs
+    picsize = drawgetimagesize(SPIDER_CROSS);
+    picsize_x *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);
+    picsize_y *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);
+    drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), SPIDER_CROSS, picsize, '1 1 1', cvar_or("cl_vehicle_spiderbot_cross_alpha",0.6), DRAWFLAG_NORMAL);
+
+    hudloc_y =  4;
+    hudloc_x = 4;
+
+    picsize = drawgetimagesize(spider_h) * 0.5;
+    drawpic(hudloc, spider_h, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+    picsize = drawgetimagesize(spider_a2) * 0.5;
+    drawpic(hudloc + '120 96  0', spider_a2, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+    drawstring(hudloc + '145 19  0', strcat(ftos(rint(hp * 100)), "%"),'15 15 0','0 1 0', 1, DRAWFLAG_NORMAL);
+    drawstring(hudloc + '175 34  0', strcat(ftos(rint(shield * 100)), "%"),'15 15 0','0 0 1', 1, DRAWFLAG_NORMAL);
+    drawstring(hudloc + '136 102  0', strcat(ftos(100 - rint(heat * 100)), "%"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);
+
+    picsize = drawgetimagesize(spider_a1) * 0.85;
+    if(rockets == 9)
+    {
+        drawpic(hudloc + '132 54  0', spider_a1, picsize, '-1 -1 -1', 1, DRAWFLAG_NORMAL);
+        drawstring(hudloc + '179 69 0', strcat(ftos(rint(reload * 100)), "%"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + '132 54  0', spider_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        drawstring(hudloc + '179 69  0', strcat(ftos(9 - rockets), "/8"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);
+    }
+
+    picsize = drawgetimagesize(spider_b) * 0.5;
+    hudloc_y = 10.5;
+    hudloc_x = 10.5;
+
+    drawpic(hudloc, spider_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
+    drawpic(hudloc, spider_b, picsize, '0 1 0' * hp + '1 0 0' * (1 - hp), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, spider_r, picsize, '1 1 1' * reload + '1 0 0' * (1 - reload), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, spider_g, picsize, '1 1 1' * (1 - heat) + '1 0 0' *  heat, 1, DRAWFLAG_NORMAL);
+
+
+       /*
+       // Draw health bar
+       p = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));
+       p = p + '0 1 0' * vid_conheight - '0 32 0';
+       //pp = ('0 1 0' * hp) + ('1 0 0' * (1-hp));
+       drawfill(p, '256 0 0' * shield + '0 8 0' , '0.5 0.5 1', 0.75, DRAWFLAG_NORMAL);
+       p_y += 8;
+       drawfill(p, '256 0 0' * hp + '0 8 0' , '0 1 0', 0.75, DRAWFLAG_NORMAL);
+       p_x += 256 * hp;
+       drawfill(p, '256 0 0' * (1-hp) + '0 8 0' , '0 0 0', 0.75, DRAWFLAG_NORMAL);
+
+       // Draw minigun heat indicator
+       p = '0.5 0 0' * (vid_conwidth - 256);
+       p = p + '0 1 0' * vid_conheight - '0 34  0';
+       drawfill(p, '256 0 0' * (1-heat) + '0 2 0' ,'0 0 1', 0.5, DRAWFLAG_NORMAL);
+       p_x += 256 * (1-heat);
+       drawfill(p, '256 0 0' * heat  + '0 2 0' , '1 0 0', 0.5, DRAWFLAG_NORMAL);
+
+
+       // Draw rocket icons for loaded/empty tubes.
+       pp = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));
+       pp += '0 1 0' * vid_conheight - '0 64 0';
+       for(i = 0; i < 8; ++i)
+       {
+               p = pp + '1 0 0' * (rkt_size * i);
+               if(rockets == 8)
+               {
+                       if(floor(reload * 8) == i)
+                       {
+                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '1 0 0' + '0 1 0' * ((reload*8)-i), 0.75 , DRAWFLAG_NORMAL);
+                       }
+                       else if(i < reload * 8)
+                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '1 1 0', 0.75 , DRAWFLAG_NORMAL);
+                       else
+                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0.5 0.5 0.5', 0.75, DRAWFLAG_NORMAL);
+               }
+               else
+               {
+                       if(i < rockets)
+                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0 0 0', 0.25, DRAWFLAG_NORMAL);
+                       else
+                               drawpic(p, spider_rocket_icon, '1 1 0' * rkt_size, '0 1 0' * reload, 0.75, DRAWFLAG_NORMAL);
+               }
+       }
+       */
+
+       if (scoreboard_showscores)
+       {
+               HUD_DrawScoreboard();
+               HUD_DrawCenterPrint();
+       }
+
+}
+
+#define raptor_h "gfx/vehicles/hud_bg.tga"
+#define raptor_b "gfx/vehicles/raptor.tga"
+#define raptor_g1 "gfx/vehicles/raptor_guns.tga"
+#define raptor_g2 "gfx/vehicles/raptor_bombs.tga"
+#define raptor_s "gfx/vehicles/shiled.tga"
+
+void CSQC_RAPTOR_HUD()
+{
+       float rockets, reload, heat, hp, shield, energy;
+       vector picsize, hudloc;
+
+    // Fetch health & ammo stats
+    hp      = bound(0,getstatf(STAT_VEHICLESTAT_HEALTH), 1);
+       shield  = bound(0,getstatf(STAT_VEHICLESTAT_SHIELD), 1);
+       reload  = min(getstatf(STAT_VEHICLESTAT_RELOAD1), 1);
+       energy  = min(getstatf(STAT_VEHICLESTAT_ENERGY),  1);
+
+    // Draw the crosshairs
+    picsize = drawgetimagesize(SPIDER_CROSS);
+    picsize_x *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);
+    picsize_y *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);
+    drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), SPIDER_CROSS, picsize, '1 1 1', cvar_or("cl_vehicle_spiderbot_cross_alpha",0.6), DRAWFLAG_NORMAL);
+
+    hudloc_y =  4;
+    hudloc_x = 4;
+
+    picsize = drawgetimagesize(raptor_h) * 0.5;
+    drawpic(hudloc, raptor_h, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+    picsize = drawgetimagesize(spider_a2) * 0.5;
+    drawpic(hudloc + '120 96  0', spider_a2, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+    drawstring(hudloc + '145 19  0', strcat(ftos(rint(hp * 100)), "%"),'15 15 0','0 1 0', 1, DRAWFLAG_NORMAL);
+    drawstring(hudloc + '175 34  0', strcat(ftos(rint(shield * 100)), "%"),'15 15 0','0 0 1', 1, DRAWFLAG_NORMAL);
+    drawstring(hudloc + '136 102 0', strcat(ftos(rint(energy * 100)), "%"),'15 15 0','0.5 0.5 1', 1, DRAWFLAG_NORMAL);
+
+
+    picsize = drawgetimagesize(spider_a1) * 0.85;
+    if(reload == 1)
+    {
+        drawpic(hudloc + '132 54  0', spider_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        drawstring(hudloc + '179 69  0', strcat(ftos(rint(reload * 100)), "%"),'14 14 0','0 1 0', 0.5, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + '132 54  0', spider_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        drawstring(hudloc + '179 69  0', strcat(ftos(rint(reload * 100)), "%"),'14 14 0','0 0 1', 1, DRAWFLAG_NORMAL);
+    }
+
+    picsize = drawgetimagesize(raptor_b) * 0.5;
+    hudloc_y = 10.5;
+    hudloc_x = 10.5;
+
+    drawpic(hudloc, raptor_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
+    drawpic(hudloc, raptor_b, picsize, '0 1 0' * hp + '1 0 0' * (1 - hp), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, raptor_g1, picsize, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, raptor_g2, picsize, '1 1 1' * reload + '1 0 0' *  (1 - reload), 1, DRAWFLAG_NORMAL);
+
+
+       if (scoreboard_showscores)
+       {
+               HUD_DrawScoreboard();
+               HUD_DrawCenterPrint();
+       }
+
+}
+
+#define waki_h "gfx/vehicles/hud_bg.tga"
+#define waki_b "gfx/vehicles/waki.tga"
+#define waki_e "gfx/vehicles/waki_e.tga"
+#define waki_g "gfx/vehicles/waki_guns.tga"
+#define waki_r "gfx/vehicles/waki_rockets.tga"
+#define waki_s "gfx/vehicles/shiled.tga"
+
+#define waki_a1 "gfx/hud/sb_rocket.tga"
+#define waki_a2 "gfx/sb_cells.tga"
+
+void CSQC_WAKIZASHI_HUD()
+{
+       // 0--1 floats. 1 = 100%, 0.6 = 50%.
+       float health, shield, energy, rockets;
+       vector picsize, hudloc;
+
+    picsize = drawgetimagesize(SPIDER_CROSS);
+    picsize_x *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);
+    picsize_y *= cvar_or("cl_vehicle_spiderbot_cross_size", 1);
+    drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), SPIDER_CROSS, picsize, '1 1 1', cvar_or("cl_vehicle_spiderbot_cross_alpha",0.6), DRAWFLAG_NORMAL);
+
+/*
+const float STAT_VEHICLESTAT_HEALTH  = 60;
+const float STAT_VEHICLESTAT_SHIELD  = 61;
+const float STAT_VEHICLESTAT_ENERGY  = 62;
+const float STAT_VEHICLESTAT_AMMO1   = 63;
+const float STAT_VEHICLESTAT_RELAOD1 = 64;
+const float STAT_VEHICLESTAT_AMMO2   = 65;
+const float STAT_VEHICLESTAT_RELOAD2 = 66;
+*/
+    health  = min(getstatf(STAT_VEHICLESTAT_HEALTH),  1);
+       shield  = min(getstatf(STAT_VEHICLESTAT_SHIELD),  1);
+       energy  = min(getstatf(STAT_VEHICLESTAT_ENERGY),  1);
+       rockets = bound(0,getstatf(STAT_VEHICLESTAT_RELOAD1), 1);
+
+    hudloc_y =  4;
+    hudloc_x = 4;
+
+    picsize = drawgetimagesize(waki_h) * 0.5;
+    drawpic(hudloc, waki_h, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+    picsize = drawgetimagesize(waki_a2) * 0.7;
+    drawpic(hudloc + '116 92  0', waki_a2, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+
+
+    drawstring(hudloc + '145 19  0', strcat(ftos(rint(health * 100)), "%"),'15 15 0','0 1 0', 1, DRAWFLAG_NORMAL);
+    drawstring(hudloc + '175 34  0', strcat(ftos(rint(shield * 100)), "%"),'15 15 0','0 0 1', 1, DRAWFLAG_NORMAL);
+
+    drawstring(hudloc + '136 102  0', strcat(ftos(rint(energy * 100)), "%"),'14 14 0','1 1 1', 1, DRAWFLAG_NORMAL);
+
+    picsize = drawgetimagesize(waki_a1) * 0.75;
+    if(rockets == 1)
+    {
+        drawpic(hudloc + '140 55  0', waki_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+        drawpic(hudloc + '144 59  0', waki_a1, picsize, '1 1 1', 1, DRAWFLAG_NORMAL);
+    }
+    else
+    {
+        drawpic(hudloc + '140 55  0', waki_a1, picsize, '-1 -1 -1', 1, DRAWFLAG_NORMAL);
+        drawpic(hudloc + '144 59  0', waki_a1, picsize, '-1 -1 -1', 1, DRAWFLAG_NORMAL);
+        drawstring(hudloc + '165 69 0', strcat(ftos(rint(rockets * 100)), "%"),'14 14 0','1 1 0', 1, DRAWFLAG_NORMAL);
+    }
+
+    picsize = drawgetimagesize(waki_b) * 0.5;
+    hudloc_y = 10.5;
+    hudloc_x = 10.5;
+
+    drawpic(hudloc, waki_s, picsize, '1 1 1', shield, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_b, picsize, '0 1 0' * health + '1 0 0' * (1 - health), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_r, picsize, '1 1 1' * rockets + '1 0 0' * (1 - rockets), 1, DRAWFLAG_NORMAL);
+    drawpic(hudloc, waki_e, picsize, '1 1 1' * energy + '1 0 0' *  (1 - energy), 1, DRAWFLAG_NORMAL);
+
+
+
+       /*
+       p = '0.5 0 0' * (vid_conwidth - (rkt_size * 8));
+       p = p + '0 1 0' * vid_conheight - '0 32 0';
+
+       // Draw health bar
+       p_y += 8;
+       drawfill(p, '256 0 0' * health + '0 8 0' , '0 0.7 0', 0.75, DRAWFLAG_NORMAL);
+       p_x += 256 * health;
+       drawfill(p, '256 0 0' * (1 - health) + '0 8 0' , '0 0 0', 0.75, DRAWFLAG_NORMAL);
+
+       // Draw shiled bar
+       p_x -= 256 * health;
+       p_y += 4;
+       drawfill(p, '256 0 0' * shield + '0 4 0' , '0.25 0.25 1', 0.5, DRAWFLAG_NORMAL);
+
+       // Draw energy
+       //p_x -= 256 * health;
+       p_y -= 8;
+       drawfill(p, '256 0 0' * energy + '0 4 0' , '1 1 1', 0.75, DRAWFLAG_NORMAL);
+
+       // Draw rockets bar
+       p_y += 12;
+       drawfill(p, '256 0 0' * rockets + '0 4 0' , '1 0 0', 0.75, DRAWFLAG_NORMAL);
+       */
+
+
+
+
+       if (scoreboard_showscores)
+       {
+               HUD_DrawScoreboard();
+               HUD_DrawCenterPrint();
+       }
+
+}
+
+
+void CSQC_common_hud(void)
+{
+       // HUD_SortFrags(); done in HUD_Draw
+       float hud;
+       hud = getstati(STAT_HUD);
+
+       //hud = 10;
+       switch(hud)
+       {
+               case HUD_NORMAL:
+                       // hud first
+                       HUD_Main();
+
+                       // scoreboard/accuracy
+                       if (intermission == 2 && !scoreboard_showaccuracy && !scoreboard_showscores) // map voting screen
+                       {
+                               HUD_FinaleOverlay();
+                               HUD_Reset();
+                       }
+                       else if(scoreboard_showaccuracy && spectatee_status != -1)
+                               HUD_DrawAccuracyStats();
+                       else
+                               HUD_DrawScoreboard();
+
+                       if (scoreboard_showscores || scoreboard_showaccuracy || scoreboard_showscores_force || getstati(STAT_HEALTH) <= 0 || intermission == 1)
+                               HUD_Reset();
+
+                       break;
+
+               case HUD_SPIDERBOT:
+                       CSQC_SPIDER_HUD();
+                       break;
+
+               case HUD_WAKIZASHI:
+                       CSQC_WAKIZASHI_HUD();
+                       break;
+       }
+}
+
+
+// following vectors must be global to allow seamless switching between camera modes
+vector camera_offset, current_camera_offset, mouse_angles, current_angles, current_origin, current_position;
+void CSQC_Demo_Camera()
+{
+       float speed, attenuation, dimensions;
+       vector tmp, delta;
+
+       if( cvar("camera_reset") || !camera_mode )
+       {
+               camera_offset = '0 0 0';
+               current_angles = '0 0 0';
+               camera_direction = '0 0 0';
+               camera_offset_z += 30;
+               camera_offset_x += 30 * -cos(current_angles_y * DEG2RAD);
+               camera_offset_y += 30 * -sin(current_angles_y * DEG2RAD);
+               current_origin = view_origin;
+               current_camera_offset  = camera_offset;
+               cvar_set("camera_reset", "0");
+               camera_mode = CAMERA_CHASE;
+       }
+
+       // Camera angles
+       if( camera_roll )
+               mouse_angles_z += camera_roll * cvar("camera_speed_roll");
+
+       if(cvar("camera_look_player"))
+       {
+               local vector dir;
+               local float n;
+
+               dir = normalize(view_origin - current_position);
+               n = mouse_angles_z;
+               mouse_angles = vectoangles(dir);
+               mouse_angles_x = mouse_angles_x * -1;
+               mouse_angles_z = n;
+       }
+       else
+       {
+               tmp = getmousepos() * 0.1;
+               if(vlen(tmp)>cvar("camera_mouse_treshold"))
+               {
+                       mouse_angles_x += tmp_y * cos(mouse_angles_z * DEG2RAD) + (tmp_x * sin(mouse_angles_z * DEG2RAD));
+                       mouse_angles_y -= tmp_x * cos(mouse_angles_z * DEG2RAD) + (tmp_y * -sin(mouse_angles_z * DEG2RAD));
+               }
+       }
+
+       while (mouse_angles_x < -180) mouse_angles_x = mouse_angles_x + 360;
+       while (mouse_angles_x > 180) mouse_angles_x = mouse_angles_x - 360;
+       while (mouse_angles_y < -180) mouse_angles_y = mouse_angles_y + 360;
+       while (mouse_angles_y > 180) mouse_angles_y = mouse_angles_y - 360;
+
+       // Fix difference when angles don't have the same sign
+       delta = '0 0 0';
+       if(mouse_angles_y < -60 && current_angles_y > 60)
+               delta = '0 360 0';
+       if(mouse_angles_y > 60 && current_angles_y < -60)
+               delta = '0 -360 0';
+
+       if(cvar("camera_look_player"))
+               attenuation = cvar("camera_look_attenuation");
+       else
+               attenuation = cvar("camera_speed_attenuation");
+
+       attenuation = 1 / max(1, attenuation);
+       current_angles += (mouse_angles - current_angles + delta) * attenuation;
+
+       while (current_angles_x < -180) current_angles_x = current_angles_x + 360;
+       while (current_angles_x > 180) current_angles_x = current_angles_x - 360;
+       while (current_angles_y < -180) current_angles_y = current_angles_y + 360;
+       while (current_angles_y > 180) current_angles_y = current_angles_y - 360;
+
+       // Camera position
+       tmp = '0 0 0';
+       dimensions = 0;
+
+       if( camera_direction_x )
+       {
+               tmp_x = camera_direction_x * cos(current_angles_y * DEG2RAD);
+               tmp_y = camera_direction_x * sin(current_angles_y * DEG2RAD);
+               if( cvar("camera_forward_follows") && !cvar("camera_look_player") )
+                       tmp_z = camera_direction_x * -sin(current_angles_x * DEG2RAD);
+               ++dimensions;
+       }
+
+       if( camera_direction_y )
+       {
+               tmp_x += camera_direction_y * -sin(current_angles_y * DEG2RAD);
+               tmp_y += camera_direction_y * cos(current_angles_y * DEG2RAD) * cos(current_angles_z * DEG2RAD);
+               tmp_z += camera_direction_y * sin(current_angles_z * DEG2RAD);
+               ++dimensions;
+       }
+
+       if( camera_direction_z )
+       {
+               tmp_z += camera_direction_z * cos(current_angles_z * DEG2RAD);
+               ++dimensions;
+       }
+
+       if(cvar("camera_free"))
+               speed = cvar("camera_speed_free");
+       else
+               speed = cvar("camera_speed_chase");
+
+       if(dimensions)
+       {
+               speed = speed * sqrt(1 / dimensions);
+               camera_offset += tmp * speed;
+       }
+
+       current_camera_offset += (camera_offset - current_camera_offset) * attenuation;
+
+       // Camera modes
+       if( cvar("camera_free") )
+       {
+               if ( camera_mode == CAMERA_CHASE )
+               {
+                       current_camera_offset = current_origin + current_camera_offset;
+                       camera_offset = current_origin + camera_offset;
+               }
+
+               camera_mode = CAMERA_FREE;
+               current_position = current_camera_offset;
+       }
+       else
+       {
+               if ( camera_mode == CAMERA_FREE )
+               {
+                       current_origin = view_origin;
+                       camera_offset = camera_offset - current_origin;
+                       current_camera_offset = current_camera_offset - current_origin;
+               }
+
+               camera_mode = CAMERA_CHASE;
+
+               if(cvar("camera_chase_smoothly"))
+                       current_origin += (view_origin - current_origin) * attenuation;
+               else
+                       current_origin = view_origin;
+
+               current_position = current_origin + current_camera_offset;
+       }
+
+       R_SetView(VF_ANGLES, current_angles);
+       R_SetView(VF_ORIGIN, current_position);
+}