From: Mario Date: Wed, 23 Oct 2013 08:50:49 +0000 (+1100) Subject: New vehicle system based on weapons system X-Git-Tag: xonotic-v0.8.2~2059^2~26 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=23ab6599859e8a4b53501c8635b987bc1c33b771 New vehicle system based on weapons system --- diff --git a/qcsrc/client/Main.qc b/qcsrc/client/Main.qc index 8e36cc9b54..b7ffa61aa5 100644 --- a/qcsrc/client/Main.qc +++ b/qcsrc/client/Main.qc @@ -104,6 +104,7 @@ void CSQC_Init(void) // needs to be done so early because of the constants they create CALL_ACCUMULATED_FUNCTION(RegisterWeapons); + CALL_ACCUMULATED_FUNCTION(RegisterVehicles); CALL_ACCUMULATED_FUNCTION(RegisterGametypes); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); @@ -121,7 +122,6 @@ void CSQC_Init(void) GibSplash_Precache(); Casings_Precache(); DamageInfo_Precache(); - Vehicles_Precache(); turrets_precache(); Tuba_Precache(); CSQCPlayer_Precache(); diff --git a/qcsrc/client/View.qc b/qcsrc/client/View.qc index 46920a4174..2516a369e4 100644 --- a/qcsrc/client/View.qc +++ b/qcsrc/client/View.qc @@ -353,8 +353,6 @@ const float CAMERA_FREE = 1; const float CAMERA_CHASE = 2; float reticle_type; string NextFrameCommand; -void CSQC_SPIDER_HUD(); -void CSQC_RAPTOR_HUD(); vector freeze_org, freeze_ang; entity nightvision_noise, nightvision_noise2; @@ -1566,18 +1564,7 @@ void CSQC_UpdateView(float w, float h) HUD_Panel_Mouse(); if(hud && !intermission) - { - 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(hud == HUD_BUMBLEBEE) - CSQC_BUMBLE_HUD(); - else if(hud == HUD_BUMBLEBEE_GUN) - CSQC_BUMBLE_GUN_HUD(); - } + VEH_ACTION(hud, VR_HUD); cl_notice_run(); @@ -1602,22 +1589,6 @@ void CSQC_common_hud(void) HUD_FinaleOverlay(); HUD_Reset(); } - /* - switch(hud) - { - case HUD_SPIDERBOT: - CSQC_SPIDER_HUD(); - break; - - case HUD_WAKIZASHI: - CSQC_WAKIZASHI_HUD(); - break; - - case HUD_BUMBLEBEE: - CSQC_BUMBLE_HUD(); - break; - } - */ } diff --git a/qcsrc/client/autocvars.qh b/qcsrc/client/autocvars.qh index 8175695abb..c0e49d65e3 100644 --- a/qcsrc/client/autocvars.qh +++ b/qcsrc/client/autocvars.qh @@ -71,9 +71,6 @@ var float autocvar_cl_spawnzoom = 1; var float autocvar_cl_spawnzoom_speed = 1; var float autocvar_cl_spawnzoom_factor = 2; float autocvar_cl_stripcolorcodes; -var float autocvar_cl_vehicle_spiderbot_cross_alpha = 0.6; -var float autocvar_cl_vehicle_spiderbot_cross_size = 1; -var float autocvar_cl_vehicles_hud_tactical = 1; float autocvar_cl_velocityzoom; var float autocvar_cl_velocityzoom_type = 3; float autocvar_cl_velocityzoom_speed; diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index fa61033f65..3db4e4e30a 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -49,7 +49,7 @@ tturrets.qh ../server/tturrets/include/turrets_early.qh ../server/movelib.qc main.qh -vehicles/vehicles.qh +../common/vehicles/vehicles_include.qh ../common/csqcmodel_settings.qh ../csqcmodellib/common.qh ../csqcmodellib/cl_model.qh @@ -85,8 +85,7 @@ modeleffects.qc tuba.qc target_music.qc -vehicles/vehicles.qc -../server/vehicles/bumblebee.qc +../common/vehicles/vehicles_include.qc shownames.qh shownames.qc diff --git a/qcsrc/client/tturrets.qc b/qcsrc/client/tturrets.qc index 161bfa385a..a8ebd03c1f 100644 --- a/qcsrc/client/tturrets.qc +++ b/qcsrc/client/tturrets.qc @@ -257,21 +257,13 @@ void turret_draw2d() o_z = 0; if(hud != HUD_NORMAL) { - switch(hud) - { - case HUD_SPIDERBOT: - case HUD_WAKIZASHI: - case HUD_RAPTOR: - case HUD_BUMBLEBEE: - if(self.turret_type == TID_EWHEEL || self.turret_type == TID_WALKER) - txt = "gfx/vehicles/vth-mover.tga"; - else - txt = "gfx/vehicles/vth-stationary.tga"; + if(self.turret_type == TID_EWHEEL || self.turret_type == TID_WALKER) + txt = "gfx/vehicles/vth-mover.tga"; + else + txt = "gfx/vehicles/vth-stationary.tga"; - vector pz = drawgetimagesize(txt) * 0.25; - drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.75, DRAWFLAG_NORMAL); - break; - } + vector pz = drawgetimagesize(txt) * 0.25; + drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.75, DRAWFLAG_NORMAL); } } diff --git a/qcsrc/client/vehicles/racer.qc b/qcsrc/client/vehicles/racer.qc deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/qcsrc/client/vehicles/raptor.qc b/qcsrc/client/vehicles/raptor.qc deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/qcsrc/client/vehicles/spiderbot.qc b/qcsrc/client/vehicles/spiderbot.qc deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/qcsrc/client/vehicles/vehicles.qc b/qcsrc/client/vehicles/vehicles.qc deleted file mode 100644 index c95185d74c..0000000000 --- a/qcsrc/client/vehicles/vehicles.qc +++ /dev/null @@ -1,1042 +0,0 @@ -#define hud_bg "gfx/vehicles/frame.tga" -#define hud_sh "gfx/vehicles/vh-shield.tga" - -#define hud_hp_bar "gfx/vehicles/bar_up_left.tga" -#define hud_hp_ico "gfx/vehicles/health.tga" -#define hud_sh_bar "gfx/vehicles/bar_dwn_left.tga" -#define hud_sh_ico "gfx/vehicles/shield.tga" - -#define hud_ammo1_bar "gfx/vehicles/bar_up_right.tga" -#define hud_ammo1_ico "gfx/vehicles/bullets.tga" -#define hud_ammo2_bar "gfx/vehicles/bar_dwn_right.tga" -#define hud_ammo2_ico "gfx/vehicles/rocket.tga" -#define hud_energy "gfx/vehicles/energy.tga" - -#define SBRM_FIRST 1 -#define SBRM_VOLLY 1 -#define SBRM_GUIDE 2 -#define SBRM_ARTILLERY 3 -#define SBRM_LAST 3 - -#define RSM_FIRST 1 -#define RSM_BOMB 1 -#define RSM_FLARE 2 -#define RSM_LAST 2 - -entity dropmark; -var float autocvar_cl_vehicles_hudscale = 0.5; -var float autocvar_cl_vehicles_hudalpha = 0.75; - -#define raptor_ico "gfx/vehicles/raptor.tga" -#define raptor_gun "gfx/vehicles/raptor_guns.tga" -#define raptor_bomb "gfx/vehicles/raptor_bombs.tga" -#define raptor_drop "gfx/vehicles/axh-dropcross.tga" -string raptor_xhair; - -void CSQC_WAKIZASHI_HUD(); -void CSQC_SPIDER_HUD(); -void CSQC_RAPTOR_HUD(); -void CSQC_BUMBLE_HUD(); -void CSQC_BUMBLE_GUN_HUD(); - -#define MAX_AXH 4 -entity AuxiliaryXhair[MAX_AXH]; - -.string axh_image; -.float axh_fadetime; -.float axh_drawflag; -.float axh_scale; - -#define bumb_ico "gfx/vehicles/bumb.tga" -#define bumb_lgun "gfx/vehicles/bumb_lgun.tga" -#define bumb_rgun "gfx/vehicles/bumb_rgun.tga" - -#define bumb_gun_ico "gfx/vehicles/bumb_side.tga" -#define bumb_gun_gun "gfx/vehicles/bumb_side_gun.tga" - -#define spider_ico "gfx/vehicles/sbot.tga" -#define spider_rkt "gfx/vehicles/sbot_rpods.tga" -#define spider_mgun "gfx/vehicles/sbot_mguns.tga" -string spider_xhair; // = "gfx/vehicles/axh-special1.tga"; - -#define waki_ico "gfx/vehicles/waki.tga" -#define waki_eng "gfx/vehicles/waki_e.tga" -#define waki_gun "gfx/vehicles/waki_guns.tga" -#define waki_rkt "gfx/vehicles/waki_rockets.tga" -#define waki_xhair "gfx/vehicles/axh-special1.tga" - -float alarm1time; -float alarm2time; -float weapon2mode; - -void AuxiliaryXhair_Draw2D() -{ - vector loc, psize; - - psize = self.axh_scale * draw_getimagesize(self.axh_image); - loc = project_3d_to_2d(self.move_origin) - 0.5 * psize; - if not (loc_z < 0 || loc_x < 0 || loc_y < 0 || loc_x > vid_conwidth || loc_y > vid_conheight) - { - loc_z = 0; - psize_z = 0; - drawpic(loc, self.axh_image, psize, self.colormod, self.alpha, self.axh_drawflag); - } - - if(time - self.cnt > self.axh_fadetime) - self.draw2d = func_null; -} - -void Net_AuXair2(float bIsNew) -{ - float axh_id = bound(0, ReadByte(), MAX_AXH); - entity axh = AuxiliaryXhair[axh_id]; - - if(axh == world || wasfreed(axh)) // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?) - { - axh = spawn(); - axh.draw2d = func_null; - axh.drawmask = MASK_NORMAL; - axh.axh_drawflag = DRAWFLAG_ADDITIVE; - axh.axh_fadetime = 0.1; - axh.axh_image = "gfx/vehicles/axh-ring.tga"; - axh.axh_scale = 1; - axh.alpha = 1; - AuxiliaryXhair[axh_id] = axh; - } - - axh.move_origin_x = ReadCoord(); - axh.move_origin_y = ReadCoord(); - axh.move_origin_z = ReadCoord(); - axh.colormod_x = ReadByte() / 255; - axh.colormod_y = ReadByte() / 255; - axh.colormod_z = ReadByte() / 255; - axh.cnt = time; - axh.draw2d = AuxiliaryXhair_Draw2D; -} - -void Net_VehicleSetup() -{ - - float i; - - float hud_id = ReadByte(); - - // Weapon update? - if(hud_id > HUD_VEHICLE_LAST) - { - weapon2mode = hud_id - HUD_VEHICLE_LAST; - return; - } - - // hud_id == 0 means we exited a vehicle, so stop alarm sound/s - if(hud_id == 0) - { - sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - return; - } - - hud_id = bound(HUD_VEHICLE_FIRST, hud_id, HUD_VEHICLE_LAST); - - // Init auxiliary crosshairs - entity axh; - for(i = 0; i < MAX_AXH; ++i) - { - axh = AuxiliaryXhair[i]; - if(axh != world && !wasfreed(axh)) // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?) - remove(axh); - - axh = spawn(); - axh.draw2d = func_null; - axh.drawmask = MASK_NORMAL; - axh.axh_drawflag = DRAWFLAG_NORMAL; - axh.axh_fadetime = 0.1; - axh.axh_image = "gfx/vehicles/axh-ring.tga"; - axh.axh_scale = 1; - axh.alpha = 1; - AuxiliaryXhair[i] = axh; - } - - switch(hud_id) - { - case HUD_SPIDERBOT: - // Minigun1 - AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-ring.tga"; - AuxiliaryXhair[0].axh_scale = 0.25; - // Minigun2 - AuxiliaryXhair[1].axh_image = "gfx/vehicles/axh-ring.tga"; - AuxiliaryXhair[1].axh_scale = 0.25; - // Rocket - AuxiliaryXhair[2].axh_image = "gfx/vehicles/axh-special1.tga"; - AuxiliaryXhair[2].axh_scale = 0.5; - break; - - case HUD_WAKIZASHI: - AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-bracket.tga"; - AuxiliaryXhair[0].axh_scale = 0.25; - break; - - case HUD_RAPTOR: - AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-special2.tga"; - AuxiliaryXhair[0].axh_scale = 0.5; - //AuxiliaryXhair[0].alpha = 0.5; - - AuxiliaryXhair[1].axh_image = "gfx/vehicles/axh-bracket.tga"; - AuxiliaryXhair[1].axh_scale = 0.25; - //AuxiliaryXhair[1].alpha = 0.75; - //AuxiliaryXhair[1].axh_drawflag = DRAWFLAG_NORMAL; - break; - - case HUD_BUMBLEBEE: - // Raygun-locked - AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-bracket.tga"; - AuxiliaryXhair[0].axh_scale = 0.5; - - // Gunner1 - AuxiliaryXhair[1].axh_image = "gfx/vehicles/axh-target.tga"; - AuxiliaryXhair[1].axh_scale = 0.75; - - // Gunner2 - AuxiliaryXhair[2].axh_image = "gfx/vehicles/axh-target.tga"; - AuxiliaryXhair[2].axh_scale = 0.75; - break; - case HUD_BUMBLEBEE_GUN: - // Plasma cannons - AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-bracket.tga"; - AuxiliaryXhair[0].axh_scale = 0.25; - // Raygun - AuxiliaryXhair[1].axh_image = "gfx/vehicles/axh-bracket.tga"; - AuxiliaryXhair[1].axh_scale = 0.25; - break; - } -} -#define HUD_GETSTATS \ - local noref float vh_health = getstati(STAT_VEHICLESTAT_HEALTH); \ - local noref float shield = getstati(STAT_VEHICLESTAT_SHIELD); \ - local noref float energy = getstati(STAT_VEHICLESTAT_ENERGY); \ - local noref float ammo1 = getstati(STAT_VEHICLESTAT_AMMO1); \ - local noref float reload1 = getstati(STAT_VEHICLESTAT_RELOAD1); \ - local noref float ammo2 = getstati(STAT_VEHICLESTAT_AMMO2); \ - local noref float reload2 = getstati(STAT_VEHICLESTAT_RELOAD2); - -void CSQC_BUMBLE_HUD() -{ -/* - 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' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL); - drawpic(hudloc, waki_e, picsize, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); -*/ - if(autocvar_r_letterbox) - return; - - vector picsize, hudloc = '0 0 0', pic2size, picloc; - - // Fetch health & ammo stats - HUD_GETSTATS - - picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale; - hudloc_y = vid_conheight - picsize_y; - hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5; - - drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL); - - shield *= 0.01; - vh_health *= 0.01; - energy *= 0.01; - reload1 *= 0.01; - - pic2size = draw_getimagesize(bumb_ico) * (autocvar_cl_vehicles_hudscale * 0.8); - picloc = picsize * 0.5 - pic2size * 0.5; - - if(vh_health < 0.25) - drawpic(hudloc + picloc, bumb_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, bumb_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL); - - drawpic(hudloc + picloc, bumb_lgun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, bumb_lgun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL); - -// Health bar - picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale; - picloc = '69 69 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight); - drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale; - picloc = '37 65 0' * autocvar_cl_vehicles_hudscale; - if(vh_health < 0.25) - { - if(alarm1time < time) - { - alarm1time = time + 2; - sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE); - } - - drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - } - else - { - drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - if(alarm1time) - { - sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - alarm1time = 0; - } - } - -// Shield bar - picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale; - picloc = '69 140 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight); - drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picloc = '40 136 0' * autocvar_cl_vehicles_hudscale; - picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale; - if(shield < 0.25) - { - if(alarm2time < time) - { - alarm2time = time + 1; - sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE); - } - drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - } - else - { - drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - if(alarm2time) - { - sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - alarm2time = 0; - } - } - - ammo1 *= 0.01; - ammo2 *= 0.01; - -// Gunner1 bar - picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale; - picloc = '450 69 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * ammo1, vid_conheight); - drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); - -// Right gunner slot occupied? - if(!AuxiliaryXhair[1].draw2d) - { - shield = (picsize_x * 0.5) - (0.5 * stringwidth(_("No right gunner!"), FALSE, '1 0 0' * picsize_y + '0 1 0' * picsize_y)); - drawfill(hudloc + picloc - '0.2 0.2 0', picsize + '0.4 0.4 0', '0.25 0.25 0.25', 0.75, DRAWFLAG_NORMAL); - drawstring(hudloc + picloc + '1 0 0' * shield, _("No right gunner!"), '1 0 0' * picsize_y + '0 1 0' * picsize_y, '1 0 0' + '0 1 1' * sin(time * 10), 1, DRAWFLAG_NORMAL); - } - -// .. and icon - picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale; - picloc = '664 60 0' * autocvar_cl_vehicles_hudscale; - if(ammo1 < 0.2) - drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - -// Gunner2 bar - picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale; - picloc = '450 140 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * ammo2, vid_conheight); - drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// Left gunner slot occupied? - if(!AuxiliaryXhair[2].draw2d) - { - shield = (picsize_x * 0.5) - (0.5 * stringwidth(_("No left gunner!"), FALSE, '1 0 0' * picsize_y + '0 1 0' * picsize_y)); - drawfill(hudloc + picloc - '0.2 0.2 0', picsize + '0.4 0.4 0', '0.25 0.25 0.25', 0.75, DRAWFLAG_NORMAL); - drawstring(hudloc + picloc + '1 0 0' * shield, _("No left gunner!"), '1 0 0' * picsize_y + '0 1 0' * picsize_y, '1 0 0' + '0 1 1' * sin(time * 10), 1, DRAWFLAG_NORMAL); - } - -// .. and icon - picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale; - picloc = '664 130 0' * autocvar_cl_vehicles_hudscale; - if(ammo2 < 0.2) - drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - - if (scoreboard_showscores) - HUD_DrawScoreboard(); - else - { - picsize = draw_getimagesize(waki_xhair); - picsize_x *= 0.5; - picsize_y *= 0.5; - drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - } - -} - -void CSQC_BUMBLE_GUN_HUD() -{ - - if(autocvar_r_letterbox) - return; - - vector picsize, hudloc = '0 0 0', pic2size, picloc; - - // Fetch health & ammo stats - HUD_GETSTATS - - picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale; - hudloc_y = vid_conheight - picsize_y; - hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5; - - drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL); - - shield *= 0.01; - vh_health *= 0.01; - energy *= 0.01; - reload1 *= 0.01; - - pic2size = draw_getimagesize(bumb_gun_ico) * (autocvar_cl_vehicles_hudscale * 0.8); - picloc = picsize * 0.5 - pic2size * 0.5; - - if(vh_health < 0.25) - drawpic(hudloc + picloc, bumb_gun_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, bumb_gun_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL); - - drawpic(hudloc + picloc, bumb_gun_gun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL); - -// Health bar - picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale; - picloc = '69 69 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight); - drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale; - picloc = '37 65 0' * autocvar_cl_vehicles_hudscale; - if(vh_health < 0.25) - { - if(alarm1time < time) - { - alarm1time = time + 2; - sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE); - } - - drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - } - else - { - drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - if(alarm1time) - { - sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - alarm1time = 0; - } - } - -// Shield bar - picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale; - picloc = '69 140 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight); - drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picloc = '40 136 0' * autocvar_cl_vehicles_hudscale; - picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale; - if(shield < 0.25) - { - if(alarm2time < time) - { - alarm2time = time + 1; - sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE); - } - drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - } - else - { - drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - if(alarm2time) - { - sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - alarm2time = 0; - } - } - -// Gun bar - picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale; - picloc = '450 69 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * energy, vid_conheight); - drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); - -// .. and icon - picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale; - picloc = '664 60 0' * autocvar_cl_vehicles_hudscale; - if(energy < 0.2) - drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - - if (scoreboard_showscores) - HUD_DrawScoreboard(); - /* - else - { - picsize = draw_getimagesize(waki_xhair); - picsize_x *= 0.5; - picsize_y *= 0.5; - - - drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - } - */ -} - - - -void CSQC_SPIDER_HUD() -{ - if(autocvar_r_letterbox) - return; - - vector picsize, hudloc = '0 0 0', pic2size, picloc; - float i; - - // Fetch health & ammo stats - HUD_GETSTATS - - picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale; - hudloc_y = vid_conheight - picsize_y; - hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5; - - drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL); - - ammo1 *= 0.01; - shield *= 0.01; - vh_health *= 0.01; - reload2 *= 0.01; - - pic2size = draw_getimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8); - picloc = picsize * 0.5 - pic2size * 0.5; - if(vh_health < 0.25) - drawpic(hudloc + picloc, spider_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, spider_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, spider_rkt, pic2size, '1 1 1' * reload2 + '1 0 0' * (1 - reload2), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, spider_mgun, pic2size, '1 1 1' * ammo1 + '1 0 0' * (1 - ammo1), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL); - -// Health bar - picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale; - picloc = '69 69 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight); - drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale; - picloc = '37 65 0' * autocvar_cl_vehicles_hudscale; - if(vh_health < 0.25) - { - if(alarm1time < time) - { - alarm1time = time + 2; - sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE); - } - drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - } - else - { - drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - if(alarm1time) - { - sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - alarm1time = 0; - } - } -// Shield bar - picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale; - picloc = '69 140 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight); - drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picloc = '40 136 0' * autocvar_cl_vehicles_hudscale; - picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale; - if(shield < 0.25) - { - if(alarm2time < time) - { - alarm2time = time + 1; - sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE); - } - drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - } - else - { - drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - if(alarm2time) - { - sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - alarm2time = 0; - } - } - -// Minigun bar - picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale; - picloc = '450 69 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * ammo1, vid_conheight); - drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale; - picloc = '664 60 0' * autocvar_cl_vehicles_hudscale; - if(ammo1 < 0.2) - drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - -// Rocket ammo bar - picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale; - ammo1 = picsize_x / 8; - picloc = '450 140 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x, hudloc_y + picloc_y, picsize_x * reload2, vid_conheight); - drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); - -// .. and icons - pic2size = 0.35 * draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale; - picloc_x -= pic2size_x; - picloc_y += pic2size_y * 2.25; - if(ammo2 == 9) - { - for(i = 1; i < 9; ++i) - { - picloc_x += ammo1; - drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, ((8 * reload2 <= i) ? '0 0 0' : '1 1 1'), 0.75, DRAWFLAG_NORMAL); - } - } - else - { - for(i = 1; i < 9; ++i) - { - picloc_x += ammo1; - drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, ((i >= ammo2) ? '1 1 1' : '0 0 0'), 0.75, DRAWFLAG_NORMAL); - } - } - pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale; - picloc = '664 130 0' * autocvar_cl_vehicles_hudscale; - if(ammo2 == 9) - drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL); - - if (scoreboard_showscores) - HUD_DrawScoreboard(); - else - { - switch(weapon2mode) - { - case SBRM_VOLLY: - spider_xhair = "gfx/vehicles/axh-bracket.tga"; - break; - case SBRM_GUIDE: - spider_xhair = "gfx/vehicles/axh-cross.tga"; - break; - case SBRM_ARTILLERY: - spider_xhair = "gfx/vehicles/axh-tag.tga"; - break; - default: - spider_xhair= "gfx/vehicles/axh-tag.tga"; - } - - picsize = draw_getimagesize(spider_xhair); - picsize_x *= autocvar_cl_vehicle_spiderbot_cross_size; - picsize_y *= autocvar_cl_vehicle_spiderbot_cross_size; - - drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), spider_xhair, picsize, '1 1 1', autocvar_cl_vehicle_spiderbot_cross_alpha, DRAWFLAG_ADDITIVE); - } -} - -void CSQC_RAPTOR_HUD() -{ - if(autocvar_r_letterbox) - return; - - vector picsize, hudloc = '0 0 0', pic2size, picloc; - - // Fetch health & ammo stats - HUD_GETSTATS - - picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale; - hudloc_y = vid_conheight - picsize_y; - hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5; - - drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL); - - ammo1 *= 0.01; - ammo2 *= 0.01; - shield *= 0.01; - vh_health *= 0.01; - energy *= 0.01; - reload1 = reload2 * 0.01; - //reload2 *= 0.01; - - pic2size = draw_getimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8); - picloc = picsize * 0.5 - pic2size * 0.5; - if(vh_health < 0.25) - drawpic(hudloc + picloc, raptor_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, raptor_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, raptor_bomb, pic2size, '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, raptor_gun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL); - -// Health bar - picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale; - picloc = '69 69 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight); - drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale; - picloc = '37 65 0' * autocvar_cl_vehicles_hudscale; - if(vh_health < 0.25) - { - if(alarm1time < time) - { - alarm1time = time + 2; - sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE); - } - - drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - } - else - { - drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - if(alarm1time) - { - sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - alarm1time = 0; - } - } - -// Shield bar - picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale; - picloc = '69 140 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight); - drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picloc = '40 136 0' * autocvar_cl_vehicles_hudscale; - picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale; - if(shield < 0.25) - { - if(alarm2time < time) - { - alarm2time = time + 1; - sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE); - } - drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - } - else - { - drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - if(alarm2time) - { - sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - alarm2time = 0; - } - } - -// Gun bar - picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale; - picloc = '450 69 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * energy, vid_conheight); - drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale; - picloc = '664 60 0' * autocvar_cl_vehicles_hudscale; - if(energy < 0.2) - drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - -// Bomb bar - picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale; - picloc = '450 140 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x, hudloc_y + picloc_y, picsize_x * reload1, vid_conheight); - drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale; - picloc = '664 130 0' * autocvar_cl_vehicles_hudscale; - if(reload1 != 1) - drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL); - - if(weapon2mode == RSM_FLARE) - { - raptor_xhair = "gfx/vehicles/axh-bracket.tga"; - } - else - { - raptor_xhair = "gfx/vehicles/axh-ring.tga"; - - // Bombing crosshair - if(!dropmark) - { - dropmark = spawn(); - dropmark.owner = self; - dropmark.gravity = 1; - } - - if(reload2 == 100) - { - vector where; - - setorigin(dropmark, pmove_org); - dropmark.velocity = pmove_vel; - tracetoss(dropmark, self); - - where = project_3d_to_2d(trace_endpos); - - setorigin(dropmark, trace_endpos); - picsize = draw_getimagesize(raptor_drop) * 0.2; - - if not (where_z < 0 || where_x < 0 || where_y < 0 || where_x > vid_conwidth || where_y > vid_conheight) - { - where_x -= picsize_x * 0.5; - where_y -= picsize_y * 0.5; - where_z = 0; - drawpic(where, raptor_drop, picsize, '0 2 0', 1, DRAWFLAG_ADDITIVE); - } - dropmark.cnt = time + 5; - } - else - { - vector where; - if(dropmark.cnt > time) - { - where = project_3d_to_2d(dropmark.origin); - picsize = draw_getimagesize(raptor_drop) * 0.25; - - if not (where_z < 0 || where_x < 0 || where_y < 0 || where_x > vid_conwidth || where_y > vid_conheight) - { - where_x -= picsize_x * 0.5; - where_y -= picsize_y * 0.5; - where_z = 0; - drawpic(where, raptor_drop, picsize, '2 0 0', 1, DRAWFLAG_ADDITIVE); - } - } - } - } - - if (scoreboard_showscores) - HUD_DrawScoreboard(); - else - { - picsize = draw_getimagesize(raptor_xhair); - picsize_x *= 0.5; - picsize_y *= 0.5; - - drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), raptor_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - } -} - -void CSQC_WAKIZASHI_HUD() -{ -/* - 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' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL); - drawpic(hudloc, waki_e, picsize, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); -*/ - if(autocvar_r_letterbox) - return; - - vector picsize, hudloc = '0 0 0', pic2size, picloc; - - // Fetch health & ammo stats - HUD_GETSTATS - - picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale; - hudloc_y = vid_conheight - picsize_y; - hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5; - - drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL); - - shield *= 0.01; - vh_health *= 0.01; - energy *= 0.01; - reload1 *= 0.01; - - pic2size = draw_getimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8); - picloc = picsize * 0.5 - pic2size * 0.5; - if(vh_health < 0.25) - drawpic(hudloc + picloc, waki_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, waki_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, waki_eng, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, waki_gun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, waki_rkt, pic2size, '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL); - drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL); - -// Health bar - picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale; - picloc = '69 69 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight); - drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale; - picloc = '37 65 0' * autocvar_cl_vehicles_hudscale; - if(vh_health < 0.25) - { - if(alarm1time < time) - { - alarm1time = time + 2; - sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE); - } - - drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - } - else - { - drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - if(alarm1time) - { - sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - alarm1time = 0; - } - } - - -// Shield bar - picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale; - picloc = '69 140 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight); - drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picloc = '40 136 0' * autocvar_cl_vehicles_hudscale; - picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale; - if(shield < 0.25) - { - if(alarm2time < time) - { - alarm2time = time + 1; - sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE); - } - drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - } - else - { - drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - if(alarm2time) - { - sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); - alarm2time = 0; - } - } - -// Gun bar - picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale; - picloc = '450 69 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * energy, vid_conheight); - drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale; - picloc = '664 60 0' * autocvar_cl_vehicles_hudscale; - if(energy < 0.2) - drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - -// Bomb bar - picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale; - picloc = '450 140 0' * autocvar_cl_vehicles_hudscale; - drawsetcliparea(hudloc_x + picloc_x, hudloc_y + picloc_y, picsize_x * reload1, vid_conheight); - drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - drawresetcliparea(); -// .. and icon - pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale; - picloc = '664 130 0' * autocvar_cl_vehicles_hudscale; - if(reload1 != 1) - drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); - else - drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL); - - if (scoreboard_showscores) - HUD_DrawScoreboard(); - else - { - picsize = draw_getimagesize(waki_xhair); - picsize_x *= 0.5; - picsize_y *= 0.5; - - - drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); - } -} - -void Vehicles_Precache() -{ - precache_model("models/vehicles/bomblet.md3"); - precache_model("models/vehicles/clusterbomb.md3"); - precache_model("models/vehicles/clusterbomb_fragment.md3"); - precache_model("models/vehicles/rocket01.md3"); - precache_model("models/vehicles/rocket02.md3"); - - precache_sound ("vehicles/alarm.wav"); - precache_sound ("vehicles/alarm_shield.wav"); -} - -void RaptorCBShellfragDraw() -{ - if(wasfreed(self)) - return; - - Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy); - self.move_avelocity += randomvec() * 15; - self.renderflags = 0; - - if(self.cnt < time) - self.alpha = bound(0, self.nextthink - time, 1); - - if(self.alpha < ALPHA_MIN_VISIBLE) - remove(self); -} - -void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang) -{ - entity sfrag; - - sfrag = spawn(); - setmodel(sfrag, "models/vehicles/clusterbomb_fragment.md3"); - setorigin(sfrag, _org); - - sfrag.move_movetype = MOVETYPE_BOUNCE; - sfrag.gravity = 0.15; - sfrag.solid = SOLID_CORPSE; - - sfrag.draw = RaptorCBShellfragDraw; - - sfrag.move_origin = sfrag.origin = _org; - sfrag.move_velocity = _vel; - sfrag.move_avelocity = prandomvec() * vlen(sfrag.move_velocity); - sfrag.angles = self.move_angles = _ang; - - sfrag.move_time = time; - sfrag.damageforcescale = 4; - - sfrag.nextthink = time + 3; - sfrag.cnt = time + 2; - sfrag.alpha = 1; - sfrag.drawmask = MASK_NORMAL; -} diff --git a/qcsrc/client/vehicles/vehicles.qh b/qcsrc/client/vehicles/vehicles.qh deleted file mode 100644 index 66b2af1bf6..0000000000 --- a/qcsrc/client/vehicles/vehicles.qh +++ /dev/null @@ -1,4 +0,0 @@ -void RaptorCBShellfragDraw(); -void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang); -void Vehicles_Precache(); - diff --git a/qcsrc/common/constants.qh b/qcsrc/common/constants.qh index b3dafaaf7b..85528e1417 100644 --- a/qcsrc/common/constants.qh +++ b/qcsrc/common/constants.qh @@ -79,7 +79,6 @@ const float ENT_CLIENT_MAPVOTE = 17; const float ENT_CLIENT_CLIENTDATA = 18; const float ENT_CLIENT_RANDOMSEED = 19; const float ENT_CLIENT_WALL = 20; -const float ENT_CLIENT_SPIDERBOT = 21; const float ENT_CLIENT_MODELEFFECT = 22; const float ENT_CLIENT_TUBANOTE = 23; const float ENT_CLIENT_WARPZONE = 24; @@ -200,9 +199,6 @@ const float STAT_DOM_PPS_BLUE = 102; const float STAT_DOM_PPS_PINK = 103; const float STAT_DOM_PPS_YELLOW = 104; -//const float STAT_SPIDERBOT_AIM 53 // compressShotOrigin -//const float STAT_SPIDERBOT_TARGET 54 // compressShotOrigin - // see DP source, quakedef.h const float STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222; const float STAT_MOVEVARS_AIRSTRAFEACCEL_QW = 223; @@ -214,13 +210,7 @@ const float CTF_STATE_DEFEND = 2; const float CTF_STATE_COMMANDER = 3; const float HUD_NORMAL = 0; -const float HUD_VEHICLE_FIRST = 10; -const float HUD_SPIDERBOT = 10; -const float HUD_WAKIZASHI = 11; -const float HUD_RAPTOR = 12; -const float HUD_BUMBLEBEE = 13; -const float HUD_BUMBLEBEE_GUN = 14; -const float HUD_VEHICLE_LAST = 14; +const float HUD_BUMBLEBEE_GUN = 25; const vector eX = '1 0 0'; const vector eY = '0 1 0'; diff --git a/qcsrc/common/notifications.qh b/qcsrc/common/notifications.qh index e8e92f0183..5a5bc58bcf 100644 --- a/qcsrc/common/notifications.qh +++ b/qcsrc/common/notifications.qh @@ -660,7 +660,11 @@ void Send_Notification_WOCOVA( MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SPECTATE, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Spectating in ^COUNT"), "") \ MSG_CENTER_NOTIF(1, CENTER_TEAMCHANGE_SUICIDE, 0, 1, "", CPID_TEAMCHANGE, "1 f1", _("^K1Suicide in ^COUNT"), "") \ MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_BEGINNING, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout begins in ^COUNT"), "") \ - MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_ENDING, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout ends in ^COUNT"), "") + MSG_CENTER_NOTIF(1, CENTER_TIMEOUT_ENDING, 0, 1, "", CPID_TIMEOUT, "1 f1", _("^F4Timeout ends in ^COUNT"), "") \ + MSG_CENTER_NOTIF(1, CENTER_VEHICLE_ENTER, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to enter/exit the vehicle"), "") \ + MSG_CENTER_NOTIF(1, CENTER_VEHICLE_ENTER_STEAL, 0, 0, "pass_key", CPID_VEHICLES, "0 0", _("^BGPress ^F2DROPFLAG%s^BG to steal this vehicle"), "") \ + MSG_CENTER_NOTIF(1, CENTER_VEHICLE_STEAL, 0, 0, "", CPID_VEHICLES_OTHER, "0 0", _("^F2The enemy is stealing one of your vehicles!\n^F4Stop them!"), "") \ + MSG_CENTER_NOTIF(1, CENTER_VEHICLE_STEAL_SELF, 0, 0, "", CPID_VEHICLES_OTHER, "4 0", _("^F2You have stolen the enemy's vehicle, you are now visible on their radar!"), "") #define MULTITEAM_MULTI2(default,prefix,anncepre,infopre,centerpre) \ MSG_MULTI_NOTIF(default, prefix##RED, anncepre##RED, infopre##RED, centerpre##RED) \ diff --git a/qcsrc/common/vehicles/all.qh b/qcsrc/common/vehicles/all.qh new file mode 100644 index 0000000000..45e18b7323 --- /dev/null +++ b/qcsrc/common/vehicles/all.qh @@ -0,0 +1,6 @@ +#include "unit/spiderbot.qc" +#include "unit/raptor.qc" +#include "unit/racer.qc" +#ifndef VEHICLES_NO_UNSTABLE +#include "unit/bumblebee.qc" +#endif \ No newline at end of file diff --git a/qcsrc/common/vehicles/cl_vehicles.qc b/qcsrc/common/vehicles/cl_vehicles.qc new file mode 100644 index 0000000000..e0d1a619f0 --- /dev/null +++ b/qcsrc/common/vehicles/cl_vehicles.qc @@ -0,0 +1,309 @@ +#define hud_bg "gfx/vehicles/frame.tga" +#define hud_sh "gfx/vehicles/vh-shield.tga" + +#define hud_hp_bar "gfx/vehicles/bar_up_left.tga" +#define hud_hp_ico "gfx/vehicles/health.tga" +#define hud_sh_bar "gfx/vehicles/bar_dwn_left.tga" +#define hud_sh_ico "gfx/vehicles/shield.tga" + +#define hud_ammo1_bar "gfx/vehicles/bar_up_right.tga" +#define hud_ammo1_ico "gfx/vehicles/bullets.tga" +#define hud_ammo2_bar "gfx/vehicles/bar_dwn_right.tga" +#define hud_ammo2_ico "gfx/vehicles/rocket.tga" +#define hud_energy "gfx/vehicles/energy.tga" + +entity dropmark; +var float autocvar_cl_vehicles_hudscale = 0.5; +var float autocvar_cl_vehicles_hudalpha = 0.75; + +void CSQC_BUMBLE_GUN_HUD(); + +#define MAX_AXH 4 +entity AuxiliaryXhair[MAX_AXH]; + +.string axh_image; +.float axh_fadetime; +.float axh_drawflag; +.float axh_scale; + +#define bumb_ico "gfx/vehicles/bumb.tga" +#define bumb_lgun "gfx/vehicles/bumb_lgun.tga" +#define bumb_rgun "gfx/vehicles/bumb_rgun.tga" + +#define bumb_gun_ico "gfx/vehicles/bumb_side.tga" +#define bumb_gun_gun "gfx/vehicles/bumb_side_gun.tga" + +float alarm1time; +float alarm2time; +float weapon2mode; + +void vehicle_alarm(entity e, float ch, string s0und) +{ + if not(autocvar_cl_vehicles_alarm) + return; + + sound(e, ch, s0und, VOL_BASEVOICE, ATTEN_NONE); +} + +void AuxiliaryXhair_Draw2D() +{ + vector loc, psize; + + psize = self.axh_scale * draw_getimagesize(self.axh_image); + loc = project_3d_to_2d(self.move_origin) - 0.5 * psize; + if not (loc_z < 0 || loc_x < 0 || loc_y < 0 || loc_x > vid_conwidth || loc_y > vid_conheight) + { + loc_z = 0; + psize_z = 0; + drawpic(loc, self.axh_image, psize, self.colormod, self.alpha, self.axh_drawflag); + } + + if(time - self.cnt > self.axh_fadetime) + self.draw2d = func_null; +} + +void Net_AuXair2(float bIsNew) +{ + float axh_id = bound(0, ReadByte(), MAX_AXH); + entity axh = AuxiliaryXhair[axh_id]; + + if(axh == world || wasfreed(axh)) // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?) + { + axh = spawn(); + axh.draw2d = func_null; + axh.drawmask = MASK_NORMAL; + axh.axh_drawflag = DRAWFLAG_ADDITIVE; + axh.axh_fadetime = 0.1; + axh.axh_image = "gfx/vehicles/axh-ring.tga"; + axh.axh_scale = 1; + axh.alpha = 1; + AuxiliaryXhair[axh_id] = axh; + } + + axh.move_origin_x = ReadCoord(); + axh.move_origin_y = ReadCoord(); + axh.move_origin_z = ReadCoord(); + axh.colormod_x = ReadByte() / 255; + axh.colormod_y = ReadByte() / 255; + axh.colormod_z = ReadByte() / 255; + axh.cnt = time; + axh.draw2d = AuxiliaryXhair_Draw2D; +} + +void Net_VehicleSetup() +{ + + float i; + + float hud_id = ReadByte(); + + // Weapon update? + if(hud_id > VEH_LAST && hud_id != HUD_BUMBLEBEE_GUN) + { + weapon2mode = hud_id - VEH_LAST; + return; + } + + // hud_id == 0 means we exited a vehicle, so stop alarm sound/s + if(hud_id == 0) + { + sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); + sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); + return; + } + + // Init auxiliary crosshairs + entity axh; + for(i = 0; i < MAX_AXH; ++i) + { + axh = AuxiliaryXhair[i]; + if(axh != world && !wasfreed(axh)) // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?) + remove(axh); + + axh = spawn(); + axh.draw2d = func_null; + axh.drawmask = MASK_NORMAL; + axh.axh_drawflag = DRAWFLAG_NORMAL; + axh.axh_fadetime = 0.1; + axh.axh_image = "gfx/vehicles/axh-ring.tga"; + axh.axh_scale = 1; + axh.alpha = 1; + AuxiliaryXhair[i] = axh; + } + + VEH_ACTION(hud_id, VR_SETUP); + + if(hud_id == HUD_BUMBLEBEE_GUN) + { + // Plasma cannons + AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-bracket.tga"; + AuxiliaryXhair[0].axh_scale = 0.25; + // Raygun + AuxiliaryXhair[1].axh_image = "gfx/vehicles/axh-bracket.tga"; + AuxiliaryXhair[1].axh_scale = 0.25; + } +} + +void CSQC_BUMBLE_GUN_HUD() +{ + + if(autocvar_r_letterbox) + return; + + vector picsize, hudloc = '0 0 0', pic2size, picloc; + + // Fetch health & ammo stats + HUD_GETVEHICLESTATS + + picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale; + hudloc_y = vid_conheight - picsize_y; + hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5; + + drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL); + + shield *= 0.01; + vh_health *= 0.01; + energy *= 0.01; + reload1 *= 0.01; + + pic2size = draw_getimagesize(bumb_gun_ico) * (autocvar_cl_vehicles_hudscale * 0.8); + picloc = picsize * 0.5 - pic2size * 0.5; + + if(vh_health < 0.25) + drawpic(hudloc + picloc, bumb_gun_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, bumb_gun_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL); + + drawpic(hudloc + picloc, bumb_gun_gun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL); + +// Health bar + picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale; + picloc = '69 69 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight); + drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL); + drawresetcliparea(); +// .. and icon + picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale; + picloc = '37 65 0' * autocvar_cl_vehicles_hudscale; + if(vh_health < 0.25) + { + if(alarm1time < time) + { + alarm1time = time + 2; + vehicle_alarm(self, CH_PAIN_SINGLE, "vehicles/alarm.wav"); + } + + drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + } + else + { + drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + if(alarm1time) + { + vehicle_alarm(self, CH_PAIN_SINGLE, "misc/null.wav"); + alarm1time = 0; + } + } + +// Shield bar + picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale; + picloc = '69 140 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight); + drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); +// .. and icon + picloc = '40 136 0' * autocvar_cl_vehicles_hudscale; + picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale; + if(shield < 0.25) + { + if(alarm2time < time) + { + alarm2time = time + 1; + vehicle_alarm(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav"); + } + drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + } + else + { + drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + if(alarm2time) + { + vehicle_alarm(self, CH_TRIGGER_SINGLE, "misc/null.wav"); + alarm2time = 0; + } + } + +// Gun bar + picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale; + picloc = '450 69 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * energy, vid_conheight); + drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + +// .. and icon + picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale; + picloc = '664 60 0' * autocvar_cl_vehicles_hudscale; + if(energy < 0.2) + drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + + if (scoreboard_showscores) + HUD_DrawScoreboard(); + /* + else + { + picsize = draw_getimagesize(waki_xhair); + picsize_x *= 0.5; + picsize_y *= 0.5; + + + drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + } + */ +} + +void RaptorCBShellfragDraw() +{ + if(wasfreed(self)) + return; + + Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy); + self.move_avelocity += randomvec() * 15; + self.renderflags = 0; + + if(self.cnt < time) + self.alpha = bound(0, self.nextthink - time, 1); + + if(self.alpha < ALPHA_MIN_VISIBLE) + remove(self); +} + +void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang) +{ + entity sfrag; + + sfrag = spawn(); + setmodel(sfrag, "models/vehicles/clusterbomb_fragment.md3"); + setorigin(sfrag, _org); + + sfrag.move_movetype = MOVETYPE_BOUNCE; + sfrag.gravity = 0.15; + sfrag.solid = SOLID_CORPSE; + + sfrag.draw = RaptorCBShellfragDraw; + + sfrag.move_origin = sfrag.origin = _org; + sfrag.move_velocity = _vel; + sfrag.move_avelocity = prandomvec() * vlen(sfrag.move_velocity); + sfrag.angles = self.move_angles = _ang; + + sfrag.move_time = time; + sfrag.damageforcescale = 4; + + sfrag.nextthink = time + 3; + sfrag.cnt = time + 2; + sfrag.alpha = 1; + sfrag.drawmask = MASK_NORMAL; +} diff --git a/qcsrc/common/vehicles/cl_vehicles.qh b/qcsrc/common/vehicles/cl_vehicles.qh new file mode 100644 index 0000000000..1368353bcb --- /dev/null +++ b/qcsrc/common/vehicles/cl_vehicles.qh @@ -0,0 +1,17 @@ +// vehicle cvars +var float autocvar_cl_vehicles_alarm = 1; +var float autocvar_cl_vehicle_spiderbot_cross_alpha = 0.6; +var float autocvar_cl_vehicle_spiderbot_cross_size = 1; +var float autocvar_cl_vehicles_hud_tactical = 1; + +void RaptorCBShellfragDraw(); +void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang); + +#define HUD_GETVEHICLESTATS \ + local noref float vh_health = getstati(STAT_VEHICLESTAT_HEALTH); \ + local noref float shield = getstati(STAT_VEHICLESTAT_SHIELD); \ + local noref float energy = getstati(STAT_VEHICLESTAT_ENERGY); \ + local noref float ammo1 = getstati(STAT_VEHICLESTAT_AMMO1); \ + local noref float reload1 = getstati(STAT_VEHICLESTAT_RELOAD1); \ + local noref float ammo2 = getstati(STAT_VEHICLESTAT_AMMO2); \ + local noref float reload2 = getstati(STAT_VEHICLESTAT_RELOAD2); diff --git a/qcsrc/common/vehicles/sv_vehicles.qc b/qcsrc/common/vehicles/sv_vehicles.qc new file mode 100644 index 0000000000..b3a324695b --- /dev/null +++ b/qcsrc/common/vehicles/sv_vehicles.qc @@ -0,0 +1,1182 @@ +// ========================= +// SVQC Vehicle Properties +// ========================= + + +float SendAuxiliaryXhair(entity to, float sf) +{ + + WriteByte(MSG_ENTITY, ENT_CLIENT_AUXILIARYXHAIR); + + WriteByte(MSG_ENTITY, self.cnt); + + WriteCoord(MSG_ENTITY, self.origin_x); + WriteCoord(MSG_ENTITY, self.origin_y); + WriteCoord(MSG_ENTITY, self.origin_z); + + WriteByte(MSG_ENTITY, rint(self.colormod_x * 255)); + WriteByte(MSG_ENTITY, rint(self.colormod_y * 255)); + WriteByte(MSG_ENTITY, rint(self.colormod_z * 255)); + + return TRUE; +} + +void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, float axh_id) +{ + if not(IS_REAL_CLIENT(own)) + return; + + entity axh; + + axh_id = bound(0, axh_id, MAX_AXH); + axh = own.(AuxiliaryXhair[axh_id]); + + if(axh == world || wasfreed(axh)) // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?) + { + axh = spawn(); + axh.cnt = axh_id; + axh.drawonlytoclient = own; + axh.owner = own; + Net_LinkEntity(axh, FALSE, 0, SendAuxiliaryXhair); + } + + setorigin(axh, loc); + axh.colormod = clr; + axh.SendFlags = 0x01; + own.(AuxiliaryXhair[axh_id]) = axh; +} + +void CSQCVehicleSetup(entity own, float vehicle_id) +{ + if not(IS_REAL_CLIENT(own)) + return; + + msg_entity = own; + + WriteByte(MSG_ONE, SVC_TEMPENTITY); + WriteByte(MSG_ONE, TE_CSQC_VEHICLESETUP); + if(vehicle_id != 0) + WriteByte(MSG_ONE, vehicle_id); + else + WriteByte(MSG_ONE, 1 + own.vehicle.vehicle_weapon2mode + VEH_LAST); +} + +vector targetdrone_getnewspot() +{ + + vector spot; + float i; + for(i = 0; i < 100; ++i) + { + spot = self.origin + randomvec() * 1024; + tracebox(spot, self.mins, self.maxs, spot, MOVE_NORMAL, self); + if(trace_fraction == 1.0 && trace_startsolid == 0 && trace_allsolid == 0) + return spot; + } + return self.origin; +} + +void vehicles_locktarget(float incr, float decr, float _lock_time) +{ + if(self.lock_target && self.lock_target.deadflag != DEAD_NO) + { + self.lock_target = world; + self.lock_strength = 0; + self.lock_time = 0; + } + + if(self.lock_time > time) + { + if(self.lock_target) + if(self.lock_soundtime < time) + { + self.lock_soundtime = time + 0.5; + play2(self.owner, "vehicles/locked.wav"); + } + + return; + } + + if(trace_ent != world) + { + if(teamplay && trace_ent.team == self.team) + trace_ent = world; + + if(trace_ent.deadflag != DEAD_NO) + trace_ent = world; + + if not (trace_ent.vehicle_flags & VHF_ISVEHICLE || + trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET || + trace_ent.takedamage == DAMAGE_TARGETDRONE) + trace_ent = world; + } + + if(self.lock_target == world && trace_ent != world) + self.lock_target = trace_ent; + + if(self.lock_target && trace_ent == self.lock_target) + { + if(self.lock_strength != 1 && self.lock_strength + incr >= 1) + { + play2(self.owner, "vehicles/lock.wav"); + self.lock_soundtime = time + 0.8; + } + else if (self.lock_strength != 1 && self.lock_soundtime < time) + { + play2(self.owner, "vehicles/locking.wav"); + self.lock_soundtime = time + 0.3; + } + + } + + // Have a locking target + // Trace hit current target + if(trace_ent == self.lock_target && trace_ent != world) + { + self.lock_strength = min(self.lock_strength + incr, 1); + if(self.lock_strength == 1) + self.lock_time = time + _lock_time; + } + else + { + if(trace_ent) + self.lock_strength = max(self.lock_strength - decr * 2, 0); + else + self.lock_strength = max(self.lock_strength - decr, 0); + + if(self.lock_strength == 0) + self.lock_target = world; + } +} + +vector vehicles_force_fromtag_hover(string tag_name, float spring_length, float max_power) +{ + force_fromtag_origin = gettaginfo(self, gettagindex(self, tag_name)); + v_forward = normalize(v_forward) * -1; + traceline(force_fromtag_origin, force_fromtag_origin - (v_forward * spring_length), MOVE_NORMAL, self); + + force_fromtag_power = (1 - trace_fraction) * max_power; + force_fromtag_normpower = force_fromtag_power / max_power; + + return v_forward * force_fromtag_power; +} + +vector vehicles_force_fromtag_maglev(string tag_name, float spring_length, float max_power) +{ + + force_fromtag_origin = gettaginfo(self, gettagindex(self, tag_name)); + v_forward = normalize(v_forward) * -1; + traceline(force_fromtag_origin, force_fromtag_origin - (v_forward * spring_length), MOVE_NORMAL, self); + + // TODO - this may NOT be compatible with wall/celing movement, unhardcode 0.25 (engine count multiplier) + if(trace_fraction == 1.0) + { + force_fromtag_normpower = -0.25; + return '0 0 -200'; + } + + force_fromtag_power = ((1 - trace_fraction) - trace_fraction) * max_power; + force_fromtag_normpower = force_fromtag_power / max_power; + + return v_forward * force_fromtag_power; +} + +// projectile handling +void vehicles_projectile_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) +{ + // Ignore damage from oterh projectiles from my owner (dont mess up volly's) + if(inflictor.owner == self.owner) + return; + + self.health -= damage; + self.velocity += force; + if(self.health < 1) + { + self.takedamage = DAMAGE_NO; + self.event_damage = func_null; + self.think = self.use; + self.nextthink = time; + } +} + +void vehicles_projectile_explode() +{ + if(self.owner && other != world) + { + if(other == self.owner.vehicle) + return; + + if(other == self.owner.vehicle.tur_head) + return; + } + + PROJECTILE_TOUCH; + + self.event_damage = func_null; + RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, self.shot_force, self.totalfrags, other); + + remove (self); +} + +entity vehicles_projectile(string _mzlfx, string _mzlsound, + vector _org, vector _vel, + float _dmg, float _radi, float _force, float _size, + float _deahtype, float _projtype, float _health, + float _cull, float _clianim, entity _owner) +{ + entity proj; + + proj = spawn(); + + PROJECTILE_MAKETRIGGER(proj); + setorigin(proj, _org); + + proj.shot_dmg = _dmg; + proj.shot_radius = _radi; + proj.shot_force = _force; + proj.totalfrags = _deahtype; + proj.solid = SOLID_BBOX; + proj.movetype = MOVETYPE_FLYMISSILE; + proj.flags = FL_PROJECTILE; + proj.bot_dodge = TRUE; + proj.bot_dodgerating = _dmg; + proj.velocity = _vel; + proj.touch = vehicles_projectile_explode; + proj.use = vehicles_projectile_explode; + proj.owner = self; + proj.realowner = _owner; + proj.think = SUB_Remove; + proj.nextthink = time + 30; + + if(_health) + { + proj.takedamage = DAMAGE_AIM; + proj.event_damage = vehicles_projectile_damage; + proj.health = _health; + } + else + proj.flags = FL_PROJECTILE | FL_NOTARGET; + + if(_mzlsound) + sound (self, CH_WEAPON_A, _mzlsound, VOL_BASE, ATTEN_NORM); + + if(_mzlfx) + pointparticles(particleeffectnum(_mzlfx), proj.origin, proj.velocity, 1); + + + setsize (proj, '-1 -1 -1' * _size, '1 1 1' * _size); + + CSQCProjectile(proj, _clianim, _projtype, _cull); + + return proj; +} + +void vehicles_gib_explode() +{ + sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); + remove(self); +} + +void vehicles_gib_think() +{ + self.alpha -= 0.1; + if(self.cnt >= time) + remove(self); + else + self.nextthink = time + 0.1; +} + +entity vehicle_tossgib(entity _template, vector _vel, string _tag, float _burn, float _explode, float _maxtime, vector _rot) +{ + entity _gib = spawn(); + setmodel(_gib, _template.model); + setorigin(_gib, gettaginfo(self, gettagindex(self, _tag))); + _gib.velocity = _vel; + _gib.movetype = MOVETYPE_TOSS; + _gib.solid = SOLID_CORPSE; + _gib.colormod = '-0.5 -0.5 -0.5'; + _gib.effects = EF_LOWPRECISION; + _gib.avelocity = _rot; + + if(_burn) + _gib.effects |= EF_FLAME; + + if(_explode) + { + _gib.think = vehicles_gib_explode; + _gib.nextthink = time + random() * _explode; + _gib.touch = vehicles_gib_explode; + } + else + { + _gib.cnt = time + _maxtime; + _gib.think = vehicles_gib_think; + _gib.nextthink = time + _maxtime - 1; + _gib.alpha = 1; + } + return _gib; +} + +float vehicle_addplayerslot( entity _owner, + entity _slot, + float _hud, + string _hud_model, + float() _framefunc, + void(float) _exitfunc) +{ + if not (_owner.vehicle_flags & VHF_MULTISLOT) + _owner.vehicle_flags |= VHF_MULTISLOT; + + _slot.PlayerPhysplug = _framefunc; + _slot.vehicle_exit = _exitfunc; + _slot.hud = _hud; + _slot.vehicle_flags = VHF_PLAYERSLOT; + _slot.vehicle_viewport = spawn(); + _slot.vehicle_hudmodel = spawn(); + _slot.vehicle_hudmodel.viewmodelforclient = _slot; + _slot.vehicle_viewport.effects = (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT); + + setmodel(_slot.vehicle_hudmodel, _hud_model); + setmodel(_slot.vehicle_viewport, "null"); + + setattachment(_slot.vehicle_hudmodel, _slot, ""); + setattachment(_slot.vehicle_viewport, _slot.vehicle_hudmodel, ""); + + return TRUE; +} + +vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname, + float _pichlimit_min, float _pichlimit_max, + float _rotlimit_min, float _rotlimit_max, float _aimspeed) +{ + vector vtmp, vtag; + float ftmp; + vtag = gettaginfo(_turrret, gettagindex(_turrret, _tagname)); + vtmp = vectoangles(normalize(_target - vtag)); + vtmp = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(_vehic.angles), AnglesTransform_FromAngles(vtmp))) - _turrret.angles; + vtmp = AnglesTransform_Normalize(vtmp, TRUE); + ftmp = _aimspeed * frametime; + vtmp_y = bound(-ftmp, vtmp_y, ftmp); + vtmp_x = bound(-ftmp, vtmp_x, ftmp); + _turrret.angles_y = bound(_rotlimit_min, _turrret.angles_y + vtmp_y, _rotlimit_max); + _turrret.angles_x = bound(_pichlimit_min, _turrret.angles_x + vtmp_x, _pichlimit_max); + return vtag; +} + +void vehicles_reset_colors() +{ + entity e; + float _effects = 0, _colormap; + vector _glowmod, _colormod; + + if(autocvar_g_nodepthtestplayers) + _effects |= EF_NODEPTHTEST; + + if(autocvar_g_fullbrightplayers) + _effects |= EF_FULLBRIGHT; + + if(self.team) + _colormap = 1024 + (self.team - 1) * 17; + else + _colormap = 1024; + + _glowmod = '0 0 0'; + _colormod = '0 0 0'; + + // Find all ents attacked to main model and setup effects, colormod etc. + e = findchainentity(tag_entity, self); + while(e) + { + if(e != self.vehicle_shieldent) + { + e.effects = _effects; // | EF_LOWPRECISION; + e.colormod = _colormod; + e.colormap = _colormap; + e.alpha = 1; + } + e = e.chain; + } + + self.vehicle_hudmodel.effects = self.effects = _effects; // | EF_LOWPRECISION; + self.vehicle_hudmodel.colormod = self.colormod = _colormod; + self.vehicle_hudmodel.colormap = self.colormap = _colormap; + self.vehicle_viewport.effects = (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT); + + self.alpha = 1; + self.avelocity = '0 0 0'; + self.velocity = '0 0 0'; + self.effects = _effects; +} + +void vehicles_clearreturn(entity veh) +{ + entity ret; + // Remove "return helper", if any. + ret = findchain(classname, "vehicle_return"); + while(ret) + { + if(ret.wp00 == veh) + { + ret.classname = ""; + ret.think = SUB_Remove; + ret.nextthink = time + 0.1; + + if(ret.waypointsprite_attached) + WaypointSprite_Kill(ret.waypointsprite_attached); + + return; + } + ret = ret.chain; + } +} + +void vehicles_spawn(); +void vehicles_return() +{ + pointparticles(particleeffectnum("teleport"), self.wp00.origin + '0 0 64', '0 0 0', 1); + + self.wp00.think = vehicles_spawn; + self.wp00.nextthink = time; + + if(self.waypointsprite_attached) + WaypointSprite_Kill(self.waypointsprite_attached); + + remove(self); +} + +void vehicles_showwp_goaway() +{ + if(self.waypointsprite_attached) + WaypointSprite_Kill(self.waypointsprite_attached); + + remove(self); + +} + +void vehicles_showwp() +{ + entity oldself = world; + vector rgb; + + if(self.cnt) + { + self.think = vehicles_return; + self.nextthink = self.cnt; + } + else + { + self.think = vehicles_return; + self.nextthink = time +1; + + oldself = self; + self = spawn(); + setmodel(self, "null"); + self.team = oldself.wp00.team; + self.wp00 = oldself.wp00; + setorigin(self, oldself.wp00.pos1); + + self.nextthink = time + 5; + self.think = vehicles_showwp_goaway; + } + + if(teamplay && self.team) + rgb = Team_ColorRGB(self.team); + else + rgb = '1 1 1'; + WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, TRUE, RADARICON_POWERUP, rgb); + if(self.waypointsprite_attached) + { + WaypointSprite_UpdateRule(self.waypointsprite_attached, self.wp00.team, SPRITERULE_DEFAULT); + if(oldself == world) + WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, self.nextthink); + WaypointSprite_Ping(self.waypointsprite_attached); + } + + if(oldself != world) + self = oldself; +} + +void vehicles_setreturn(entity veh) +{ + entity ret; + + vehicles_clearreturn(veh); + + ret = spawn(); + ret.classname = "vehicle_return"; + ret.wp00 = veh; + ret.team = veh.team; + ret.think = vehicles_showwp; + + if(veh.deadflag != DEAD_NO) + { + ret.cnt = time + veh.respawntime; + ret.nextthink = min(time + veh.respawntime, time + veh.respawntime - 5); + } + else + { + ret.nextthink = min(time + veh.respawntime, time + veh.respawntime - 1); + } + + setmodel(ret, "null"); + setorigin(ret, veh.pos1 + '0 0 96'); + +} + +void vehicle_use() +{ + dprint("vehicle ",self.netname, " used by ", activator.classname, "\n"); + + self.tur_head.team = activator.team; + + if(self.tur_head.team == 0) + self.active = ACTIVE_NOT; + else + self.active = ACTIVE_ACTIVE; + + if(self.active == ACTIVE_ACTIVE && self.deadflag == DEAD_NO) + { + dprint("Respawning vehicle: ", self.netname, "\n"); + vehicles_setreturn(self); + vehicles_reset_colors(); + } +} + +void vehicles_regen(float timer, .float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale) +{ + if(self.regen_field < field_max) + if(timer + rpause < time) + { + if(_healthscale) + regen = regen * (self.vehicle_health / self.max_health); + + self.regen_field = min(self.regen_field + regen * delta_time, field_max); + + if(self.owner) + self.owner.regen_field = (self.regen_field / field_max) * 100; + } +} + +void shieldhit_think() +{ + self.alpha -= 0.1; + if (self.alpha <= 0) + { + //setmodel(self, ""); + self.alpha = -1; + self.effects |= EF_NODRAW; + } + else + { + self.nextthink = time + 0.1; + } +} + +void vehicles_painframe() +{ + if(self.owner.vehicle_health <= 50) + if(self.pain_frame < time) + { + float _ftmp; + _ftmp = self.owner.vehicle_health / 50; + self.pain_frame = time + 0.1 + (random() * 0.5 * _ftmp); + pointparticles(particleeffectnum("smoke_small"), (self.origin + (randomvec() * 80)), '0 0 0', 1); + + if(self.vehicle_flags & VHF_DMGSHAKE) + self.velocity += randomvec() * 30; + + if(self.vehicle_flags & VHF_DMGROLL) + if(self.vehicle_flags & VHF_DMGHEADROLL) + self.tur_head.angles += randomvec(); + else + self.angles += randomvec(); + + } +} + +void vehicles_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) +{ + self.dmg_time = time; + + if(DEATH_ISWEAPON(deathtype, WEP_NEX)) + damage *= autocvar_g_vehicles_nex_damagerate; + + if(DEATH_ISWEAPON(deathtype, WEP_UZI)) + damage *= autocvar_g_vehicles_uzi_damagerate; + + if(DEATH_ISWEAPON(deathtype, WEP_RIFLE)) + damage *= autocvar_g_vehicles_rifle_damagerate; + + if(DEATH_ISWEAPON(deathtype, WEP_MINSTANEX)) + damage *= autocvar_g_vehicles_minstanex_damagerate; + + if(DEATH_ISWEAPON(deathtype, WEP_SEEKER)) + damage *= autocvar_g_vehicles_tag_damagerate; + + self.enemy = attacker; + + if((self.vehicle_flags & VHF_HASSHIELD) && (self.vehicle_shield > 0)) + { + if (wasfreed(self.vehicle_shieldent) || self.vehicle_shieldent == world) + { + self.vehicle_shieldent = spawn(); + self.vehicle_shieldent.effects = EF_LOWPRECISION; + + setmodel(self.vehicle_shieldent, "models/vhshield.md3"); + setattachment(self.vehicle_shieldent, self, ""); + setorigin(self.vehicle_shieldent, real_origin(self) - self.origin); + self.vehicle_shieldent.scale = 256 / vlen(self.maxs - self.mins); + self.vehicle_shieldent.think = shieldhit_think; + } + + self.vehicle_shieldent.colormod = '1 1 1'; + self.vehicle_shieldent.alpha = 0.45; + self.vehicle_shieldent.angles = vectoangles(normalize(hitloc - (self.origin + self.vehicle_shieldent.origin))) - self.angles; + self.vehicle_shieldent.nextthink = time; + self.vehicle_shieldent.effects &= ~EF_NODRAW; + + self.vehicle_shield -= damage; + + if(self.vehicle_shield < 0) + { + self.vehicle_health -= fabs(self.vehicle_shield); + self.vehicle_shieldent.colormod = '2 0 0'; + self.vehicle_shield = 0; + self.vehicle_shieldent.alpha = 0.75; + + if(sound_allowed(MSG_BROADCAST, attacker)) + spamsound (self, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM); // FIXME: PLACEHOLDER + } + else + if(sound_allowed(MSG_BROADCAST, attacker)) + spamsound (self, CH_PAIN, "onslaught/electricity_explode.wav", VOL_BASE, ATTEN_NORM); // FIXME: PLACEHOLDER + + } + else + { + self.vehicle_health -= damage; + + if(sound_allowed(MSG_BROADCAST, attacker)) + spamsound (self, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM); // FIXME: PLACEHOLDER + } + + if(self.damageforcescale < 1 && self.damageforcescale > 0) + self.velocity += force * self.damageforcescale; + else + self.velocity += force; + + if(self.vehicle_health <= 0) + { + if(self.owner) + if(self.vehicle_flags & VHF_DEATHEJECT) + vehicles_exit(VHEF_EJECT); + else + vehicles_exit(VHEF_RELESE); + + + antilag_clear(self); + + VEH_ACTION(self.vehicleid, VR_DEATH); + vehicles_setreturn(self); + } +} + +float vehicles_crushable(entity e) +{ + if(IS_PLAYER(e)) + return TRUE; + + if(e.flags & FL_MONSTER) + return TRUE; + + return FALSE; +} + +void vehicles_impact(float _minspeed, float _speedfac, float _maxpain) +{ + if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) + return; + + if(self.play_time < time) + { + float wc = vlen(self.velocity - self.oldvelocity); + //dprint("oldvel: ", vtos(self.oldvelocity), "\n"); + //dprint("vel: ", vtos(self.velocity), "\n"); + if(_minspeed < wc) + { + float take = min(_speedfac * wc, _maxpain); + Damage (self, world, world, take, DEATH_FALL, self.origin, '0 0 0'); + self.play_time = time + 0.25; + + //dprint("wc: ", ftos(wc), "\n"); + //dprint("take: ", ftos(take), "\n"); + } + } +} + +// vehicle enter/exit handling +vector vehicles_findgoodexit(vector prefer_spot) +{ + //vector exitspot; + float mysize; + + tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, prefer_spot, MOVE_NORMAL, self.owner); + if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) + return prefer_spot; + + mysize = 1.5 * vlen(self.maxs - self.mins); + float i; + vector v, v2; + v2 = 0.5 * (self.absmin + self.absmax); + for(i = 0; i < 100; ++i) + { + v = randomvec(); + v_z = 0; + v = v2 + normalize(v) * mysize; + tracebox(v2, PL_MIN, PL_MAX, v, MOVE_NORMAL, self.owner); + if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) + return v; + } + + /* + exitspot = (self.origin + '0 0 48') + v_forward * mysize; + tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner); + if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) + return exitspot; + + exitspot = (self.origin + '0 0 48') - v_forward * mysize; + tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner); + if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) + return exitspot; + + exitspot = (self.origin + '0 0 48') + v_right * mysize; + tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner); + if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) + return exitspot; + + exitspot = (self.origin + '0 0 48') - v_right * mysize; + tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner); + if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) + return exitspot; + */ + + return self.origin; +} + +void vehicles_exit(float eject) +{ + entity _vehicle; + entity _player; + entity _oldself = self; + + if(vehicles_exit_running) + { + dprint("^1vehicles_exit allready running! this is not good..\n"); + return; + } + + vehicles_exit_running = TRUE; + if(IS_CLIENT(self)) + { + _vehicle = self.vehicle; + + if (_vehicle.vehicle_flags & VHF_PLAYERSLOT) + { + _vehicle.vehicle_exit(eject); + self = _oldself; + vehicles_exit_running = FALSE; + return; + } + } + else + _vehicle = self; + + _player = _vehicle.owner; + + self = _vehicle; + + if (_player) + { + if (IS_REAL_CLIENT(_player)) + { + msg_entity = _player; + WriteByte (MSG_ONE, SVC_SETVIEWPORT); + WriteEntity( MSG_ONE, _player); + + WriteByte (MSG_ONE, SVC_SETVIEWANGLES); + WriteAngle(MSG_ONE, 0); + WriteAngle(MSG_ONE, _vehicle.angles_y); + WriteAngle(MSG_ONE, 0); + } + + setsize(_player, PL_MIN,PL_MAX); + + _player.takedamage = DAMAGE_AIM; + _player.solid = SOLID_SLIDEBOX; + _player.movetype = MOVETYPE_WALK; + _player.effects &= ~EF_NODRAW; + _player.alpha = 1; + _player.PlayerPhysplug = func_null; + _player.vehicle = world; + _player.view_ofs = PL_VIEW_OFS; + _player.event_damage = PlayerDamage; + _player.hud = HUD_NORMAL; + _player.switchweapon = _vehicle.switchweapon; + _player.last_vehiclecheck = time + 3; + + CSQCVehicleSetup(_player, HUD_NORMAL); + } + _vehicle.flags |= FL_NOTARGET; + + if(_vehicle.deadflag == DEAD_NO) + _vehicle.avelocity = '0 0 0'; + + _vehicle.tur_head.nodrawtoclient = world; + + if not(teamplay) + _vehicle.team = 0; + + Kill_Notification(NOTIF_ONE, _player, MSG_CENTER_CPID, CPID_VEHICLES); + Kill_Notification(NOTIF_ONE, _player, MSG_CENTER_CPID, CPID_VEHICLES_OTHER); // kill all vehicle notifications when exiting a vehicle? + + WaypointSprite_Kill(_vehicle.wps_intruder); + + vh_player = _player; + vh_vehicle = _vehicle; + MUTATOR_CALLHOOK(VehicleExit); + _player = vh_player; + _vehicle = vh_vehicle; + + _vehicle.team = _vehicle.tur_head.team; + + sound (_vehicle, CH_TRIGGER_SINGLE, "misc/null.wav", 1, ATTEN_NORM); + _vehicle.vehicle_hudmodel.viewmodelforclient = _vehicle; + _vehicle.phase = time + 1; + + _vehicle.vehicle_exit(eject); + + vehicles_setreturn(_vehicle); + vehicles_reset_colors(); + _vehicle.owner = world; + self = _oldself; + + vehicles_exit_running = FALSE; +} + +void vehicles_touch() +{ + if(MUTATOR_CALLHOOK(VehicleTouch)) + return; + + // Vehicle currently in use + if(self.owner) + { + if(other != world) + if(vehicles_crushable(other)) + { + if(vlen(self.velocity) != 0) + Damage(other, self, self.owner, autocvar_g_vehicles_crush_dmg, DEATH_VH_CRUSH, '0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicles_crush_force); + + return; // Dont do selfdamage when hitting "soft targets". + } + + if(self.play_time < time) + VEH_ACTION(self.vehicleid, VR_IMPACT); + + return; + } + + if(autocvar_g_vehicles_enter) + return; + + vehicles_enter(other, self); +} + +void vehicles_enter(entity pl, entity veh) +{ + // Remove this when bots know how to use vehicles + if (IS_BOT_CLIENT(pl)) + if (autocvar_g_vehicles_allow_bots) + dprint("Bot enters vehicle\n"); // This is where we need to disconnect (some, all?) normal bot AI and hand over to vehicle's _aiframe() + else + return; + + if not(IS_PLAYER(pl)) + return; + + if(veh.phase > time) + return; + + if(pl.freezetag_frozen) + return; + + if(pl.deadflag != DEAD_NO) + return; + + if(pl.vehicle) + return; + + if(teamplay) + if(veh.team) + if(DIFF_TEAM(pl, veh)) + if(autocvar_g_vehicles_steal) + { + entity head; + FOR_EACH_PLAYER(head) if(SAME_TEAM(head, veh)) + Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_VEHICLE_STEAL); + + Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_VEHICLE_STEAL_SELF); + + WaypointSprite_Spawn("intruder", 0, 0, pl, '0 0 68', world, veh.team, veh, wps_intruder, TRUE, RADARICON_DANGER, Team_ColorRGB(pl.team)); + } + else return; + + RemoveGrapplingHook(pl); + + veh.vehicle_ammo1 = 0; + veh.vehicle_ammo2 = 0; + veh.vehicle_reload1 = 0; + veh.vehicle_reload2 = 0; + veh.vehicle_energy = 0; + + veh.owner = pl; + pl.vehicle = veh; + + // .viewmodelforclient works better. + //veh.vehicle_hudmodel.drawonlytoclient = veh.owner; + + veh.vehicle_hudmodel.viewmodelforclient = pl; + + veh.event_damage = vehicles_damage; + veh.nextthink = 0; + pl.angles = veh.angles; + pl.takedamage = DAMAGE_NO; + pl.solid = SOLID_NOT; + pl.movetype = MOVETYPE_NOCLIP; + pl.alpha = -1; + pl.vehicle = veh; + pl.event_damage = func_null; + pl.view_ofs = '0 0 0'; + veh.colormap = pl.colormap; + if(veh.tur_head) + veh.tur_head.colormap = pl.colormap; + veh.switchweapon = pl.switchweapon; + if(veh.hud) + pl.hud = veh.hud; + else + pl.hud = veh.vehicleid; + pl.PlayerPhysplug = veh.PlayerPhysplug; + + pl.vehicle_ammo1 = veh.vehicle_ammo1; + pl.vehicle_ammo2 = veh.vehicle_ammo2; + pl.vehicle_reload1 = veh.vehicle_reload1; + pl.vehicle_reload2 = veh.vehicle_reload2; + + // Cant do this, hides attached objects too. + //veh.exteriormodeltoclient = veh.owner; + //veh.tur_head.exteriormodeltoclient = veh.owner; + + pl.flags &= ~FL_ONGROUND; + veh.flags &= ~FL_ONGROUND; + + veh.team = pl.team; + veh.flags -= FL_NOTARGET; + + if (IS_REAL_CLIENT(pl)) + { + Send_Notification(NOTIF_ONE, pl, MSG_CENTER, CENTER_VEHICLE_ENTER); + + msg_entity = pl; + WriteByte (MSG_ONE, SVC_SETVIEWPORT); + WriteEntity(MSG_ONE, veh.vehicle_viewport); + + WriteByte (MSG_ONE, SVC_SETVIEWANGLES); + if(veh.tur_head) + { + WriteAngle(MSG_ONE, veh.tur_head.angles_x + veh.angles_x); // tilt + WriteAngle(MSG_ONE, veh.tur_head.angles_y + veh.angles_y); // yaw + WriteAngle(MSG_ONE, 0); // roll + } + else + { + WriteAngle(MSG_ONE, veh.angles_x * -1); // tilt + WriteAngle(MSG_ONE, veh.angles_y); // yaw + WriteAngle(MSG_ONE, 0); // roll + } + } + + vehicles_clearreturn(veh); + + CSQCVehicleSetup(pl, veh.vehicleid); + + vh_player = pl; + vh_vehicle = veh; + MUTATOR_CALLHOOK(VehicleEnter); + pl = vh_player; + veh = vh_vehicle; + + entity oldself = self; + self = veh; + VEH_ACTION(veh.vehicleid, VR_ENTER); + self = oldself; + + antilag_clear(pl); +} + +void vehicles_think() +{ + self.nextthink = time; + + VEH_ACTION(self.vehicleid, VR_THINK); +} + +// initialization +void vehicles_spawn() +{ + dprint("Spawning vehicle: ", self.netname, "\n"); + + // disown & reset + self.vehicle_hudmodel.viewmodelforclient = self; + + self.owner = world; + self.touch = vehicles_touch; + self.event_damage = vehicles_damage; + self.iscreature = TRUE; + self.teleportable = FALSE; // no teleporting for vehicles, too buggy + self.damagedbycontents = TRUE; + self.movetype = MOVETYPE_WALK; + self.solid = SOLID_SLIDEBOX; + self.takedamage = DAMAGE_AIM; + self.deadflag = DEAD_NO; + self.bot_attack = TRUE; + self.flags = FL_NOTARGET; + self.avelocity = '0 0 0'; + self.velocity = '0 0 0'; + self.think = vehicles_think; + self.nextthink = time; + + // Reset locking + self.lock_strength = 0; + self.lock_target = world; + self.misc_bulletcounter = 0; + + // Return to spawn + self.angles = self.pos2; + setorigin(self, self.pos1 + '0 0 0'); + // Show it + pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1); + + if(self.vehicle_controller) + self.team = self.vehicle_controller.team; + + vehicles_reset_colors(); + + VEH_ACTION(self.vehicleid, VR_SPAWN); +} + +float vehicle_initialize(float vehicle_id, float nodrop) +{ + if not(autocvar_g_vehicles) + return FALSE; + + entity veh = get_vehicleinfo(vehicle_id); + + if(self.targetname) + { + self.vehicle_controller = find(world, target, self.targetname); + if not(self.vehicle_controller) + { + bprint("^1WARNING: ^7Vehicle with invalid .targetname\n"); + } + else + { + self.team = self.vehicle_controller.team; + self.use = vehicle_use; + + if(teamplay) + { + if(self.vehicle_controller.team == 0) + self.active = ACTIVE_NOT; + else + self.active = ACTIVE_ACTIVE; + } + } + } + + if(self.team && !teamplay) + self.team = 0; + + self.vehicle_flags |= VHF_ISVEHICLE; + + setmodel(self, veh.model); + + self.vehicle_viewport = spawn(); + self.vehicle_hudmodel = spawn(); + self.tur_head = spawn(); + self.tur_head.owner = self; + self.takedamage = DAMAGE_AIM; + self.bot_attack = TRUE; + self.iscreature = TRUE; + self.teleportable = FALSE; // no teleporting for vehicles, too buggy + self.damagedbycontents = TRUE; + self.vehicleid = vehicle_id; + self.PlayerPhysplug = veh.PlayerPhysplug; + self.event_damage = func_null; + self.touch = vehicles_touch; + self.think = vehicles_spawn; + self.nextthink = time; + self.effects = EF_NODRAW; + self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID; + + if(autocvar_g_playerclip_collisions) + self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP; + + if(autocvar_g_nodepthtestplayers) + self.effects |= EF_NODEPTHTEST; + + if(autocvar_g_fullbrightplayers) + self.effects |= EF_FULLBRIGHT; + + setmodel(self.vehicle_hudmodel, veh.hud_model); + setmodel(self.vehicle_viewport, "null"); + + if(veh.head_model != "") + { + setmodel(self.tur_head, veh.head_model); + setattachment(self.tur_head, self, veh.tag_head); + setattachment(self.vehicle_hudmodel, self.tur_head, veh.tag_hud); + setattachment(self.vehicle_viewport, self.vehicle_hudmodel, veh.tag_view); + } + else + { + setattachment(self.tur_head, self, ""); + setattachment(self.vehicle_hudmodel, self, veh.tag_hud); + setattachment(self.vehicle_viewport, self.vehicle_hudmodel, veh.tag_view); + } + + setsize(self, veh.mins, veh.maxs); + + if not(nodrop) + { + setorigin(self, self.origin); + tracebox(self.origin + '0 0 100', veh.mins, veh.maxs, self.origin - '0 0 10000', MOVE_WORLDONLY, self); + setorigin(self, trace_endpos); + } + + self.pos1 = self.origin; + self.pos2 = self.angles; + self.tur_head.team = self.team; + + VEH_ACTION(vehicle_id, VR_SETUP); + + if(autocvar_g_vehicles_delayspawn) + self.nextthink = time + self.respawntime + (random() * autocvar_g_vehicles_delayspawn_jitter); + else + self.nextthink = time + game_starttime; + + if(MUTATOR_CALLHOOK(VehicleSpawn)) + return FALSE; + + return TRUE; +} diff --git a/qcsrc/common/vehicles/sv_vehicles.qh b/qcsrc/common/vehicles/sv_vehicles.qh new file mode 100644 index 0000000000..a3349b86e4 --- /dev/null +++ b/qcsrc/common/vehicles/sv_vehicles.qh @@ -0,0 +1,99 @@ +// #define VEHICLES_USE_ODE + +// vehicle cvars +float autocvar_g_vehicles; +float autocvar_g_vehicles_enter; +float autocvar_g_vehicles_enter_radius; +float autocvar_g_vehicles_steal; +float autocvar_g_vehicles_crush_dmg; +float autocvar_g_vehicles_crush_force; +float autocvar_g_vehicles_delayspawn; +float autocvar_g_vehicles_delayspawn_jitter; +float autocvar_g_vehicles_allow_bots; +var float autocvar_g_vehicles_nex_damagerate = 0.5; +var float autocvar_g_vehicles_uzi_damagerate = 0.5; +var float autocvar_g_vehicles_rifle_damagerate = 0.75; +var float autocvar_g_vehicles_minstanex_damagerate = 0.001; +var float autocvar_g_vehicles_tag_damagerate = 5; + +// vehicle definitions +.entity gun1; +.entity gun2; +.entity gun3; +.entity vehicle_shieldent; /// Entity to disply the shild effect on damage +.entity vehicle; +.entity vehicle_viewport; +.entity vehicle_hudmodel; +.entity vehicle_controller; + +.entity gunner1; +.entity gunner2; + +.float vehicle_health; /// If self is player this is 0..100 indicating precentage of health left on vehicle. If self is vehile, this is the real health value. +.float vehicle_energy; /// If self is player this is 0..100 indicating precentage of energy left on vehicle. If self is vehile, this is the real energy value. +.float vehicle_shield; /// If self is player this is 0..100 indicating precentage of shield left on vehicle. If self is vehile, this is the real shield value. + +.float vehicle_ammo1; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real ammo1 value. +.float vehicle_reload1; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real reload1 value. +.float vehicle_ammo2; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real ammo2 value. +.float vehicle_reload2; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real reload2 value. + +.float sound_nexttime; +#define VOL_VEHICLEENGINE 1 + +const float SVC_SETVIEWPORT = 5; // Net.Protocol 0x05 +const float SVC_SETVIEWANGLES = 10; // Net.Protocol 0x0A +const float SVC_UPDATEENTITY = 128; // Net.Protocol 0x80 + +#define VHSF_NORMAL 0 +#define VHSF_FACTORY 2 + +.float hud; +.float dmg_time; + +.float volly_counter; + +const float MAX_AXH = 4; +.entity AuxiliaryXhair[MAX_AXH]; + +.entity wps_intruder; + +.entity lock_target; +.float lock_strength; +.float lock_time; +.float lock_soundtime; +const float DAMAGE_TARGETDRONE = 10; + +float force_fromtag_power; +float force_fromtag_normpower; +vector force_fromtag_origin; + +float vehicles_exit_running; + +#ifdef VEHICLES_USE_ODE +void(entity e, float physics_enabled) physics_enable = #540; // enable or disable physics on object +void(entity e, vector force, vector force_pos) physics_addforce = #541; // apply a force from certain origin, length of force vector is power of force +void(entity e, vector torque) physics_addtorque = #542; // add relative torque +#endif // VEHICLES_USE_ODE + +// functions used outside the vehicle code +void vehicles_exit(float eject); +void vehicles_enter(entity pl, entity veh); + +// vehicle functions +.void(float _spawnflag) vehicle_spawn; /// Vehicles custom fucntion to be efecuted when vehicle (re)spawns +.float(float _imp) vehicles_impulse; +.float vehicle_weapon2mode = volly_counter; +.void(float exit_flags) vehicle_exit; +const float VHEF_NORMAL = 0; /// User pressed exit key +const float VHEF_EJECT = 1; /// User pressed exit key 3 times fast (not implemented) or vehile is dying +const float VHEF_RELESE = 2; /// Release ownership, client possibly allready dissconnected / went spec / changed team / used "kill" (not implemented) + +// macros +#define VEHICLE_UPDATE_PLAYER(ply,fld,vhname) \ + ply.vehicle_##fld = (self.vehicle_##fld / autocvar_g_vehicle_##vhname##_##fld) * 100 + +#define vehicles_sweap_collision(orig,vel,dt,acm,mult) \ + traceline(orig, orig + vel * dt, MOVE_NORMAL, self); \ + if(trace_fraction != 1) \ + acm += normalize(self.origin - trace_endpos) * (vlen(vel) * mult) \ No newline at end of file diff --git a/qcsrc/common/vehicles/unit/bumblebee.qc b/qcsrc/common/vehicles/unit/bumblebee.qc new file mode 100644 index 0000000000..e22a4da704 --- /dev/null +++ b/qcsrc/common/vehicles/unit/bumblebee.qc @@ -0,0 +1,1224 @@ +#ifdef REGISTER_VEHICLE +REGISTER_VEHICLE( +/* VEH_##id */ BUMBLEBEE, +/* function */ v_bumblebee, +/* spawnflags */ VHF_DMGSHAKE, +/* mins,maxs */ '-130 -130 -130', '130 130 130', +/* model */ "models/vehicles/bumblebee_body.dpm", +/* head_model */ "", +/* hud_model */ "models/vehicles/spiderbot_cockpit.dpm", +/* tags */ "", "", "tag_viewport", +/* netname */ "bumblebee", +/* fullname */ _("Bumblebee") +); +#else + +const float BRG_SETUP = 2; +const float BRG_START = 4; +const float BRG_END = 8; + +#ifdef SVQC +float autocvar_g_vehicle_bumblebee_speed_forward; +float autocvar_g_vehicle_bumblebee_speed_strafe; +float autocvar_g_vehicle_bumblebee_speed_up; +float autocvar_g_vehicle_bumblebee_speed_down; +float autocvar_g_vehicle_bumblebee_turnspeed; +float autocvar_g_vehicle_bumblebee_pitchspeed; +float autocvar_g_vehicle_bumblebee_pitchlimit; +float autocvar_g_vehicle_bumblebee_friction; + +float autocvar_g_vehicle_bumblebee_energy; +float autocvar_g_vehicle_bumblebee_energy_regen; +float autocvar_g_vehicle_bumblebee_energy_regen_pause; + +float autocvar_g_vehicle_bumblebee_health; +float autocvar_g_vehicle_bumblebee_health_regen; +float autocvar_g_vehicle_bumblebee_health_regen_pause; + +float autocvar_g_vehicle_bumblebee_shield; +float autocvar_g_vehicle_bumblebee_shield_regen; +float autocvar_g_vehicle_bumblebee_shield_regen_pause; + +float autocvar_g_vehicle_bumblebee_cannon_cost; +float autocvar_g_vehicle_bumblebee_cannon_damage; +float autocvar_g_vehicle_bumblebee_cannon_radius; +float autocvar_g_vehicle_bumblebee_cannon_refire; +float autocvar_g_vehicle_bumblebee_cannon_speed; +float autocvar_g_vehicle_bumblebee_cannon_spread; +float autocvar_g_vehicle_bumblebee_cannon_force; + +float autocvar_g_vehicle_bumblebee_cannon_ammo; +float autocvar_g_vehicle_bumblebee_cannon_ammo_regen; +float autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause; + +var float autocvar_g_vehicle_bumblebee_cannon_lock = 0; + +float autocvar_g_vehicle_bumblebee_cannon_turnspeed; +float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down; +float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up; +float autocvar_g_vehicle_bumblebee_cannon_turnlimit_in; +float autocvar_g_vehicle_bumblebee_cannon_turnlimit_out; + + +float autocvar_g_vehicle_bumblebee_raygun_turnspeed; +float autocvar_g_vehicle_bumblebee_raygun_pitchlimit_down; +float autocvar_g_vehicle_bumblebee_raygun_pitchlimit_up; +float autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides; + +float autocvar_g_vehicle_bumblebee_raygun_range; +float autocvar_g_vehicle_bumblebee_raygun_dps; +float autocvar_g_vehicle_bumblebee_raygun_aps; +float autocvar_g_vehicle_bumblebee_raygun_fps; + +float autocvar_g_vehicle_bumblebee_raygun; +float autocvar_g_vehicle_bumblebee_healgun_hps; +float autocvar_g_vehicle_bumblebee_healgun_hmax; +float autocvar_g_vehicle_bumblebee_healgun_aps; +float autocvar_g_vehicle_bumblebee_healgun_amax; +float autocvar_g_vehicle_bumblebee_healgun_sps; +float autocvar_g_vehicle_bumblebee_healgun_locktime; + +float autocvar_g_vehicle_bumblebee_respawntime; + +float autocvar_g_vehicle_bumblebee_blowup_radius; +float autocvar_g_vehicle_bumblebee_blowup_coredamage; +float autocvar_g_vehicle_bumblebee_blowup_edgedamage; +float autocvar_g_vehicle_bumblebee_blowup_forceintensity; +var vector autocvar_g_vehicle_bumblebee_bouncepain; + +var float autocvar_g_vehicle_bumblebee = 0; + + +float bumble_raygun_send(entity to, float sf); + +void bumblebee_fire_cannon(entity _gun, string _tagname, entity _owner) +{ + vector v = gettaginfo(_gun, gettagindex(_gun, _tagname)); + vehicles_projectile("bigplasma_muzzleflash", "weapons/flacexp3.wav", + v, normalize(v_forward + randomvec() * autocvar_g_vehicle_bumblebee_cannon_spread) * autocvar_g_vehicle_bumblebee_cannon_speed, + autocvar_g_vehicle_bumblebee_cannon_damage, autocvar_g_vehicle_bumblebee_cannon_radius, autocvar_g_vehicle_bumblebee_cannon_force, 0, + DEATH_VH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, TRUE, TRUE, _owner); +} + +float bumblebee_gunner_frame() +{ + entity vehic = self.vehicle.owner; + entity gun = self.vehicle; + entity gunner = self; + self = vehic; + + vehic.solid = SOLID_NOT; + //setorigin(gunner, vehic.origin); + gunner.velocity = vehic.velocity; + + float _in, _out; + vehic.angles_x *= -1; + makevectors(vehic.angles); + vehic.angles_x *= -1; + if((gun == vehic.gun1)) + { + _in = autocvar_g_vehicle_bumblebee_cannon_turnlimit_in; + _out = autocvar_g_vehicle_bumblebee_cannon_turnlimit_out; + setorigin(gunner, vehic.origin + v_up * -16 + v_forward * -16 + v_right * 128); + } + else + { + _in = autocvar_g_vehicle_bumblebee_cannon_turnlimit_out; + _out = autocvar_g_vehicle_bumblebee_cannon_turnlimit_in; + setorigin(gunner, vehic.origin + v_up * -16 + v_forward * -16 + v_right * -128); + } + + crosshair_trace(gunner); + vector _ct = trace_endpos; + vector ad; + + if(autocvar_g_vehicle_bumblebee_cannon_lock) + { + if(gun.lock_time < time) + gun.enemy = world; + + if(trace_ent) + if(trace_ent.movetype) + if(trace_ent.takedamage) + if(!trace_ent.deadflag) + { + if(teamplay) + { + if(trace_ent.team != gunner.team) + { + gun.enemy = trace_ent; + gun.lock_time = time + 5; + } + } + else + { + gun.enemy = trace_ent; + gun.lock_time = time + 5; + } + } + } + + if(gun.enemy) + { + float i, distance, impact_time; + + vector vf = real_origin(gun.enemy); + vector _vel = gun.enemy.velocity; + if(gun.enemy.movetype == MOVETYPE_WALK) + _vel_z *= 0.1; + + + ad = vf; + for(i = 0; i < 4; ++i) + { + distance = vlen(ad - gunner.origin); + impact_time = distance / autocvar_g_vehicle_bumblebee_cannon_speed; + ad = vf + _vel * impact_time; + } + trace_endpos = ad; + + + UpdateAuxiliaryXhair(gunner, ad, '1 0 1', 1); + vehicle_aimturret(vehic, trace_endpos, gun, "fire", + autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up, + _out * -1, _in, autocvar_g_vehicle_bumblebee_cannon_turnspeed); + + } + else + vehicle_aimturret(vehic, _ct, gun, "fire", + autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up, + _out * -1, _in, autocvar_g_vehicle_bumblebee_cannon_turnspeed); + + if(gunner.BUTTON_ATCK) + if(time > gun.attack_finished_single) + if(gun.vehicle_energy >= autocvar_g_vehicle_bumblebee_cannon_cost) + { + gun.vehicle_energy -= autocvar_g_vehicle_bumblebee_cannon_cost; + bumblebee_fire_cannon(gun, "fire", gunner); + gun.delay = time; + gun.attack_finished_single = time + autocvar_g_vehicle_bumblebee_cannon_refire; + } + + VEHICLE_UPDATE_PLAYER(gunner, health, bumblebee); + + if(vehic.vehicle_flags & VHF_HASSHIELD) + VEHICLE_UPDATE_PLAYER(gunner, shield, bumblebee); + + ad = gettaginfo(gun, gettagindex(gun, "fire")); + traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, gun); + + UpdateAuxiliaryXhair(gunner, trace_endpos, ('1 0 0' * gunner.vehicle_reload1) + ('0 1 0' *(1 - gunner.vehicle_reload1)), 0); + + if(vehic.owner) + UpdateAuxiliaryXhair(vehic.owner, trace_endpos, ('1 0 0' * gunner.vehicle_reload1) + ('0 1 0' *(1 - gunner.vehicle_reload1)), ((gunner == vehic.gunner1) ? 1 : 2)); + + vehic.solid = SOLID_BBOX; + gunner.BUTTON_ATCK = gunner.BUTTON_ATCK2 = gunner.BUTTON_CROUCH = 0; + gunner.vehicle_energy = (gun.vehicle_energy / autocvar_g_vehicle_bumblebee_cannon_ammo) * 100; + + self = gunner; + return 1; +} + +void bumblebee_gunner_exit(float _exitflag) +{ + if(IS_REAL_CLIENT(self)) + { + msg_entity = self; + WriteByte(MSG_ONE, SVC_SETVIEWPORT); + WriteEntity(MSG_ONE, self); + + WriteByte(MSG_ONE, SVC_SETVIEWANGLES); + WriteAngle(MSG_ONE, 0); + WriteAngle(MSG_ONE, self.vehicle.angles_y); + WriteAngle(MSG_ONE, 0); + } + + CSQCVehicleSetup(self, HUD_NORMAL); + setsize(self, PL_MIN, PL_MAX); + + self.takedamage = DAMAGE_AIM; + self.solid = SOLID_SLIDEBOX; + self.movetype = MOVETYPE_WALK; + self.effects &= ~EF_NODRAW; + self.alpha = 1; + self.PlayerPhysplug = func_null; + self.view_ofs = PL_VIEW_OFS; + self.event_damage = PlayerDamage; + self.hud = HUD_NORMAL; + self.switchweapon = self.vehicle.switchweapon; + + vh_player = self; + vh_vehicle = self.vehicle; + MUTATOR_CALLHOOK(VehicleExit); + self = vh_player; + self.vehicle = vh_vehicle; + + self.vehicle.vehicle_hudmodel.viewmodelforclient = self.vehicle; + + fixedmakevectors(self.vehicle.owner.angles); + + if(self == self.vehicle.owner.gunner1) + { + self.vehicle.owner.gunner1 = world; + } + else if(self == self.vehicle.owner.gunner2) + { + self.vehicle.owner.gunner2 = world; + v_right *= -1; + } + else + dprint("^1self != gunner1 or gunner2, this is a BIG PROBLEM, tell tZork this happend.\n"); + + vector spot = self.vehicle.owner.origin + + v_up * 128 + v_right * 300; + spot = vehicles_findgoodexit(spot); + //setorigin(self , spot); + + self.velocity = 0.75 * self.vehicle.owner.velocity + normalize(spot - self.vehicle.owner.origin) * 200; + self.velocity_z += 10; + + self.vehicle.phase = time + 5; + self.vehicle = world; +} + +float bumblebee_gunner_enter() +{ + RemoveGrapplingHook(other); + entity _gun, _gunner; + if(!self.gunner1) + { + _gun = self.gun1; + _gunner = self.gunner1; + self.gunner1 = other; + } + else if(!self.gunner2) + { + _gun = self.gun2; + _gunner = self.gunner2; + self.gunner2 = other; + } + else + { + dprint("^1ERROR:^7Tried to enter a fully occupied vehicle!\n"); + return FALSE; + } + + _gunner = other; + _gunner.vehicle = _gun; + _gun.switchweapon = other.switchweapon; + _gun.vehicle_exit = bumblebee_gunner_exit; + + other.angles = self.angles; + other.takedamage = DAMAGE_NO; + other.solid = SOLID_NOT; + other.movetype = MOVETYPE_NOCLIP; + other.alpha = -1; + other.event_damage = func_null; + other.view_ofs = '0 0 0'; + other.hud = _gun.hud; + other.PlayerPhysplug = _gun.PlayerPhysplug; + other.vehicle_ammo1 = self.vehicle_ammo1; + other.vehicle_ammo2 = self.vehicle_ammo2; + other.vehicle_reload1 = self.vehicle_reload1; + other.vehicle_reload2 = self.vehicle_reload2; + other.vehicle_energy = self.vehicle_energy; + other.PlayerPhysplug = bumblebee_gunner_frame; + other.flags &= ~FL_ONGROUND; + + msg_entity = other; + WriteByte(MSG_ONE, SVC_SETVIEWPORT); + WriteEntity(MSG_ONE, _gun.vehicle_viewport); + WriteByte(MSG_ONE, SVC_SETVIEWANGLES); + WriteAngle(MSG_ONE, _gun.angles_x + self.angles_x); // tilt + WriteAngle(MSG_ONE, _gun.angles_y + self.angles_y); // yaw + WriteAngle(MSG_ONE, 0); // roll + _gun.vehicle_hudmodel.viewmodelforclient = other; + + CSQCVehicleSetup(other, other.hud); + + vh_player = other; + vh_vehicle = _gun; + MUTATOR_CALLHOOK(VehicleEnter); + other = vh_player; + _gun = vh_vehicle; + + return TRUE; +} + +float vehicles_valid_pilot() +{ + if not(IS_PLAYER(other)) + return FALSE; + + if(other.deadflag != DEAD_NO) + return FALSE; + + if(other.vehicle != world) + return FALSE; + + if not(IS_REAL_CLIENT(other)) + if(!autocvar_g_vehicles_allow_bots) + return FALSE; + + if(teamplay && other.team != self.team) + return FALSE; + + return TRUE; +} + +void bumblebee_touch() +{ + if(self.gunner1 != world && self.gunner2 != world) + { + vehicles_touch(); + return; + } + + if(vehicles_valid_pilot()) + { + if(self.gun1.phase <= time) + if(bumblebee_gunner_enter()) + return; + + if(self.gun2.phase <= time) + if(bumblebee_gunner_enter()) + return; + } + + vehicles_touch(); +} + +void bumblebee_regen() +{ + if(self.gun1.delay + autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause < time) + self.gun1.vehicle_energy = min(autocvar_g_vehicle_bumblebee_cannon_ammo, + self.gun1.vehicle_energy + autocvar_g_vehicle_bumblebee_cannon_ammo_regen * frametime); + + if(self.gun2.delay + autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause < time) + self.gun2.vehicle_energy = min(autocvar_g_vehicle_bumblebee_cannon_ammo, + self.gun2.vehicle_energy + autocvar_g_vehicle_bumblebee_cannon_ammo_regen * frametime); + + if(self.vehicle_flags & VHF_SHIELDREGEN) + vehicles_regen(self.dmg_time, vehicle_shield, autocvar_g_vehicle_bumblebee_shield, autocvar_g_vehicle_bumblebee_shield_regen_pause, autocvar_g_vehicle_bumblebee_shield_regen, frametime, TRUE); + + if(self.vehicle_flags & VHF_HEALTHREGEN) + vehicles_regen(self.dmg_time, vehicle_health, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_health_regen_pause, autocvar_g_vehicle_bumblebee_health_regen, frametime, FALSE); + + if(self.vehicle_flags & VHF_ENERGYREGEN) + vehicles_regen(self.wait, vehicle_energy, autocvar_g_vehicle_bumblebee_energy, autocvar_g_vehicle_bumblebee_energy_regen_pause, autocvar_g_vehicle_bumblebee_energy_regen, frametime, FALSE); + +} + +float bumblebee_pilot_frame() +{ + entity pilot, vehic; + vector newvel; + + pilot = self; + vehic = self.vehicle; + self = vehic; + + + if(vehic.deadflag != DEAD_NO) + { + self = pilot; + pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = 0; + return 1; + } + + bumblebee_regen(); + + crosshair_trace(pilot); + + vector vang; + float ftmp; + + vang = vehic.angles; + newvel = vectoangles(normalize(trace_endpos - self.origin + '0 0 32')); + vang_x *= -1; + newvel_x *= -1; + if(newvel_x > 180) newvel_x -= 360; + if(newvel_x < -180) newvel_x += 360; + if(newvel_y > 180) newvel_y -= 360; + if(newvel_y < -180) newvel_y += 360; + + ftmp = shortangle_f(pilot.v_angle_y - vang_y, vang_y); + if(ftmp > 180) ftmp -= 360; + if(ftmp < -180) ftmp += 360; + vehic.avelocity_y = bound(-autocvar_g_vehicle_bumblebee_turnspeed, ftmp + vehic.avelocity_y * 0.9, autocvar_g_vehicle_bumblebee_turnspeed); + + // Pitch + ftmp = 0; + if(pilot.movement_x > 0 && vang_x < autocvar_g_vehicle_bumblebee_pitchlimit) + ftmp = 4; + else if(pilot.movement_x < 0 && vang_x > -autocvar_g_vehicle_bumblebee_pitchlimit) + ftmp = -8; + + newvel_x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x , autocvar_g_vehicle_bumblebee_pitchlimit); + ftmp = vang_x - bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x + ftmp, autocvar_g_vehicle_bumblebee_pitchlimit); + vehic.avelocity_x = bound(-autocvar_g_vehicle_bumblebee_pitchspeed, ftmp + vehic.avelocity_x * 0.9, autocvar_g_vehicle_bumblebee_pitchspeed); + + vehic.angles_x = anglemods(vehic.angles_x); + vehic.angles_y = anglemods(vehic.angles_y); + vehic.angles_z = anglemods(vehic.angles_z); + + makevectors('0 1 0' * vehic.angles_y); + newvel = vehic.velocity * -autocvar_g_vehicle_bumblebee_friction; + + if(pilot.movement_x != 0) + { + if(pilot.movement_x > 0) + newvel += v_forward * autocvar_g_vehicle_bumblebee_speed_forward; + else if(pilot.movement_x < 0) + newvel -= v_forward * autocvar_g_vehicle_bumblebee_speed_forward; + } + + if(pilot.movement_y != 0) + { + if(pilot.movement_y < 0) + newvel -= v_right * autocvar_g_vehicle_bumblebee_speed_strafe; + else if(pilot.movement_y > 0) + newvel += v_right * autocvar_g_vehicle_bumblebee_speed_strafe; + ftmp = newvel * v_right; + ftmp *= frametime * 0.1; + vehic.angles_z = bound(-15, vehic.angles_z + ftmp, 15); + } + else + { + vehic.angles_z *= 0.95; + if(vehic.angles_z >= -1 && vehic.angles_z <= -1) + vehic.angles_z = 0; + } + + if(pilot.BUTTON_CROUCH) + newvel -= v_up * autocvar_g_vehicle_bumblebee_speed_down; + else if(pilot.BUTTON_JUMP) + newvel += v_up * autocvar_g_vehicle_bumblebee_speed_up; + + vehic.velocity += newvel * frametime; + pilot.velocity = pilot.movement = vehic.velocity; + + + if(autocvar_g_vehicle_bumblebee_healgun_locktime) + { + if(vehic.tur_head.lock_time < time || vehic.tur_head.enemy.deadflag) + vehic.tur_head.enemy = world; + + if(trace_ent) + if(trace_ent.movetype) + if(trace_ent.takedamage) + if(!trace_ent.deadflag) + { + if(teamplay) + { + if(trace_ent.team == pilot.team) + { + vehic.tur_head.enemy = trace_ent; + vehic.tur_head.lock_time = time + autocvar_g_vehicle_bumblebee_healgun_locktime; + } + } + else + { + vehic.tur_head.enemy = trace_ent; + vehic.tur_head.lock_time = time + autocvar_g_vehicle_bumblebee_healgun_locktime; + } + } + + if(vehic.tur_head.enemy) + { + trace_endpos = real_origin(vehic.tur_head.enemy); + UpdateAuxiliaryXhair(pilot, trace_endpos, '0 0.75 0', 0); + } + } + + vang = vehicle_aimturret(vehic, trace_endpos, self.gun3, "fire", + autocvar_g_vehicle_bumblebee_raygun_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_raygun_pitchlimit_up, + autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides * -1, autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides, autocvar_g_vehicle_bumblebee_raygun_turnspeed); + + if((pilot.BUTTON_ATCK || pilot.BUTTON_ATCK2) && (vehic.vehicle_energy > autocvar_g_vehicle_bumblebee_raygun_dps * sys_frametime || autocvar_g_vehicle_bumblebee_raygun == 0)) + { + vehic.gun3.enemy.realowner = pilot; + vehic.gun3.enemy.effects &= ~EF_NODRAW; + + vehic.gun3.enemy.hook_start = gettaginfo(vehic.gun3, gettagindex(vehic.gun3, "fire")); + vehic.gun3.enemy.SendFlags |= BRG_START; + + traceline(vehic.gun3.enemy.hook_start, vehic.gun3.enemy.hook_start + v_forward * autocvar_g_vehicle_bumblebee_raygun_range, MOVE_NORMAL, vehic); + + if(trace_ent) + { + if(autocvar_g_vehicle_bumblebee_raygun) + { + Damage(trace_ent, vehic, pilot, autocvar_g_vehicle_bumblebee_raygun_dps * sys_frametime, DEATH_GENERIC, trace_endpos, v_forward * autocvar_g_vehicle_bumblebee_raygun_fps * sys_frametime); + vehic.vehicle_energy -= autocvar_g_vehicle_bumblebee_raygun_aps * sys_frametime; + } + else + { + if(trace_ent.deadflag == DEAD_NO) + if((teamplay && trace_ent.team == pilot.team) || !teamplay) + { + + if(trace_ent.vehicle_flags & VHF_ISVEHICLE) + { + if(autocvar_g_vehicle_bumblebee_healgun_sps && trace_ent.vehicle_health <= trace_ent.tur_health) + trace_ent.vehicle_shield = min(trace_ent.vehicle_shield + autocvar_g_vehicle_bumblebee_healgun_sps * frametime, trace_ent.tur_head.tur_health); + + if(autocvar_g_vehicle_bumblebee_healgun_hps) + trace_ent.vehicle_health = min(trace_ent.vehicle_health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, trace_ent.tur_health); + } + else if(IS_CLIENT(trace_ent)) + { + if(trace_ent.health <= autocvar_g_vehicle_bumblebee_healgun_hmax && autocvar_g_vehicle_bumblebee_healgun_hps) + trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, autocvar_g_vehicle_bumblebee_healgun_hmax); + + if(trace_ent.armorvalue <= autocvar_g_vehicle_bumblebee_healgun_amax && autocvar_g_vehicle_bumblebee_healgun_aps) + trace_ent.armorvalue = min(trace_ent.armorvalue + autocvar_g_vehicle_bumblebee_healgun_aps * frametime, autocvar_g_vehicle_bumblebee_healgun_amax); + + trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, autocvar_g_vehicle_bumblebee_healgun_hmax); + } + else if(trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET) + { + if(trace_ent.health <= trace_ent.tur_health && autocvar_g_vehicle_bumblebee_healgun_hps) + trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, trace_ent.tur_health); + //else ..hmmm what? ammo? + + trace_ent.SendFlags |= TNSF_STATUS; + } + } + } + } + + vehic.gun3.enemy.hook_end = trace_endpos; + setorigin(vehic.gun3.enemy, trace_endpos); + vehic.gun3.enemy.SendFlags |= BRG_END; + + vehic.wait = time + 1; + } + else + vehic.gun3.enemy.effects |= EF_NODRAW; + /*{ + if(vehic.gun3.enemy) + remove(vehic.gun3.enemy); + + vehic.gun3.enemy = world; + } + */ + + VEHICLE_UPDATE_PLAYER(pilot, health, bumblebee); + VEHICLE_UPDATE_PLAYER(pilot, energy, bumblebee); + + pilot.vehicle_ammo1 = (vehic.gun1.vehicle_energy / autocvar_g_vehicle_bumblebee_cannon_ammo) * 100; + pilot.vehicle_ammo2 = (vehic.gun2.vehicle_energy / autocvar_g_vehicle_bumblebee_cannon_ammo) * 100; + + if(vehic.vehicle_flags & VHF_HASSHIELD) + VEHICLE_UPDATE_PLAYER(pilot, shield, bumblebee); + + vehic.angles_x *= -1; + makevectors(vehic.angles); + vehic.angles_x *= -1; + setorigin(pilot, vehic.origin + v_up * 48 + v_forward * 160); + + pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = pilot.BUTTON_CROUCH = 0; + self = pilot; + + return 1; +} + +void bumblebee_exit(float eject) +{ + self.touch = vehicles_touch; + self.think = vehicles_think; + self.nextthink = time; + + if(!self.owner) + return; + + fixedmakevectors(self.angles); + vector spot; + if(vlen(self.velocity) > autocvar_g_vehicle_bumblebee_speed_forward * 0.5) + spot = self.origin + v_up * 128 + v_forward * 200; + else + spot = self.origin + v_up * 128 - v_forward * 200; + + spot = vehicles_findgoodexit(spot); + + // Hide beam + if(self.gun3.enemy || !wasfreed(self.gun3.enemy)) { + self.gun3.enemy.effects |= EF_NODRAW; + } + + self.owner.velocity = 0.75 * self.vehicle.velocity + normalize(spot - self.vehicle.origin) * 200; + self.owner.velocity_z += 10; + setorigin(self.owner, spot); + + antilag_clear(self.owner); + self.owner = world; +} + +void bumblebee_blowup() +{ + RadiusDamage(self, self.enemy, autocvar_g_vehicle_bumblebee_blowup_coredamage, + autocvar_g_vehicle_bumblebee_blowup_edgedamage, + autocvar_g_vehicle_bumblebee_blowup_radius, self, + autocvar_g_vehicle_bumblebee_blowup_forceintensity, + DEATH_VH_BUMB_DEATH, world); + + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("explosion_large"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); + + if(self.owner.deadflag == DEAD_DYING) + self.owner.deadflag = DEAD_DEAD; + + remove(self); +} + +void bumblebee_diethink() +{ + if(time >= self.wait) + self.think = bumblebee_blowup; + + if(random() < 0.1) + { + sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); + } + + self.nextthink = time + 0.1; +} + +float bumble_raygun_send(entity to, float sf) +{ + WriteByte(MSG_ENTITY, ENT_CLIENT_BUMBLE_RAYGUN); + + WriteByte(MSG_ENTITY, sf); + if(sf & BRG_SETUP) + { + WriteByte(MSG_ENTITY, num_for_edict(self.realowner)); + WriteByte(MSG_ENTITY, self.realowner.team); + WriteByte(MSG_ENTITY, self.cnt); + } + + if(sf & BRG_START) + { + WriteCoord(MSG_ENTITY, self.hook_start_x); + WriteCoord(MSG_ENTITY, self.hook_start_y); + WriteCoord(MSG_ENTITY, self.hook_start_z); + } + + if(sf & BRG_END) + { + WriteCoord(MSG_ENTITY, self.hook_end_x); + WriteCoord(MSG_ENTITY, self.hook_end_y); + WriteCoord(MSG_ENTITY, self.hook_end_z); + } + + return TRUE; +} + +void spawnfunc_vehicle_bumblebee() +{ + if not(autocvar_g_vehicle_bumblebee) { remove(self); return; } + if not(vehicle_initialize(VEH_BUMBLEBEE, FALSE)) { remove(self); return; } +} + +float v_bumblebee(float req) +{ + switch(req) + { + case VR_IMPACT: + { + if(autocvar_g_vehicle_bumblebee_bouncepain) + vehicles_impact(autocvar_g_vehicle_bumblebee_bouncepain_x, autocvar_g_vehicle_bumblebee_bouncepain_y, autocvar_g_vehicle_bumblebee_bouncepain_z); + + return TRUE; + } + case VR_ENTER: + { + self.touch = bumblebee_touch; + self.nextthink = 0; + self.movetype = MOVETYPE_BOUNCEMISSILE; + return TRUE; + } + case VR_THINK: + { + self.movetype = MOVETYPE_TOSS; + + self.angles_z *= 0.8; + self.angles_x *= 0.8; + + self.nextthink = time + 0.05; + + if(!self.owner) + { + entity oldself = self; + if(self.gunner1) + { + self = self.gunner1; + oldself.gun1.vehicle_exit(VHEF_EJECT); + entity oldother = other; + other = self; + self = oldself; + self.phase = 0; + self.touch(); + other = oldother; + return TRUE; + } + + if(self.gunner2) + { + self = self.gunner2; + oldself.gun2.vehicle_exit(VHEF_EJECT); + entity oldother = other; + other = self; + self = oldself; + self.phase = 0; + self.touch(); + other = oldother; + return TRUE; + } + } + + return TRUE; + } + case VR_DEATH: + { + entity oldself = self; + + // Hide beam + if(self.gun3.enemy || !wasfreed(self.gun3.enemy)) + self.gun3.enemy.effects |= EF_NODRAW; + + if(self.gunner1) + { + self = self.gunner1; + oldself.gun1.vehicle_exit(VHEF_EJECT); + self = oldself; + } + + if(self.gunner2) + { + self = self.gunner2; + oldself.gun2.vehicle_exit(VHEF_EJECT); + self = oldself; + } + + self.vehicle_exit(VHEF_EJECT); + + fixedmakevectors(self.angles); + vehicle_tossgib(self.gun1, self.velocity + v_right * 300 + v_up * 100 + randomvec() * 200, "cannon_right", rint(random()), rint(random()), 6, randomvec() * 200); + vehicle_tossgib(self.gun2, self.velocity + v_right * -300 + v_up * 100 + randomvec() * 200, "cannon_left", rint(random()), rint(random()), 6, randomvec() * 200); + vehicle_tossgib(self.gun3, self.velocity + v_forward * 300 + v_up * -100 + randomvec() * 200, "raygun", rint(random()), rint(random()), 6, randomvec() * 300); + + entity _body = vehicle_tossgib(self, self.velocity + randomvec() * 200, "", rint(random()), rint(random()), 6, randomvec() * 100); + + if(random() > 0.5) + _body.touch = bumblebee_blowup; + else + _body.touch = func_null; + + _body.think = bumblebee_diethink; + _body.nextthink = time; + _body.wait = time + 2 + (random() * 8); + _body.owner = self; + _body.enemy = self.enemy; + + pointparticles(particleeffectnum("explosion_medium"), findbetterlocation(self.origin, 16), '0 0 0', 1); + + self.health = 0; + self.event_damage = func_null; + self.solid = SOLID_CORPSE; + self.takedamage = DAMAGE_NO; + self.deadflag = DEAD_DYING; + self.movetype = MOVETYPE_NONE; + self.effects = EF_NODRAW; + self.colormod = '0 0 0'; + self.avelocity = '0 0 0'; + self.velocity = '0 0 0'; + self.touch = func_null; + self.nextthink = 0; + + setorigin(self, self.pos1); + return TRUE; + } + case VR_SPAWN: + { + if not(self.gun1) + { + // for some reason, autosizing of the shield entity refuses to work for this one so set it up in advance. + self.vehicle_shieldent = spawn(); + self.vehicle_shieldent.effects = EF_LOWPRECISION; + setmodel(self.vehicle_shieldent, "models/vhshield.md3"); + setattachment(self.vehicle_shieldent, self, ""); + setorigin(self.vehicle_shieldent, real_origin(self) - self.origin); + self.vehicle_shieldent.scale = 512 / vlen(self.maxs - self.mins); + self.vehicle_shieldent.think = shieldhit_think; + self.vehicle_shieldent.alpha = -1; + self.vehicle_shieldent.effects = EF_LOWPRECISION | EF_NODRAW; + + self.gun1 = spawn(); + self.gun2 = spawn(); + self.gun3 = spawn(); + + self.vehicle_flags |= VHF_MULTISLOT; + + self.gun1.owner = self; + self.gun2.owner = self; + self.gun3.owner = self; + + setmodel(self.gun1, "models/vehicles/bumblebee_plasma_right.dpm"); + setmodel(self.gun2, "models/vehicles/bumblebee_plasma_left.dpm"); + setmodel(self.gun3, "models/vehicles/bumblebee_ray.dpm"); + + setattachment(self.gun1, self, "cannon_right"); + setattachment(self.gun2, self, "cannon_left"); + + // Angled bones are no fun, messes up gun-aim; so work arround it. + self.gun3.pos1 = self.angles; + self.angles = '0 0 0'; + vector ofs = gettaginfo(self, gettagindex(self, "raygun")); + ofs -= self.origin; + setattachment(self.gun3, self, ""); + setorigin(self.gun3, ofs); + self.angles = self.gun3.pos1; + + vehicle_addplayerslot(self, self.gun1, HUD_BUMBLEBEE_GUN, "models/vehicles/wakizashi_cockpit.dpm", bumblebee_gunner_frame, bumblebee_gunner_exit); + vehicle_addplayerslot(self, self.gun2, HUD_BUMBLEBEE_GUN, "models/vehicles/wakizashi_cockpit.dpm", bumblebee_gunner_frame, bumblebee_gunner_exit); + + setorigin(self.vehicle_hudmodel, '50 0 -5'); // Move cockpit forward - down. + setorigin(self.vehicle_viewport, '5 0 2'); // Move camera forward up + + //fixme-model-bones + setorigin(self.gun1.vehicle_hudmodel, '90 -27 -23'); + setorigin(self.gun1.vehicle_viewport, '-85 0 50'); + //fixme-model-bones + setorigin(self.gun2.vehicle_hudmodel, '90 27 -23'); + setorigin(self.gun2.vehicle_viewport, '-85 0 50'); + + self.scale = 1.5; + + // Raygun beam + if(self.gun3.enemy == world) + { + self.gun3.enemy = spawn(); + Net_LinkEntity(self.gun3.enemy, TRUE, 0, bumble_raygun_send); + self.gun3.enemy.SendFlags = BRG_SETUP; + self.gun3.enemy.cnt = autocvar_g_vehicle_bumblebee_raygun; + self.gun3.enemy.effects = EF_NODRAW | EF_LOWPRECISION; + } + } + + self.vehicle_health = autocvar_g_vehicle_bumblebee_health; + self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield; + self.solid = SOLID_BBOX; + self.movetype = MOVETYPE_TOSS; + self.damageforcescale = 0.025; + + self.PlayerPhysplug = bumblebee_pilot_frame; + + setorigin(self, self.origin + '0 0 25'); + return TRUE; + } + case VR_SETUP: + { + if(autocvar_g_vehicle_bumblebee_energy) + if(autocvar_g_vehicle_bumblebee_energy_regen) + self.vehicle_flags |= VHF_ENERGYREGEN; + + if(autocvar_g_vehicle_bumblebee_shield) + self.vehicle_flags |= VHF_HASSHIELD; + + if(autocvar_g_vehicle_bumblebee_shield_regen) + self.vehicle_flags |= VHF_SHIELDREGEN; + + if(autocvar_g_vehicle_bumblebee_health_regen) + self.vehicle_flags |= VHF_HEALTHREGEN; + + self.vehicle_exit = bumblebee_exit; + self.respawntime = autocvar_g_vehicle_bumblebee_respawntime; + self.vehicle_health = autocvar_g_vehicle_bumblebee_health; + self.max_health = self.vehicle_health; + self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield; + + return TRUE; + } + case VR_PRECACHE: + { + precache_model("models/vehicles/bumblebee_body.dpm"); + precache_model("models/vehicles/bumblebee_plasma_left.dpm"); + precache_model("models/vehicles/bumblebee_plasma_right.dpm"); + precache_model("models/vehicles/bumblebee_ray.dpm"); + precache_model("models/vehicles/wakizashi_cockpit.dpm"); + precache_model("models/vehicles/spiderbot_cockpit.dpm"); + precache_model("models/vehicles/raptor_cockpit.dpm"); + return TRUE; + } + } + + return TRUE; +} + +#endif // SVQC +#ifdef CSQC + +void bumble_raygun_draw() +{ + float _len; + vector _dir; + vector _vtmp1, _vtmp2; + + _len = vlen(self.origin - self.move_origin); + _dir = normalize(self.move_origin - self.origin); + + if(self.total_damages < time) + { + boxparticles(self.traileffect, self, self.origin, self.origin + _dir * -64, _dir * -_len , _dir * -_len, 1, PARTICLES_USEALPHA); + boxparticles(self.lip, self, self.move_origin, self.move_origin + _dir * -64, _dir * -200 , _dir * -200, 1, PARTICLES_USEALPHA); + self.total_damages = time + 0.1; + } + + float i, df, sz, al; + for(i = -0.1; i < 0.2; i += 0.1) + { + df = DRAWFLAG_NORMAL; //((random() < 0.5) ? DRAWFLAG_ADDITIVE : DRAWFLAG_SCREEN); + sz = 5 + random() * 5; + al = 0.25 + random() * 0.5; + _vtmp1 = self.origin + _dir * _len * (0.25 + i); + _vtmp1 += (randomvec() * (_len * 0.2) * (frametime * 2)); //self.raygun_l1; + Draw_CylindricLine(self.origin, _vtmp1, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin); + + _vtmp2 = self.origin + _dir * _len * (0.5 + i); + _vtmp2 += (randomvec() * (_len * 0.2) * (frametime * 5)); //self.raygun_l2; + Draw_CylindricLine(_vtmp1, _vtmp2, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin); + + _vtmp1 = self.origin + _dir * _len * (0.75 + i); + _vtmp1 += randomvec() * (_len * 0.2) * (frametime * 10); //self.raygun_l3; + Draw_CylindricLine(_vtmp2, _vtmp1, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin); + + Draw_CylindricLine(_vtmp1, self.move_origin + randomvec() * 32, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin); + } +} + +void bumble_raygun_read(float bIsNew) +{ + float sf = ReadByte(); + + if(sf & BRG_SETUP) + { + self.cnt = ReadByte(); + self.team = ReadByte(); + self.cnt = ReadByte(); + + if(self.cnt) + self.colormod = '1 0 0'; + else + self.colormod = '0 1 0'; + + self.traileffect = particleeffectnum("healray_muzzleflash"); + self.lip = particleeffectnum("healray_impact"); + + self.draw = bumble_raygun_draw; + } + + + if(sf & BRG_START) + { + self.origin_x = ReadCoord(); + self.origin_y = ReadCoord(); + self.origin_z = ReadCoord(); + setorigin(self, self.origin); + } + + if(sf & BRG_END) + { + self.move_origin_x = ReadCoord(); + self.move_origin_y = ReadCoord(); + self.move_origin_z = ReadCoord(); + } +} + +float v_bumblebee(float req) +{ + switch(req) + { + case VR_HUD: + { + if(autocvar_r_letterbox) + return TRUE; + + vector picsize, hudloc = '0 0 0', pic2size, picloc; + + // Fetch health & ammo stats + HUD_GETVEHICLESTATS + + picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale; + hudloc_y = vid_conheight - picsize_y; + hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5; + + drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL); + + shield *= 0.01; + vh_health *= 0.01; + energy *= 0.01; + reload1 *= 0.01; + + pic2size = draw_getimagesize(bumb_ico) * (autocvar_cl_vehicles_hudscale * 0.8); + picloc = picsize * 0.5 - pic2size * 0.5; + + if(vh_health < 0.25) + drawpic(hudloc + picloc, bumb_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, bumb_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL); + + drawpic(hudloc + picloc, bumb_lgun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, bumb_lgun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL); + + // Health bar + picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale; + picloc = '69 69 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight); + drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale; + picloc = '37 65 0' * autocvar_cl_vehicles_hudscale; + if(vh_health < 0.25) + { + if(alarm1time < time) + { + alarm1time = time + 2; + vehicle_alarm(self, CH_PAIN_SINGLE, "vehicles/alarm.wav"); + } + + drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + } + else + { + drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + if(alarm1time) + { + vehicle_alarm(self, CH_PAIN_SINGLE, "misc/null.wav"); + alarm1time = 0; + } + } + + // Shield bar + picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale; + picloc = '69 140 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight); + drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picloc = '40 136 0' * autocvar_cl_vehicles_hudscale; + picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale; + if(shield < 0.25) + { + if(alarm2time < time) + { + alarm2time = time + 1; + vehicle_alarm(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav"); + } + drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + } + else + { + drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + if(alarm2time) + { + vehicle_alarm(self, CH_TRIGGER_SINGLE, "misc/null.wav"); + alarm2time = 0; + } + } + + ammo1 *= 0.01; + ammo2 *= 0.01; + + // Gunner1 bar + picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale; + picloc = '450 69 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * ammo1, vid_conheight); + drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + + // Right gunner slot occupied? + if(!AuxiliaryXhair[1].draw2d) + { + shield = (picsize_x * 0.5) - (0.5 * stringwidth(_("No right gunner!"), FALSE, '1 0 0' * picsize_y + '0 1 0' * picsize_y)); + drawfill(hudloc + picloc - '0.2 0.2 0', picsize + '0.4 0.4 0', '0.25 0.25 0.25', 0.75, DRAWFLAG_NORMAL); + drawstring(hudloc + picloc + '1 0 0' * shield, _("No right gunner!"), '1 0 0' * picsize_y + '0 1 0' * picsize_y, '1 0 0' + '0 1 1' * sin(time * 10), 1, DRAWFLAG_NORMAL); + } + + // .. and icon + picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale; + picloc = '664 60 0' * autocvar_cl_vehicles_hudscale; + if(ammo1 < 0.2) + drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + + // Gunner2 bar + picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale; + picloc = '450 140 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * ammo2, vid_conheight); + drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + // Left gunner slot occupied? + if(!AuxiliaryXhair[2].draw2d) + { + shield = (picsize_x * 0.5) - (0.5 * stringwidth(_("No left gunner!"), FALSE, '1 0 0' * picsize_y + '0 1 0' * picsize_y)); + drawfill(hudloc + picloc - '0.2 0.2 0', picsize + '0.4 0.4 0', '0.25 0.25 0.25', 0.75, DRAWFLAG_NORMAL); + drawstring(hudloc + picloc + '1 0 0' * shield, _("No left gunner!"), '1 0 0' * picsize_y + '0 1 0' * picsize_y, '1 0 0' + '0 1 1' * sin(time * 10), 1, DRAWFLAG_NORMAL); + } + + // .. and icon + picsize = 1.5 * draw_getimagesize(hud_energy) * autocvar_cl_vehicles_hudscale; + picloc = '664 130 0' * autocvar_cl_vehicles_hudscale; + if(ammo2 < 0.2) + drawpic(hudloc + picloc, hud_energy, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, hud_energy, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + + if (scoreboard_showscores) + HUD_DrawScoreboard(); + else + { + picsize = draw_getimagesize(waki_xhair); + picsize_x *= 0.5; + picsize_y *= 0.5; + drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + } + return TRUE; + } + case VR_SETUP: + { + // Raygun-locked + AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-bracket.tga"; + AuxiliaryXhair[0].axh_scale = 0.5; + + // Gunner1 + AuxiliaryXhair[1].axh_image = "gfx/vehicles/axh-target.tga"; + AuxiliaryXhair[1].axh_scale = 0.75; + + // Gunner2 + AuxiliaryXhair[2].axh_image = "gfx/vehicles/axh-target.tga"; + AuxiliaryXhair[2].axh_scale = 0.75; + return TRUE; + } + case VR_PRECACHE: + { + precache_model("models/vehicles/bumblebee_body.dpm"); + precache_model("models/vehicles/bumblebee_plasma_left.dpm"); + precache_model("models/vehicles/bumblebee_plasma_right.dpm"); + precache_model("models/vehicles/bumblebee_ray.dpm"); + precache_model("models/vehicles/wakizashi_cockpit.dpm"); + precache_model("models/vehicles/spiderbot_cockpit.dpm"); + precache_model("models/vehicles/raptor_cockpit.dpm"); + return TRUE; + } + } + + return TRUE; +} + +#endif // CSQC +#endif // REGISTER_VEHICLE diff --git a/qcsrc/common/vehicles/unit/racer.qc b/qcsrc/common/vehicles/unit/racer.qc new file mode 100644 index 0000000000..66d2d80481 --- /dev/null +++ b/qcsrc/common/vehicles/unit/racer.qc @@ -0,0 +1,863 @@ +#ifdef REGISTER_VEHICLE +REGISTER_VEHICLE( +/* VEH_##id */ RACER, +/* function */ v_racer, +/* spawnflags */ VHF_DMGSHAKE | VHF_DMGROLL, +/* mins,maxs */ '-120 -120 -40' * 0.5, '120 120 40' * 0.5, +/* model */ "models/vehicles/wakizashi.dpm", +/* head_model */ "null", +/* hud_model */ "models/vehicles/wakizashi_cockpit.dpm", +/* tags */ "", "", "tag_viewport", +/* netname */ "racer", +/* fullname */ _("Racer") +); +#else + +#define RSM_FIRST 1 +#define RSM_BOMB 1 +#define RSM_FLARE 2 +#define RSM_LAST 2 + +#ifdef SVQC +float autocvar_g_vehicle_racer; + +float autocvar_g_vehicle_racer_speed_afterburn; +float autocvar_g_vehicle_racer_afterburn_cost; + +float autocvar_g_vehicle_racer_anglestabilizer; +float autocvar_g_vehicle_racer_downforce; + +float autocvar_g_vehicle_racer_speed_forward; +float autocvar_g_vehicle_racer_speed_strafe; +float autocvar_g_vehicle_racer_springlength; +float autocvar_g_vehicle_racer_upforcedamper; +float autocvar_g_vehicle_racer_friction; + +float autocvar_g_vehicle_racer_hovertype; +float autocvar_g_vehicle_racer_hoverpower; + +float autocvar_g_vehicle_racer_turnroll; +float autocvar_g_vehicle_racer_turnspeed; +float autocvar_g_vehicle_racer_pitchspeed; + +float autocvar_g_vehicle_racer_energy; +float autocvar_g_vehicle_racer_energy_regen; +float autocvar_g_vehicle_racer_energy_regen_pause; + +float autocvar_g_vehicle_racer_health; +float autocvar_g_vehicle_racer_health_regen; +float autocvar_g_vehicle_racer_health_regen_pause; + +float autocvar_g_vehicle_racer_shield; +float autocvar_g_vehicle_racer_shield_regen; +float autocvar_g_vehicle_racer_shield_regen_pause; + +float autocvar_g_vehicle_racer_cannon_cost; +float autocvar_g_vehicle_racer_cannon_damage; +float autocvar_g_vehicle_racer_cannon_radius; +float autocvar_g_vehicle_racer_cannon_refire; +float autocvar_g_vehicle_racer_cannon_speed; +float autocvar_g_vehicle_racer_cannon_spread; +float autocvar_g_vehicle_racer_cannon_force; + +float autocvar_g_vehicle_racer_rocket_accel; +float autocvar_g_vehicle_racer_rocket_damage; +float autocvar_g_vehicle_racer_rocket_radius; +float autocvar_g_vehicle_racer_rocket_force; +float autocvar_g_vehicle_racer_rocket_refire; +float autocvar_g_vehicle_racer_rocket_speed; +float autocvar_g_vehicle_racer_rocket_turnrate; + +float autocvar_g_vehicle_racer_rocket_locktarget; +float autocvar_g_vehicle_racer_rocket_locking_time; +float autocvar_g_vehicle_racer_rocket_locking_releasetime; +float autocvar_g_vehicle_racer_rocket_locked_time; +float autocvar_g_vehicle_racer_rocket_locked_maxangle; +float autocvar_g_vehicle_racer_rocket_climbspeed; + +float autocvar_g_vehicle_racer_respawntime; + +float autocvar_g_vehicle_racer_blowup_radius; +float autocvar_g_vehicle_racer_blowup_coredamage; +float autocvar_g_vehicle_racer_blowup_edgedamage; +float autocvar_g_vehicle_racer_blowup_forceintensity; + +float autocvar_g_vehicle_racer_bouncefactor; +float autocvar_g_vehicle_racer_bouncestop; +vector autocvar_g_vehicle_racer_bouncepain; + +var vector racer_force_from_tag(string tag_name, float spring_length, float max_power); + +void racer_align4point(float _delta) +{ + vector push_vector; + float fl_push, fr_push, bl_push, br_push; + + push_vector = racer_force_from_tag("tag_engine_fr", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower); + fr_push = force_fromtag_normpower; + //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier); + + push_vector += racer_force_from_tag("tag_engine_fl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower); + fl_push = force_fromtag_normpower; + //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier); + + push_vector += racer_force_from_tag("tag_engine_br", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower); + br_push = force_fromtag_normpower; + //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier); + + push_vector += racer_force_from_tag("tag_engine_bl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower); + bl_push = force_fromtag_normpower; + //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier); + + self.velocity += push_vector * _delta; + + // Anti ocilation + if(self.velocity_z > 0) + self.velocity_z *= 1 - autocvar_g_vehicle_racer_upforcedamper * _delta; + + push_vector_x = (fl_push - bl_push); + push_vector_x += (fr_push - br_push); + push_vector_x *= 360; + + push_vector_z = (fr_push - fl_push); + push_vector_z += (br_push - bl_push); + push_vector_z *= 360; + + // Apply angle diffrance + self.angles_z += push_vector_z * _delta; + self.angles_x += push_vector_x * _delta; + + // Apply stabilizer + self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta); + self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta); +} + +void racer_fire_cannon(string tagname) +{ + vector v; + entity bolt; + + v = gettaginfo(self, gettagindex(self, tagname)); + bolt = vehicles_projectile("wakizashi_gun_muzzleflash", "weapons/lasergun_fire.wav", + v, normalize(v_forward + randomvec() * autocvar_g_vehicle_racer_cannon_spread) * autocvar_g_vehicle_racer_cannon_speed, + autocvar_g_vehicle_racer_cannon_damage, autocvar_g_vehicle_racer_cannon_radius, autocvar_g_vehicle_racer_cannon_force, 0, + DEATH_VH_WAKI_GUN, PROJECTILE_WAKICANNON, 0, TRUE, TRUE, self.owner); + + // Fix z-aim (for chase mode) + v = normalize(trace_endpos - bolt.origin); + v_forward_z = v_z * 0.5; + bolt.velocity = v_forward * autocvar_g_vehicle_racer_cannon_speed; +} + +void racer_rocket_groundhugger() +{ + vector olddir, newdir; + float oldvel, newvel; + + self.nextthink = time; + + if(self.owner.deadflag != DEAD_NO || self.cnt < time) + { + self.use(); + return; + } + + if not (self.realowner.vehicle) + { + UpdateCSQCProjectile(self); + return; + } + + olddir = normalize(self.velocity); + oldvel = vlen(self.velocity); + newvel = oldvel + self.lip; + + tracebox(self.origin, self.mins, self.maxs, self.origin + olddir * 64, MOVE_WORLDONLY,self); + if(trace_fraction <= 0.5) + { + // Hitting somethign soon, just speed ahead + self.velocity = olddir * newvel; + UpdateCSQCProjectile(self); + return; + } + + traceline(trace_endpos, trace_endpos - '0 0 64', MOVE_NORMAL, self); + if(trace_fraction != 1.0) + { + newdir = normalize(trace_endpos + '0 0 64' - self.origin) * autocvar_g_vehicle_racer_rocket_turnrate; + self.velocity = normalize(olddir + newdir) * newvel; + } + else + { + self.velocity = olddir * newvel; + self.velocity_z -= 1600 * sys_frametime; // 2x grav looks better for this one + } + + UpdateCSQCProjectile(self); + return; +} + +void racer_rocket_tracker() +{ + vector olddir, newdir; + float oldvel, newvel; + + self.nextthink = time; + + if (self.owner.deadflag != DEAD_NO || self.cnt < time) + { + self.use(); + return; + } + + if not (self.realowner.vehicle) + { + UpdateCSQCProjectile(self); + return; + } + + olddir = normalize(self.velocity); + oldvel = vlen(self.velocity); + newvel = oldvel + self.lip; + makevectors(vectoangles(olddir)); + + float time_to_impact = min(vlen(self.enemy.origin - self.origin) / vlen(self.velocity), 1); + vector predicted_origin = self.enemy.origin + self.enemy.velocity * time_to_impact; + + traceline(self.origin, self.origin + v_forward * 64 - '0 0 32', MOVE_NORMAL, self); + newdir = normalize(predicted_origin - self.origin); + + //vector + float height_diff = predicted_origin_z - self.origin_z; + + if(vlen(newdir - v_forward) > autocvar_g_vehicle_racer_rocket_locked_maxangle) + { + //bprint("Target lost!\n"); + //dprint("OF:", ftos(vlen(newdir - v_forward)), "\n"); + self.think = racer_rocket_groundhugger; + return; + } + + if(trace_fraction != 1.0 && trace_ent != self.enemy) + newdir_z += 16 * sys_frametime; + + self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_racer_rocket_turnrate) * newvel; + self.velocity_z -= 800 * sys_frametime; + self.velocity_z += max(height_diff, autocvar_g_vehicle_racer_rocket_climbspeed) * sys_frametime ; + + UpdateCSQCProjectile(self); + return; +} + +void racer_fire_rocket(string tagname, entity trg) +{ + vector v = gettaginfo(self, gettagindex(self, tagname)); + entity rocket = rocket = vehicles_projectile("wakizashi_rocket_launch", "weapons/rocket_fire.wav", + v, v_forward * autocvar_g_vehicle_racer_rocket_speed, + autocvar_g_vehicle_racer_rocket_damage, autocvar_g_vehicle_racer_rocket_radius, autocvar_g_vehicle_racer_rocket_force, 3, + DEATH_VH_WAKI_ROCKET, PROJECTILE_WAKIROCKET, 20, FALSE, FALSE, self.owner); + + rocket.lip = autocvar_g_vehicle_racer_rocket_accel * sys_frametime; + rocket.wait = autocvar_g_vehicle_racer_rocket_turnrate; + rocket.nextthink = time; + rocket.enemy = trg; + rocket.cnt = time + 15; + + if(trg) + rocket.think = racer_rocket_tracker; + else + rocket.think = racer_rocket_groundhugger; +} + +float racer_frame() +{ + entity player, racer; + vector df; + float ftmp; + + if(intermission_running) + return 1; + + player = self; + racer = self.vehicle; + self = racer; + + player.BUTTON_ZOOM = player.BUTTON_CROUCH = 0; + + vehicles_painframe(); + + if(racer.deadflag != DEAD_NO) + { + self = player; + player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; + return 1; + } + + racer_align4point(frametime); + + crosshair_trace(player); + + racer.angles_x *= -1; + + // Yaw + ftmp = autocvar_g_vehicle_racer_turnspeed * frametime; + ftmp = bound(-ftmp, shortangle_f(player.v_angle_y - racer.angles_y, racer.angles_y), ftmp); + racer.angles_y = anglemods(racer.angles_y + ftmp); + + // Roll + racer.angles_z += -ftmp * autocvar_g_vehicle_racer_turnroll * frametime; + + // Pitch + ftmp = autocvar_g_vehicle_racer_pitchspeed * frametime; + ftmp = bound(-ftmp, shortangle_f(player.v_angle_x - racer.angles_x, racer.angles_x), ftmp); + racer.angles_x = bound(-30, anglemods(racer.angles_x + ftmp), 30); + + makevectors(racer.angles); + racer.angles_x *= -1; + + //ftmp = racer.velocity_z; + df = racer.velocity * -autocvar_g_vehicle_racer_friction; + //racer.velocity_z = ftmp; + + if(vlen(player.movement) != 0) + { + if(player.movement_x) + df += v_forward * ((player.movement_x > 0) ? autocvar_g_vehicle_racer_speed_forward : -autocvar_g_vehicle_racer_speed_forward); + + if(player.movement_y) + df += v_right * ((player.movement_y > 0) ? autocvar_g_vehicle_racer_speed_strafe : -autocvar_g_vehicle_racer_speed_strafe); + + if(self.sound_nexttime < time || self.sounds != 1) + { + self.sounds = 1; + self.sound_nexttime = time + 10.922667; //soundlength("vehicles/racer_move.wav"); + sound (self, CH_TRIGGER_SINGLE, "vehicles/racer_move.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + } + } + else + { + if(self.sound_nexttime < time || self.sounds != 0) + { + self.sounds = 0; + self.sound_nexttime = time + 11.888604; //soundlength("vehicles/racer_idle.wav"); + sound (self, CH_TRIGGER_SINGLE, "vehicles/racer_idle.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + } + } + + // Afterburn + if (player.BUTTON_JUMP && racer.vehicle_energy >= (autocvar_g_vehicle_racer_afterburn_cost * frametime)) + { + if(time - racer.wait > 0.2) + pointparticles(particleeffectnum("wakizashi_booster_smoke"), self.origin - v_forward * 32, v_forward * vlen(self.velocity), 1); + + racer.wait = time; + racer.vehicle_energy -= autocvar_g_vehicle_racer_afterburn_cost * frametime; + df += (v_forward * autocvar_g_vehicle_racer_speed_afterburn); + + if(racer.invincible_finished < time) + { + traceline(racer.origin, racer.origin - '0 0 256', MOVE_NORMAL, self); + if(trace_fraction != 1.0) + pointparticles(particleeffectnum("smoke_small"), trace_endpos, '0 0 0', 1); + + racer.invincible_finished = time + 0.1 + (random() * 0.1); + } + + if(racer.strength_finished < time) + { + racer.strength_finished = time + 10.922667; //soundlength("vehicles/racer_boost.wav"); + sound (racer.tur_head, CH_TRIGGER_SINGLE, "vehicles/racer_boost.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + } + } + else + { + racer.strength_finished = 0; + sound (racer.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + } + + df -= v_up * (vlen(racer.velocity) * autocvar_g_vehicle_racer_downforce); + player.movement = racer.velocity += df * frametime; + + if(player.BUTTON_ATCK) + if(time > racer.attack_finished_single) + if(racer.vehicle_energy >= autocvar_g_vehicle_racer_cannon_cost) + { + racer.vehicle_energy -= autocvar_g_vehicle_racer_cannon_cost; + racer.wait = time; + + crosshair_trace(player); + if(racer.cnt) + { + racer_fire_cannon("tag_fire1"); + racer.cnt = 0; + } + else + { + racer_fire_cannon("tag_fire2"); + racer.cnt = 1; + } + racer.attack_finished_single = time + autocvar_g_vehicle_racer_cannon_refire; + } + + if(autocvar_g_vehicle_racer_rocket_locktarget) + { + vehicles_locktarget((1 / autocvar_g_vehicle_racer_rocket_locking_time) * frametime, + (1 / autocvar_g_vehicle_racer_rocket_locking_releasetime) * frametime, + autocvar_g_vehicle_racer_rocket_locked_time); + + if(self.lock_target) + { + if(racer.lock_strength == 1) + UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '1 0 0', 0); + else if(self.lock_strength > 0.5) + UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '0 1 0', 0); + else if(self.lock_strength < 0.5) + UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '0 0 1', 0); + } + } + + if(time > racer.delay) + if(player.BUTTON_ATCK2) + { + racer.misc_bulletcounter += 1; + racer.delay = time + 0.3; + + if(racer.misc_bulletcounter == 1) + racer_fire_rocket("tag_rocket_r", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world); + else if(racer.misc_bulletcounter == 2) + { + racer_fire_rocket("tag_rocket_l", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world); + racer.lock_strength = 0; + racer.lock_target = world; + racer.misc_bulletcounter = 0; + + racer.delay = time + autocvar_g_vehicle_racer_rocket_refire; + racer.lip = time; + } + } + player.vehicle_reload1 = bound(0, 100 * ((time - racer.lip) / (racer.delay - racer.lip)), 100); + + if(racer.vehicle_flags & VHF_SHIELDREGEN) + vehicles_regen(racer.dmg_time, vehicle_shield, autocvar_g_vehicle_racer_shield, autocvar_g_vehicle_racer_shield_regen_pause, autocvar_g_vehicle_racer_shield_regen, frametime, TRUE); + + if(racer.vehicle_flags & VHF_HEALTHREGEN) + vehicles_regen(racer.dmg_time, vehicle_health, autocvar_g_vehicle_racer_health, autocvar_g_vehicle_racer_health_regen_pause, autocvar_g_vehicle_racer_health_regen, frametime, FALSE); + + if(racer.vehicle_flags & VHF_ENERGYREGEN) + vehicles_regen(racer.wait, vehicle_energy, autocvar_g_vehicle_racer_energy, autocvar_g_vehicle_racer_energy_regen_pause, autocvar_g_vehicle_racer_energy_regen, frametime, FALSE); + + + VEHICLE_UPDATE_PLAYER(player, health, racer); + VEHICLE_UPDATE_PLAYER(player, energy, racer); + + if(racer.vehicle_flags & VHF_HASSHIELD) + VEHICLE_UPDATE_PLAYER(player, shield, racer); + + player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; + setorigin(player,racer.origin + '0 0 32'); + player.velocity = racer.velocity; + + self = player; + return 1; +} + +void racer_think() +{ + self.nextthink = time; + + float pushdeltatime = time - self.lastpushtime; + if (pushdeltatime > 0.15) pushdeltatime = 0; + self.lastpushtime = time; + if(!pushdeltatime) return; + + tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * autocvar_g_vehicle_racer_springlength), MOVE_NORMAL, self); + + vector df = self.velocity * -autocvar_g_vehicle_racer_friction; + df_z += (1 - trace_fraction) * autocvar_g_vehicle_racer_hoverpower + sin(time * 2) * (autocvar_g_vehicle_racer_springlength * 2); + + self.velocity += df * pushdeltatime; + if(self.velocity_z > 0) + self.velocity_z *= 1 - autocvar_g_vehicle_racer_upforcedamper * pushdeltatime; + + self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime); + self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime); +} + +void racer_exit(float eject) +{ + vector spot; + + self.think = racer_think; + self.nextthink = time; + self.movetype = MOVETYPE_BOUNCE; + sound (self.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + + if not (self.owner) + return; + + makevectors(self.angles); + if(eject) + { + spot = self.origin + v_forward * 100 + '0 0 64'; + spot = vehicles_findgoodexit(spot); + setorigin(self.owner , spot); + self.owner.velocity = (v_up + v_forward * 0.25) * 750; + self.owner.oldvelocity = self.owner.velocity; + } + else + { + if(vlen(self.velocity) > 2 * autocvar_sv_maxairspeed) + { + self.owner.velocity = normalize(self.velocity) * autocvar_sv_maxairspeed * 2; + self.owner.velocity_z += 200; + spot = self.origin + v_forward * 32 + '0 0 32'; + spot = vehicles_findgoodexit(spot); + } + else + { + self.owner.velocity = self.velocity * 0.5; + self.owner.velocity_z += 10; + spot = self.origin - v_forward * 200 + '0 0 32'; + spot = vehicles_findgoodexit(spot); + } + self.owner.oldvelocity = self.owner.velocity; + setorigin(self.owner , spot); + } + antilag_clear(self.owner); + self.owner = world; +} + +void racer_blowup() +{ + self.deadflag = DEAD_DEAD; + self.vehicle_exit(VHEF_NORMAL); + + RadiusDamage (self, self.enemy, autocvar_g_vehicle_racer_blowup_coredamage, + autocvar_g_vehicle_racer_blowup_edgedamage, + autocvar_g_vehicle_racer_blowup_radius, world, + autocvar_g_vehicle_racer_blowup_forceintensity, + DEATH_VH_WAKI_DEATH, world); + + self.nextthink = time + autocvar_g_vehicle_racer_respawntime; + self.think = vehicles_spawn; + self.movetype = MOVETYPE_NONE; + self.effects = EF_NODRAW; + + self.colormod = '0 0 0'; + self.avelocity = '0 0 0'; + self.velocity = '0 0 0'; + + setorigin(self, self.pos1); +} + +void racer_deadtouch() +{ + self.avelocity_x *= 0.7; + self.cnt -= 1; + if(self.cnt <= 0) + racer_blowup(); +} + +void spawnfunc_vehicle_racer() +{ + if not(autocvar_g_vehicle_racer) { remove(self); return; } + if not(vehicle_initialize(VEH_RACER, TRUE)) { remove(self); return; } +} + +float v_racer(float req) +{ + switch(req) + { + case VR_IMPACT: + { + if(autocvar_g_vehicle_racer_bouncepain) + vehicles_impact(autocvar_g_vehicle_racer_bouncepain_x, autocvar_g_vehicle_racer_bouncepain_y, autocvar_g_vehicle_racer_bouncepain_z); + return TRUE; + } + case VR_ENTER: + { + self.movetype = MOVETYPE_BOUNCE; + self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_racer_health) * 100; + self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_racer_shield) * 100; + + if(self.owner.flagcarried) + setorigin(self.owner.flagcarried, '-190 0 96'); + + return TRUE; + } + case VR_THINK: + { + + return TRUE; + } + case VR_DEATH: + { + self.health = 0; + self.event_damage = func_null; + self.solid = SOLID_CORPSE; + self.takedamage = DAMAGE_NO; + self.deadflag = DEAD_DYING; + self.movetype = MOVETYPE_BOUNCE; + self.wait = time; + self.cnt = 1 + random() * 2; + self.touch = racer_deadtouch; + + pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1); + + if(random() < 0.5) + self.avelocity_z = 32; + else + self.avelocity_z = -32; + + self.avelocity_x = -vlen(self.velocity) * 0.2; + self.velocity += '0 0 700'; + self.colormod = '-0.5 -0.5 -0.5'; + + self.think = racer_blowup; + self.nextthink = 2 + time + random() * 3; + + return TRUE; + } + case VR_SPAWN: + { + if(self.scale != 0.5) + { + if(autocvar_g_vehicle_racer_hovertype != 0) + racer_force_from_tag = vehicles_force_fromtag_maglev; + else + racer_force_from_tag = vehicles_force_fromtag_hover; + + // FIXME: this be hakkz, fix the models insted (scale body, add tag_viewport to the hudmodel). + self.scale = 0.5; + setattachment(self.vehicle_hudmodel, self, ""); + setattachment(self.vehicle_viewport, self, "tag_viewport"); + + self.mass = 900; + } + + self.think = racer_think; + self.nextthink = time; + self.vehicle_health = autocvar_g_vehicle_racer_health; + self.vehicle_shield = autocvar_g_vehicle_racer_shield; + + self.movetype = MOVETYPE_TOSS; + self.solid = SOLID_SLIDEBOX; + self.delay = time; + self.scale = 0.5; + + self.PlayerPhysplug = racer_frame; + + self.bouncefactor = autocvar_g_vehicle_racer_bouncefactor; + self.bouncestop = autocvar_g_vehicle_racer_bouncestop; + self.damageforcescale = 0.5; + self.vehicle_health = autocvar_g_vehicle_racer_health; + self.vehicle_shield = autocvar_g_vehicle_racer_shield; + + return TRUE; + } + case VR_SETUP: + { + if(autocvar_g_vehicle_racer_energy) + if(autocvar_g_vehicle_racer_energy_regen) + self.vehicle_flags |= VHF_ENERGYREGEN; + + if(autocvar_g_vehicle_racer_shield) + self.vehicle_flags |= VHF_HASSHIELD; + + if(autocvar_g_vehicle_racer_shield_regen) + self.vehicle_flags |= VHF_SHIELDREGEN; + + if(autocvar_g_vehicle_racer_health_regen) + self.vehicle_flags |= VHF_HEALTHREGEN; + + self.vehicle_exit = racer_exit; + self.respawntime = autocvar_g_vehicle_racer_respawntime; + self.vehicle_health = autocvar_g_vehicle_racer_health; + self.vehicle_shield = autocvar_g_vehicle_racer_shield; + self.max_health = self.vehicle_health; + + return TRUE; + } + case VR_PRECACHE: + { + precache_sound ("weapons/lasergun_fire.wav"); + precache_sound ("weapons/rocket_fire.wav"); + + precache_sound ("vehicles/racer_idle.wav"); + precache_sound ("vehicles/racer_move.wav"); + precache_sound ("vehicles/racer_boost.wav"); + + precache_model ("models/vhshield.md3"); + precache_model ("models/vehicles/wakizashi.dpm"); + precache_model ("models/vehicles/wakizashi_cockpit.dpm"); + return TRUE; + } + } + + return TRUE; +} + +#endif // SVQC +#ifdef CSQC + +#define waki_ico "gfx/vehicles/waki.tga" +#define waki_eng "gfx/vehicles/waki_e.tga" +#define waki_gun "gfx/vehicles/waki_guns.tga" +#define waki_rkt "gfx/vehicles/waki_rockets.tga" +#define waki_xhair "gfx/vehicles/axh-special1.tga" + +float v_racer(float req) +{ + switch(req) + { + case VR_HUD: + { + if(autocvar_r_letterbox) + return TRUE; + + vector picsize, hudloc = '0 0 0', pic2size, picloc; + + // Fetch health & ammo stats + HUD_GETVEHICLESTATS + + picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale; + hudloc_y = vid_conheight - picsize_y; + hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5; + + drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL); + + shield *= 0.01; + vh_health *= 0.01; + energy *= 0.01; + reload1 *= 0.01; + + pic2size = draw_getimagesize(waki_ico) * (autocvar_cl_vehicles_hudscale * 0.8); + picloc = picsize * 0.5 - pic2size * 0.5; + if(vh_health < 0.25) + drawpic(hudloc + picloc, waki_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, waki_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, waki_eng, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, waki_gun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, waki_rkt, pic2size, '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL); + + // Health bar + picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale; + picloc = '69 69 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight); + drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale; + picloc = '37 65 0' * autocvar_cl_vehicles_hudscale; + if(vh_health < 0.25) + { + if(alarm1time < time) + { + alarm1time = time + 2; + vehicle_alarm(self, CH_PAIN_SINGLE, "vehicles/alarm.wav"); + } + + drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + } + else + { + drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + if(alarm1time) + { + vehicle_alarm(self, CH_PAIN_SINGLE, "misc/null.wav"); + alarm1time = 0; + } + } + + + // Shield bar + picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale; + picloc = '69 140 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight); + drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picloc = '40 136 0' * autocvar_cl_vehicles_hudscale; + picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale; + if(shield < 0.25) + { + if(alarm2time < time) + { + alarm2time = time + 1; + vehicle_alarm(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav"); + } + drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + } + else + { + drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + if(alarm2time) + { + vehicle_alarm(self, CH_TRIGGER_SINGLE, "misc/null.wav"); + alarm2time = 0; + } + } + + // Gun bar + picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale; + picloc = '450 69 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * energy, vid_conheight); + drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale; + picloc = '664 60 0' * autocvar_cl_vehicles_hudscale; + if(energy < 0.2) + drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + + // Bomb bar + picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale; + picloc = '450 140 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x, hudloc_y + picloc_y, picsize_x * reload1, vid_conheight); + drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale; + picloc = '664 130 0' * autocvar_cl_vehicles_hudscale; + if(reload1 != 1) + drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL); + + if (scoreboard_showscores) + HUD_DrawScoreboard(); + else + { + picsize = draw_getimagesize(waki_xhair); + picsize_x *= 0.5; + picsize_y *= 0.5; + + + drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), waki_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + } + return TRUE; + } + case VR_SETUP: + { + AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-bracket.tga"; + AuxiliaryXhair[0].axh_scale = 0.25; + return TRUE; + } + case VR_PRECACHE: + { + precache_model ("models/vhshield.md3"); + precache_model ("models/vehicles/wakizashi.dpm"); + precache_model ("models/vehicles/wakizashi_cockpit.dpm"); + return TRUE; + } + } + + return TRUE; +} + +#endif // CSQC +#endif // REGISTER_VEHICLE diff --git a/qcsrc/common/vehicles/unit/raptor.qc b/qcsrc/common/vehicles/unit/raptor.qc new file mode 100644 index 0000000000..c9eefa6e00 --- /dev/null +++ b/qcsrc/common/vehicles/unit/raptor.qc @@ -0,0 +1,1171 @@ +#ifdef REGISTER_VEHICLE +REGISTER_VEHICLE( +/* VEH_##id */ RAPTOR, +/* function */ v_raptor, +/* spawnflags */ VHF_DMGSHAKE | VHF_DMGROLL, +/* mins,maxs */ '-80 -80 0', '80 80 70', +/* model */ "models/vehicles/raptor.dpm", +/* head_model */ "", +/* hud_model */ "models/vehicles/raptor_cockpit.dpm", +/* tags */ "", "tag_hud", "tag_camera", +/* netname */ "raptor", +/* fullname */ _("Raptor") +); +#else + +const float RSM_FIRST = 0; +const float RSM_BOMB = 0; +const float RSM_FLARE = 1; +const float RSM_LAST = 1; + +#ifdef SVQC +float autocvar_g_vehicle_raptor; + +float autocvar_g_vehicle_raptor_respawntime; +float autocvar_g_vehicle_raptor_takeofftime; + +float autocvar_g_vehicle_raptor_movestyle; +float autocvar_g_vehicle_raptor_turnspeed; +float autocvar_g_vehicle_raptor_pitchspeed; +float autocvar_g_vehicle_raptor_pitchlimit; + +float autocvar_g_vehicle_raptor_speed_forward; +float autocvar_g_vehicle_raptor_speed_strafe; +float autocvar_g_vehicle_raptor_speed_up; +float autocvar_g_vehicle_raptor_speed_down; +float autocvar_g_vehicle_raptor_friction; + +float autocvar_g_vehicle_raptor_bomblets; +float autocvar_g_vehicle_raptor_bomblet_alt; +float autocvar_g_vehicle_raptor_bomblet_time; +float autocvar_g_vehicle_raptor_bomblet_damage; +float autocvar_g_vehicle_raptor_bomblet_spread; +float autocvar_g_vehicle_raptor_bomblet_edgedamage; +float autocvar_g_vehicle_raptor_bomblet_radius; +float autocvar_g_vehicle_raptor_bomblet_force; +float autocvar_g_vehicle_raptor_bomblet_explode_delay; +float autocvar_g_vehicle_raptor_bombs_refire; + +float autocvar_g_vehicle_raptor_flare_refire; +float autocvar_g_vehicle_raptor_flare_lifetime; +float autocvar_g_vehicle_raptor_flare_chase; +float autocvar_g_vehicle_raptor_flare_range; + +float autocvar_g_vehicle_raptor_cannon_turnspeed; +float autocvar_g_vehicle_raptor_cannon_turnlimit; +float autocvar_g_vehicle_raptor_cannon_pitchlimit_up; +float autocvar_g_vehicle_raptor_cannon_pitchlimit_down; + +float autocvar_g_vehicle_raptor_cannon_locktarget; +float autocvar_g_vehicle_raptor_cannon_locking_time; +float autocvar_g_vehicle_raptor_cannon_locking_releasetime; +float autocvar_g_vehicle_raptor_cannon_locked_time; +float autocvar_g_vehicle_raptor_cannon_predicttarget; + +float autocvar_g_vehicle_raptor_cannon_cost; +float autocvar_g_vehicle_raptor_cannon_damage; +float autocvar_g_vehicle_raptor_cannon_radius; +float autocvar_g_vehicle_raptor_cannon_refire; +float autocvar_g_vehicle_raptor_cannon_speed; +float autocvar_g_vehicle_raptor_cannon_spread; +float autocvar_g_vehicle_raptor_cannon_force; + +float autocvar_g_vehicle_raptor_energy; +float autocvar_g_vehicle_raptor_energy_regen; +float autocvar_g_vehicle_raptor_energy_regen_pause; + +float autocvar_g_vehicle_raptor_health; +float autocvar_g_vehicle_raptor_health_regen; +float autocvar_g_vehicle_raptor_health_regen_pause; + +float autocvar_g_vehicle_raptor_shield; +float autocvar_g_vehicle_raptor_shield_regen; +float autocvar_g_vehicle_raptor_shield_regen_pause; + +float autocvar_g_vehicle_raptor_bouncefactor; +float autocvar_g_vehicle_raptor_bouncestop; +vector autocvar_g_vehicle_raptor_bouncepain; + +.entity bomb1; +.entity bomb2; + +float raptor_altitude(float amax) +{ + tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * amax), MOVE_WORLDONLY, self); + return vlen(self.origin - trace_endpos); +} + +void raptor_bomblet_boom() +{ + RadiusDamage (self, self.realowner, autocvar_g_vehicle_raptor_bomblet_damage, + autocvar_g_vehicle_raptor_bomblet_edgedamage, + autocvar_g_vehicle_raptor_bomblet_radius, world, + autocvar_g_vehicle_raptor_bomblet_force, DEATH_VH_RAPT_BOMB, world); + remove(self); +} + +void raptor_bomblet_touch() +{ + if(other == self.owner) + return; + + PROJECTILE_TOUCH; + self.think = raptor_bomblet_boom; + self.nextthink = time + random() * autocvar_g_vehicle_raptor_bomblet_explode_delay; +} + +void raptor_bomb_burst() +{ + if(self.cnt > time) + if(autocvar_g_vehicle_raptor_bomblet_alt) + { + self.nextthink = time; + traceline(self.origin, self.origin + (normalize(self.velocity) * autocvar_g_vehicle_raptor_bomblet_alt), MOVE_NORMAL, self); + if((trace_fraction == 1.0) || (vlen(self.origin - self.owner.origin) < autocvar_g_vehicle_raptor_bomblet_radius)) + { + UpdateCSQCProjectile(self); + return; + } + } + + entity bomblet; + float i; + + Damage_DamageInfo(self.origin, 0, 0, 0, '0 0 0', DEATH_VH_RAPT_FRAGMENT, 0, self); + + for(i = 0; i < autocvar_g_vehicle_raptor_bomblets; ++i) + { + bomblet = spawn(); + setorigin(bomblet, self.origin); + + bomblet.movetype = MOVETYPE_TOSS; + bomblet.touch = raptor_bomblet_touch; + bomblet.think = raptor_bomblet_boom; + bomblet.nextthink = time + 5; + bomblet.owner = self.owner; + bomblet.realowner = self.realowner; + bomblet.velocity = normalize(normalize(self.velocity) + (randomvec() * autocvar_g_vehicle_raptor_bomblet_spread)) * vlen(self.velocity); + + PROJECTILE_MAKETRIGGER(bomblet); + CSQCProjectile(bomblet, TRUE, PROJECTILE_RAPTORBOMBLET, TRUE); + } + + remove(self); +} + +void raptor_bombdrop() +{ + entity bomb_1, bomb_2; + + bomb_1 = spawn(); + bomb_2 = spawn(); + + setorigin(bomb_1, gettaginfo(self, gettagindex(self, "bombmount_left"))); + setorigin(bomb_2, gettaginfo(self, gettagindex(self, "bombmount_right"))); + + bomb_1.movetype = bomb_2.movetype = MOVETYPE_BOUNCE; + bomb_1.velocity = bomb_2.velocity = self.velocity; + bomb_1.touch = bomb_2.touch = raptor_bomb_burst; + bomb_1.think = bomb_2.think = raptor_bomb_burst; + bomb_1.cnt = bomb_2.cnt = time + 10; + + if(autocvar_g_vehicle_raptor_bomblet_alt) + bomb_1.nextthink = bomb_2.nextthink = time; + else + bomb_1.nextthink = bomb_2.nextthink = time + autocvar_g_vehicle_raptor_bomblet_time; + + bomb_1.owner = bomb_2.owner = self; + bomb_1.realowner = bomb_2.realowner = self.owner; + bomb_1.solid = bomb_2.solid = SOLID_BBOX; + bomb_1.gravity = bomb_2.gravity = 1; + + PROJECTILE_MAKETRIGGER(bomb_1); + PROJECTILE_MAKETRIGGER(bomb_2); + + CSQCProjectile(bomb_1, TRUE, PROJECTILE_RAPTORBOMB, TRUE); + CSQCProjectile(bomb_2, TRUE, PROJECTILE_RAPTORBOMB, TRUE); +} + + +void raptor_fire_cannon(entity gun, string tagname) +{ + vehicles_projectile("raptor_cannon_muzzleflash", "weapons/lasergun_fire.wav", + gettaginfo(gun, gettagindex(gun, tagname)), normalize(v_forward + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed, + autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force, 0, + DEATH_VH_RAPT_CANNON, PROJECTILE_RAPTORCANNON, 0, TRUE, TRUE, self.owner); +} + +void raptor_land() +{ + float hgt; + + hgt = raptor_altitude(512); + self.velocity = (self.velocity * 0.9) + ('0 0 -1800' * (hgt / 256) * sys_frametime); + self.angles_x *= 0.95; + self.angles_z *= 0.95; + + if(hgt < 128) + if(hgt > 0) + self.frame = (hgt / 128) * 25; + + self.bomb1.gun1.avelocity_y = 90 + ((self.frame / 25) * 2000); + self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y; + + if(hgt < 16) + { + self.movetype = MOVETYPE_TOSS; + self.think = vehicles_think; + self.frame = 0; + } + + self.nextthink = time; +} + +void raptor_exit(float eject) +{ + vector spot; + self.tur_head.exteriormodeltoclient = world; + + if(self.deadflag == DEAD_NO) + { + self.think = raptor_land; + self.nextthink = time; + } + + if not (self.owner) + return; + + makevectors(self.angles); + if(eject) + { + spot = self.origin + v_forward * 100 + '0 0 64'; + spot = vehicles_findgoodexit(spot); + setorigin(self.owner , spot); + self.owner.velocity = (v_up + v_forward * 0.25) * 750; + self.owner.oldvelocity = self.owner.velocity; + } + else + { + if(vlen(self.velocity) > 2 * autocvar_sv_maxairspeed) + { + self.owner.velocity = normalize(self.velocity) * autocvar_sv_maxairspeed * 2; + self.owner.velocity_z += 200; + spot = self.origin + v_forward * 32 + '0 0 64'; + spot = vehicles_findgoodexit(spot); + } + else + { + self.owner.velocity = self.velocity * 0.5; + self.owner.velocity_z += 10; + spot = self.origin - v_forward * 200 + '0 0 64'; + spot = vehicles_findgoodexit(spot); + } + self.owner.oldvelocity = self.owner.velocity; + setorigin(self.owner , spot); + } + + antilag_clear(self.owner); + self.owner = world; +} + +void raptor_flare_touch() +{ + remove(self); +} + +void raptor_flare_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) +{ + self.health -= damage; + if(self.health <= 0) + remove(self); +} + +void raptor_flare_think() +{ + self.nextthink = time + 0.1; + entity _missile = findchainentity(enemy, self.owner); + while(_missile) + { + if(_missile.flags & FL_PROJECTILE) + if(vlen(self.origin - _missile.origin) < autocvar_g_vehicle_raptor_flare_range) + if(random() > autocvar_g_vehicle_raptor_flare_chase) + _missile.enemy = self; + _missile = _missile.chain; + } + + if(self.tur_impacttime < time) + remove(self); +} + +float raptor_frame() +{ + entity player, raptor; + float ftmp = 0; + vector df; + + if(intermission_running) + return 1; + + player = self; + raptor = self.vehicle; + self = raptor; + vehicles_painframe(); + /* + ftmp = vlen(self.velocity); + if(ftmp > autocvar_g_vehicle_raptor_speed_forward) + ftmp = 1; + else + ftmp = ftmp / autocvar_g_vehicle_raptor_speed_forward; + */ + + if(self.sound_nexttime < time) + { + self.sound_nexttime = time + 7.955812; + //sound (self.tur_head, CH_TRIGGER_SINGLE, "vehicles/raptor_fly.wav", 1 - ftmp, ATTEN_NORM ); + sound (self, CH_TRIGGER_SINGLE, "vehicles/raptor_speed.wav", 1, ATTEN_NORM); + self.wait = ftmp; + } + /* + else if(fabs(ftmp - self.wait) > 0.2) + { + sound (self.tur_head, CH_TRIGGER_SINGLE, "", 1 - ftmp, ATTEN_NORM ); + sound (self, CH_TRIGGER_SINGLE, "", ftmp, ATTEN_NORM); + self.wait = ftmp; + } + */ + + if(raptor.deadflag != DEAD_NO) + { + self = player; + player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; + return 1; + } + crosshair_trace(player); + + vector vang; + vang = raptor.angles; + df = vectoangles(normalize(trace_endpos - self.origin + '0 0 32')); + vang_x *= -1; + df_x *= -1; + if(df_x > 180) df_x -= 360; + if(df_x < -180) df_x += 360; + if(df_y > 180) df_y -= 360; + if(df_y < -180) df_y += 360; + + ftmp = shortangle_f(player.v_angle_y - vang_y, vang_y); + if(ftmp > 180) ftmp -= 360; if(ftmp < -180) ftmp += 360; + raptor.avelocity_y = bound(-autocvar_g_vehicle_raptor_turnspeed, ftmp + raptor.avelocity_y * 0.9, autocvar_g_vehicle_raptor_turnspeed); + + // Pitch + ftmp = 0; + if(player.movement_x > 0 && vang_x < autocvar_g_vehicle_raptor_pitchlimit) ftmp = 5; + else if(player.movement_x < 0 && vang_x > -autocvar_g_vehicle_raptor_pitchlimit) ftmp = -20; + + df_x = bound(-autocvar_g_vehicle_raptor_pitchlimit, df_x , autocvar_g_vehicle_raptor_pitchlimit); + ftmp = vang_x - bound(-autocvar_g_vehicle_raptor_pitchlimit, df_x + ftmp, autocvar_g_vehicle_raptor_pitchlimit); + raptor.avelocity_x = bound(-autocvar_g_vehicle_raptor_pitchspeed, ftmp + raptor.avelocity_x * 0.9, autocvar_g_vehicle_raptor_pitchspeed); + + raptor.angles_x = anglemods(raptor.angles_x); + raptor.angles_y = anglemods(raptor.angles_y); + raptor.angles_z = anglemods(raptor.angles_z); + + if(autocvar_g_vehicle_raptor_movestyle == 1) + makevectors('0 1 0' * raptor.angles_y); + else + makevectors(player.v_angle); + + df = raptor.velocity * -autocvar_g_vehicle_raptor_friction; + + if(player.movement_x != 0) + { + if(player.movement_x > 0) + df += v_forward * autocvar_g_vehicle_raptor_speed_forward; + else if(player.movement_x < 0) + df -= v_forward * autocvar_g_vehicle_raptor_speed_forward; + } + + if(player.movement_y != 0) + { + if(player.movement_y < 0) + df -= v_right * autocvar_g_vehicle_raptor_speed_strafe; + else if(player.movement_y > 0) + df += v_right * autocvar_g_vehicle_raptor_speed_strafe; + + raptor.angles_z = bound(-30,raptor.angles_z + (player.movement_y / autocvar_g_vehicle_raptor_speed_strafe),30); + } + else + { + raptor.angles_z *= 0.95; + if(raptor.angles_z >= -1 && raptor.angles_z <= -1) + raptor.angles_z = 0; + } + + if(player.BUTTON_CROUCH) + df -= v_up * autocvar_g_vehicle_raptor_speed_down; + else if (player.BUTTON_JUMP) + df += v_up * autocvar_g_vehicle_raptor_speed_up; + + raptor.velocity += df * frametime; + player.velocity = player.movement = raptor.velocity; + setorigin(player, raptor.origin + '0 0 32'); + + vector vf, ad; + // Target lock & predict + if(autocvar_g_vehicle_raptor_cannon_locktarget == 2) + { + if(raptor.gun1.lock_time < time || raptor.gun1.enemy.deadflag) + raptor.gun1.enemy = world; + + if(trace_ent) + if(trace_ent.movetype) + if(trace_ent.takedamage) + if(!trace_ent.deadflag) + { + if(teamplay) + { + if(trace_ent.team != player.team) + { + raptor.gun1.enemy = trace_ent; + raptor.gun1.lock_time = time + 5; + } + } + else + { + raptor.gun1.enemy = trace_ent; + raptor.gun1.lock_time = time + 0.5; + } + } + + if(raptor.gun1.enemy) + { + float i, distance, impact_time; + + vf = real_origin(raptor.gun1.enemy); + UpdateAuxiliaryXhair(player, vf, '1 0 0', 1); + vector _vel = raptor.gun1.enemy.velocity; + if(raptor.gun1.enemy.movetype == MOVETYPE_WALK) + _vel_z *= 0.1; + + if(autocvar_g_vehicle_raptor_cannon_predicttarget) + { + ad = vf; + for(i = 0; i < 4; ++i) + { + distance = vlen(ad - player.origin); + impact_time = distance / autocvar_g_vehicle_raptor_cannon_speed; + ad = vf + _vel * impact_time; + } + trace_endpos = ad; + } + else + trace_endpos = vf; + } + } + else if(autocvar_g_vehicle_raptor_cannon_locktarget == 1) + { + + vehicles_locktarget((1 / autocvar_g_vehicle_raptor_cannon_locking_time) * frametime, + (1 / autocvar_g_vehicle_raptor_cannon_locking_releasetime) * frametime, + autocvar_g_vehicle_raptor_cannon_locked_time); + + if(self.lock_target != world) + if(autocvar_g_vehicle_raptor_cannon_predicttarget) + if(self.lock_strength == 1) + { + float i, distance, impact_time; + + vf = real_origin(raptor.lock_target); + ad = vf; + for(i = 0; i < 4; ++i) + { + distance = vlen(ad - raptor.origin); + impact_time = distance / autocvar_g_vehicle_raptor_cannon_speed; + ad = vf + raptor.lock_target.velocity * impact_time; + } + trace_endpos = ad; + } + + if(self.lock_target) + { + if(raptor.lock_strength == 1) + UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '1 0 0', 1); + else if(self.lock_strength > 0.5) + UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '0 1 0', 1); + else if(self.lock_strength < 0.5) + UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '0 0 1', 1); + } + } + + + vehicle_aimturret(raptor, trace_endpos, raptor.gun1, "fire1", + autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1, autocvar_g_vehicle_raptor_cannon_pitchlimit_up, + autocvar_g_vehicle_raptor_cannon_turnlimit * -1, autocvar_g_vehicle_raptor_cannon_turnlimit, autocvar_g_vehicle_raptor_cannon_turnspeed); + + vehicle_aimturret(raptor, trace_endpos, raptor.gun2, "fire1", + autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1, autocvar_g_vehicle_raptor_cannon_pitchlimit_up, + autocvar_g_vehicle_raptor_cannon_turnlimit * -1, autocvar_g_vehicle_raptor_cannon_turnlimit, autocvar_g_vehicle_raptor_cannon_turnspeed); + + /* + ad = ad * 0.5; + v_forward = vf * 0.5; + traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, raptor); + UpdateAuxiliaryXhair(player, trace_endpos, '0 1 0', 0); + */ + + if(player.BUTTON_ATCK) + if(raptor.attack_finished_single <= time) + if(raptor.vehicle_energy > autocvar_g_vehicle_raptor_cannon_cost) + { + raptor.misc_bulletcounter += 1; + raptor.attack_finished_single = time + autocvar_g_vehicle_raptor_cannon_refire; + if(raptor.misc_bulletcounter <= 2) + raptor_fire_cannon(self.gun1, "fire1"); + else if(raptor.misc_bulletcounter == 3) + raptor_fire_cannon(self.gun2, "fire1"); + else + { + raptor.attack_finished_single = time + autocvar_g_vehicle_raptor_cannon_refire * 2; + raptor_fire_cannon(self.gun2, "fire1"); + raptor.misc_bulletcounter = 0; + } + raptor.vehicle_energy -= autocvar_g_vehicle_raptor_cannon_cost; + self.cnt = time; + } + + if(self.vehicle_flags & VHF_SHIELDREGEN) + vehicles_regen(raptor.dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime, TRUE); + + if(self.vehicle_flags & VHF_HEALTHREGEN) + vehicles_regen(raptor.dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime, FALSE); + + if(self.vehicle_flags & VHF_ENERGYREGEN) + vehicles_regen(raptor.cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime, FALSE); + + if(raptor.vehicle_weapon2mode == RSM_BOMB) + { + if(time > raptor.lip + autocvar_g_vehicle_raptor_bombs_refire) + if(player.BUTTON_ATCK2) + { + raptor_bombdrop(); + raptor.delay = time + autocvar_g_vehicle_raptor_bombs_refire; + raptor.lip = time; + } + } + else + { + if(time > raptor.lip + autocvar_g_vehicle_raptor_flare_refire) + if(player.BUTTON_ATCK2) + { + float i; + entity _flare; + + for(i = 0; i < 3; ++i) + { + _flare = spawn(); + setmodel(_flare, "models/runematch/rune.mdl"); + _flare.effects = EF_LOWPRECISION | EF_FLAME; + _flare.scale = 0.5; + setorigin(_flare, self.origin - '0 0 16'); + _flare.movetype = MOVETYPE_TOSS; + _flare.gravity = 0.15; + _flare.velocity = 0.25 * raptor.velocity + (v_forward + randomvec() * 0.25)* -500; + _flare.think = raptor_flare_think; + _flare.nextthink = time; + _flare.owner = raptor; + _flare.solid = SOLID_CORPSE; + _flare.takedamage = DAMAGE_YES; + _flare.event_damage = raptor_flare_damage; + _flare.health = 20; + _flare.tur_impacttime = time + autocvar_g_vehicle_raptor_flare_lifetime; + _flare.touch = raptor_flare_touch; + } + raptor.delay = time + autocvar_g_vehicle_raptor_flare_refire; + raptor.lip = time; + } + } + + raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip); + player.vehicle_reload2 = bound(0, raptor.bomb1.alpha * 100, 100); + + if(self.bomb1.cnt < time) + { + entity _missile = findchainentity(enemy, raptor); + float _incomming = 0; + while(_missile) + { + if(_missile.flags & FL_PROJECTILE) + if(MISSILE_IS_TRACKING(_missile)) + if(vlen(self.origin - _missile.origin) < 2 * autocvar_g_vehicle_raptor_flare_range) + ++_incomming; + + _missile = _missile.chain; + } + + if(_incomming) + sound(self, CH_PAIN_SINGLE, "vehicles/missile_alarm.wav", VOL_BASE, ATTEN_NONE); + + self.bomb1.cnt = time + 1; + } + + + VEHICLE_UPDATE_PLAYER(player, health, raptor); + VEHICLE_UPDATE_PLAYER(player, energy, raptor); + if(self.vehicle_flags & VHF_HASSHIELD) + VEHICLE_UPDATE_PLAYER(player, shield, raptor); + + player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0; + + self = player; + return 1; +} + +float raptor_takeoff() +{ + entity player, raptor; + + player = self; + raptor = self.vehicle; + self = raptor; + if(self.sound_nexttime < time) + { + self.sound_nexttime = time + 7.955812; //soundlength("vehicles/raptor_fly.wav"); + sound (self, CH_TRIGGER_SINGLE, "vehicles/raptor_speed.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + } + + // Takeoff sequense + if(raptor.frame < 25) + { + raptor.frame += 25 / (autocvar_g_vehicle_raptor_takeofftime / sys_frametime); + raptor.velocity_z = min(raptor.velocity_z * 1.5, 256); + self.bomb1.gun1.avelocity_y = 90 + ((raptor.frame / 25) * 25000); + self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y; + player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0; + + setorigin(player, raptor.origin + '0 0 32'); + } + else + player.PlayerPhysplug = raptor_frame; + + if(self.vehicle_flags & VHF_SHIELDREGEN) + vehicles_regen(raptor.dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime, TRUE); + + if(self.vehicle_flags & VHF_HEALTHREGEN) + vehicles_regen(raptor.dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime, FALSE); + + if(self.vehicle_flags & VHF_ENERGYREGEN) + vehicles_regen(raptor.cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime, FALSE); + + + raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip); + player.vehicle_reload2 = bound(0, raptor.bomb1.alpha * 100, 100); + + VEHICLE_UPDATE_PLAYER(player, health, raptor); + VEHICLE_UPDATE_PLAYER(player, energy, raptor); + if(self.vehicle_flags & VHF_HASSHIELD) + VEHICLE_UPDATE_PLAYER(player, shield, raptor); + + player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0; + self = player; + return 1; +} + +void raptor_blowup() +{ + self.deadflag = DEAD_DEAD; + self.vehicle_exit(VHEF_NORMAL); + RadiusDamage (self, self.enemy, 250, 15, 250, world, 250, DEATH_VH_RAPT_DEATH, world); + + self.alpha = -1; + self.movetype = MOVETYPE_NONE; + self.effects = EF_NODRAW; + self.colormod = '0 0 0'; + self.avelocity = '0 0 0'; + self.velocity = '0 0 0'; + + setorigin(self, self.pos1); + self.touch = func_null; + self.nextthink = 0; +} + +void raptor_diethink() +{ + if(time >= self.wait) + self.think = raptor_blowup; + + if(random() < 0.1) + { + sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); + } + self.nextthink = time + 0.1; +} + +// If we dont do this ever now and then, the raptors rotors +// stop working, presumably due to angle overflow. cute. +void raptor_rotor_anglefix() +{ + self.gun1.angles_y = anglemods(self.gun1.angles_y); + self.gun2.angles_y = anglemods(self.gun2.angles_y); + self.nextthink = time + 15; +} + +float raptor_impulse(float _imp) +{ + switch(_imp) + { + case 10: + case 15: + case 18: + self.vehicle.vehicle_weapon2mode += 1; + if(self.vehicle.vehicle_weapon2mode > RSM_LAST) + self.vehicle.vehicle_weapon2mode = RSM_FIRST; + + CSQCVehicleSetup(self, 0); + return TRUE; + case 12: + case 16: + case 19: + self.vehicle.vehicle_weapon2mode -= 1; + if(self.vehicle.vehicle_weapon2mode < RSM_FIRST) + self.vehicle.vehicle_weapon2mode = RSM_LAST; + + CSQCVehicleSetup(self, 0); + return TRUE; + + /* + case 17: // toss gun, could be used to exit? + break; + case 20: // Manual minigun reload? + break; + */ + } + return FALSE; +} + +void spawnfunc_vehicle_raptor() +{ + if not(autocvar_g_vehicle_raptor) { remove(self); return; } + if not(vehicle_initialize(VEH_RAPTOR, FALSE)) { remove(self); return; } +} + +float v_raptor(float req) +{ + switch(req) + { + case VR_IMPACT: + { + if(autocvar_g_vehicle_raptor_bouncepain) + vehicles_impact(autocvar_g_vehicle_raptor_bouncepain_x, autocvar_g_vehicle_raptor_bouncepain_y, autocvar_g_vehicle_raptor_bouncepain_z); + + return TRUE; + } + case VR_ENTER: + { + self.vehicle_weapon2mode = RSM_BOMB; + self.owner.PlayerPhysplug = raptor_takeoff; + self.movetype = MOVETYPE_BOUNCEMISSILE; + self.solid = SOLID_SLIDEBOX; + self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_raptor_health) * 100; + self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_raptor_shield) * 100; + self.velocity_z = 1; // Nudge upwards to takeoff sequense can work. + self.tur_head.exteriormodeltoclient = self.owner; + + self.delay = time + autocvar_g_vehicle_raptor_bombs_refire; + self.lip = time; + + if(self.owner.flagcarried) + setorigin(self.owner.flagcarried, '-20 0 96'); + + CSQCVehicleSetup(self.owner, 0); + return TRUE; + } + case VR_THINK: + { + return TRUE; + } + case VR_DEATH: + { + self.health = 0; + self.event_damage = func_null; + self.solid = SOLID_CORPSE; + self.takedamage = DAMAGE_NO; + self.deadflag = DEAD_DYING; + self.movetype = MOVETYPE_BOUNCE; + self.think = raptor_diethink; + self.nextthink = time; + self.wait = time + 5 + (random() * 5); + + pointparticles(particleeffectnum("explosion_medium"), findbetterlocation (self.origin, 16), '0 0 0', 1); + + self.velocity_z += 600; + + self.avelocity = '0 0.5 1' * (random() * 400); + self.avelocity -= '0 0.5 1' * (random() * 400); + + self.colormod = '-0.5 -0.5 -0.5'; + self.touch = raptor_blowup; + return TRUE; + } + case VR_SPAWN: + { + if not(self.gun1) + { + entity spinner; + vector ofs; + + //FIXME: Camera is in a bad place in HUD model. + //setorigin(self.vehicle_viewport, '25 0 5'); + + self.vehicles_impulse = raptor_impulse; + + self.frame = 0; + + self.bomb1 = spawn(); + self.bomb2 = spawn(); + self.gun1 = spawn(); + self.gun2 = spawn(); + + setmodel(self.bomb1,"models/vehicles/clusterbomb_folded.md3"); + setmodel(self.bomb2,"models/vehicles/clusterbomb_folded.md3"); + setmodel(self.gun1, "models/vehicles/raptor_gun.dpm"); + setmodel(self.gun2, "models/vehicles/raptor_gun.dpm"); + setmodel(self.tur_head, "models/vehicles/raptor_body.dpm"); + + setattachment(self.bomb1, self, "bombmount_left"); + setattachment(self.bomb2, self, "bombmount_right"); + setattachment(self.tur_head, self,"root"); + + // FIXMODEL Guns mounts to angled bones + self.bomb1.angles = self.angles; + self.angles = '0 0 0'; + // This messes up gun-aim, so work arround it. + //setattachment(self.gun1, self, "gunmount_left"); + ofs = gettaginfo(self, gettagindex(self, "gunmount_left")); + ofs -= self.origin; + setattachment(self.gun1, self, ""); + setorigin(self.gun1, ofs); + + //setattachment(self.gun2, self, "gunmount_right"); + ofs = gettaginfo(self, gettagindex(self, "gunmount_right")); + ofs -= self.origin; + setattachment(self.gun2, self, ""); + setorigin(self.gun2, ofs); + + self.angles = self.bomb1.angles; + self.bomb1.angles = '0 0 0'; + + spinner = spawn(); + spinner.owner = self; + setmodel(spinner,"models/vehicles/spinner.dpm"); + setattachment(spinner, self, "engine_left"); + spinner.movetype = MOVETYPE_NOCLIP; + spinner.avelocity = '0 90 0'; + self.bomb1.gun1 = spinner; + + spinner = spawn(); + spinner.owner = self; + setmodel(spinner,"models/vehicles/spinner.dpm"); + setattachment(spinner, self, "engine_right"); + spinner.movetype = MOVETYPE_NOCLIP; + spinner.avelocity = '0 -90 0'; + self.bomb1.gun2 = spinner; + + // Sigh. + self.bomb1.think = raptor_rotor_anglefix; + self.bomb1.nextthink = time; + + self.mass = 1 ; + } + + self.frame = 0; + self.vehicle_health = autocvar_g_vehicle_raptor_health; + self.vehicle_shield = autocvar_g_vehicle_raptor_shield; + self.movetype = MOVETYPE_TOSS; + self.solid = SOLID_SLIDEBOX; + self.vehicle_energy = 1; + + self.PlayerPhysplug = raptor_frame; + + self.bomb1.gun1.avelocity_y = 90; + self.bomb1.gun2.avelocity_y = -90; + + self.delay = time; + + self.bouncefactor = autocvar_g_vehicle_raptor_bouncefactor; + self.bouncestop = autocvar_g_vehicle_raptor_bouncestop; + self.damageforcescale = 0.25; + self.vehicle_health = autocvar_g_vehicle_raptor_health; + self.vehicle_shield = autocvar_g_vehicle_raptor_shield; + return TRUE; + } + case VR_SETUP: + { + if(autocvar_g_vehicle_raptor_shield) + self.vehicle_flags |= VHF_HASSHIELD; + + if(autocvar_g_vehicle_raptor_shield_regen) + self.vehicle_flags |= VHF_SHIELDREGEN; + + if(autocvar_g_vehicle_raptor_health_regen) + self.vehicle_flags |= VHF_HEALTHREGEN; + + if(autocvar_g_vehicle_raptor_energy_regen) + self.vehicle_flags |= VHF_ENERGYREGEN; + + self.vehicle_exit = raptor_exit; + self.respawntime = autocvar_g_vehicle_raptor_respawntime; + self.vehicle_health = autocvar_g_vehicle_raptor_health; + self.vehicle_shield = autocvar_g_vehicle_raptor_shield; + self.max_health = self.vehicle_health; + + return TRUE; + } + case VR_PRECACHE: + { + precache_model ("models/vehicles/raptor.dpm"); + precache_model ("models/vehicles/raptor_gun.dpm"); + precache_model ("models/vehicles/spinner.dpm"); + precache_model ("models/vehicles/raptor_cockpit.dpm"); + precache_model ("models/vehicles/clusterbomb_folded.md3"); + precache_model ("models/vehicles/raptor_body.dpm"); + + precache_sound ("vehicles/raptor_fly.wav"); + precache_sound ("vehicles/raptor_speed.wav"); + precache_sound ("vehicles/missile_alarm.wav"); + + return TRUE; + } + } + + return TRUE; +} + +#endif // SVQC +#ifdef CSQC + +#define raptor_ico "gfx/vehicles/raptor.tga" +#define raptor_gun "gfx/vehicles/raptor_guns.tga" +#define raptor_bomb "gfx/vehicles/raptor_bombs.tga" +#define raptor_drop "gfx/vehicles/axh-dropcross.tga" +string raptor_xhair; + +float v_raptor(float req) +{ + switch(req) + { + case VR_HUD: + { + if(autocvar_r_letterbox) + return TRUE; + + vector picsize, hudloc = '0 0 0', pic2size, picloc; + + // Fetch health & ammo stats + HUD_GETVEHICLESTATS + + picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale; + hudloc_y = vid_conheight - picsize_y; + hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5; + + drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL); + + ammo1 *= 0.01; + ammo2 *= 0.01; + shield *= 0.01; + vh_health *= 0.01; + energy *= 0.01; + reload1 = reload2 * 0.01; + //reload2 *= 0.01; + + pic2size = draw_getimagesize(raptor_ico) * (autocvar_cl_vehicles_hudscale * 0.8); + picloc = picsize * 0.5 - pic2size * 0.5; + if(vh_health < 0.25) + drawpic(hudloc + picloc, raptor_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, raptor_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, raptor_bomb, pic2size, '1 1 1' * reload1 + '1 0 0' * (1 - reload1), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, raptor_gun, pic2size, '1 1 1' * energy + '1 0 0' * (1 - energy), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL); + + // Health bar + picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale; + picloc = '69 69 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight); + drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale; + picloc = '37 65 0' * autocvar_cl_vehicles_hudscale; + if(vh_health < 0.25) + { + if(alarm1time < time) + { + alarm1time = time + 2; + vehicle_alarm(self, CH_PAIN_SINGLE, "vehicles/alarm.wav"); + } + + drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + } + else + { + drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + if(alarm1time) + { + vehicle_alarm(self, CH_PAIN_SINGLE, "misc/null.wav"); + alarm1time = 0; + } + } + + // Shield bar + picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale; + picloc = '69 140 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight); + drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picloc = '40 136 0' * autocvar_cl_vehicles_hudscale; + picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale; + if(shield < 0.25) + { + if(alarm2time < time) + { + alarm2time = time + 1; + vehicle_alarm(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav"); + } + drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + } + else + { + drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + if(alarm2time) + { + vehicle_alarm(self, CH_TRIGGER_SINGLE, "misc/null.wav"); + alarm2time = 0; + } + } + + // Gun bar + picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale; + picloc = '450 69 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * energy, vid_conheight); + drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale; + picloc = '664 60 0' * autocvar_cl_vehicles_hudscale; + if(energy < 0.2) + drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + + // Bomb bar + picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale; + picloc = '450 140 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x, hudloc_y + picloc_y, picsize_x * reload1, vid_conheight); + drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale; + picloc = '664 130 0' * autocvar_cl_vehicles_hudscale; + if(reload1 != 1) + drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL); + + if(weapon2mode == RSM_FLARE) + { + raptor_xhair = "gfx/vehicles/axh-bracket.tga"; + } + else + { + raptor_xhair = "gfx/vehicles/axh-ring.tga"; + + // Bombing crosshair + if(!dropmark) + { + dropmark = spawn(); + dropmark.owner = self; + dropmark.gravity = 1; + } + + if(reload2 == 100) + { + vector where; + + setorigin(dropmark, pmove_org); + dropmark.velocity = pmove_vel; + tracetoss(dropmark, self); + + where = project_3d_to_2d(trace_endpos); + + setorigin(dropmark, trace_endpos); + picsize = draw_getimagesize(raptor_drop) * 0.2; + + if not (where_z < 0 || where_x < 0 || where_y < 0 || where_x > vid_conwidth || where_y > vid_conheight) + { + where_x -= picsize_x * 0.5; + where_y -= picsize_y * 0.5; + where_z = 0; + drawpic(where, raptor_drop, picsize, '0 2 0', 1, DRAWFLAG_ADDITIVE); + } + dropmark.cnt = time + 5; + } + else + { + vector where; + if(dropmark.cnt > time) + { + where = project_3d_to_2d(dropmark.origin); + picsize = draw_getimagesize(raptor_drop) * 0.25; + + if not (where_z < 0 || where_x < 0 || where_y < 0 || where_x > vid_conwidth || where_y > vid_conheight) + { + where_x -= picsize_x * 0.5; + where_y -= picsize_y * 0.5; + where_z = 0; + drawpic(where, raptor_drop, picsize, '2 0 0', 1, DRAWFLAG_ADDITIVE); + } + } + } + } + + if (scoreboard_showscores) + HUD_DrawScoreboard(); + else + { + picsize = draw_getimagesize(raptor_xhair); + picsize_x *= 0.5; + picsize_y *= 0.5; + + drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), raptor_xhair, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + } + + return TRUE; + } + case VR_SETUP: + { + AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-special2.tga"; + AuxiliaryXhair[0].axh_scale = 0.5; + + AuxiliaryXhair[1].axh_image = "gfx/vehicles/axh-bracket.tga"; + AuxiliaryXhair[1].axh_scale = 0.25; + return TRUE; + } + case VR_PRECACHE: + { + precache_model ("models/vehicles/raptor.dpm"); + precache_model ("models/vehicles/raptor_gun.dpm"); + precache_model ("models/vehicles/spinner.dpm"); + precache_model ("models/vehicles/raptor_cockpit.dpm"); + precache_model ("models/vehicles/clusterbomb_folded.md3"); + precache_model ("models/vehicles/raptor_body.dpm"); + + return TRUE; + } + } + + return TRUE; +} + +#endif // CSQC +#endif // REGISTER_VEHICLE diff --git a/qcsrc/common/vehicles/unit/spiderbot.qc b/qcsrc/common/vehicles/unit/spiderbot.qc new file mode 100644 index 0000000000..f4c3068c63 --- /dev/null +++ b/qcsrc/common/vehicles/unit/spiderbot.qc @@ -0,0 +1,1079 @@ +#ifdef REGISTER_VEHICLE +REGISTER_VEHICLE( +/* VEH_##id */ SPIDERBOT, +/* function */ v_spiderbot, +/* spawnflags */ VHF_DMGSHAKE, +/* mins,maxs */ '-75 -75 10', '75 75 125', +/* model */ "models/vehicles/spiderbot.dpm", +/* head_model */ "models/vehicles/spiderbot_top.dpm", +/* hud_model */ "models/vehicles/spiderbot_cockpit.dpm", +/* tags */ "tag_head", "tag_hud", "", +/* netname */ "spiderbot", +/* fullname */ _("Spiderbot") +); +#else + +#define SBRM_FIRST 1 +#define SBRM_VOLLY 1 +#define SBRM_GUIDE 2 +#define SBRM_ARTILLERY 3 +#define SBRM_LAST 3 + +#ifdef SVQC +float autocvar_g_vehicle_spiderbot; + +float autocvar_g_vehicle_spiderbot_respawntime; + +float autocvar_g_vehicle_spiderbot_speed_stop; +float autocvar_g_vehicle_spiderbot_speed_strafe; +float autocvar_g_vehicle_spiderbot_speed_walk; +float autocvar_g_vehicle_spiderbot_turnspeed; +float autocvar_g_vehicle_spiderbot_turnspeed_strafe; +float autocvar_g_vehicle_spiderbot_movement_inertia; + +float autocvar_g_vehicle_spiderbot_springlength; +float autocvar_g_vehicle_spiderbot_springup; +float autocvar_g_vehicle_spiderbot_springblend; +float autocvar_g_vehicle_spiderbot_tiltlimit; + +float autocvar_g_vehicle_spiderbot_head_pitchlimit_down; +float autocvar_g_vehicle_spiderbot_head_pitchlimit_up; +float autocvar_g_vehicle_spiderbot_head_turnlimit; +float autocvar_g_vehicle_spiderbot_head_turnspeed; + +float autocvar_g_vehicle_spiderbot_health; +float autocvar_g_vehicle_spiderbot_health_regen; +float autocvar_g_vehicle_spiderbot_health_regen_pause; + +float autocvar_g_vehicle_spiderbot_shield; +float autocvar_g_vehicle_spiderbot_shield_regen; +float autocvar_g_vehicle_spiderbot_shield_regen_pause; + +float autocvar_g_vehicle_spiderbot_minigun_damage; +float autocvar_g_vehicle_spiderbot_minigun_refire; +float autocvar_g_vehicle_spiderbot_minigun_spread; +float autocvar_g_vehicle_spiderbot_minigun_ammo_cost; +float autocvar_g_vehicle_spiderbot_minigun_ammo_max; +float autocvar_g_vehicle_spiderbot_minigun_ammo_regen; +float autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause; +float autocvar_g_vehicle_spiderbot_minigun_force; +float autocvar_g_vehicle_spiderbot_minigun_speed; +float autocvar_g_vehicle_spiderbot_minigun_bulletconstant; + +float autocvar_g_vehicle_spiderbot_rocket_damage; +float autocvar_g_vehicle_spiderbot_rocket_force; +float autocvar_g_vehicle_spiderbot_rocket_radius; +float autocvar_g_vehicle_spiderbot_rocket_speed; +float autocvar_g_vehicle_spiderbot_rocket_spread; +float autocvar_g_vehicle_spiderbot_rocket_refire; +float autocvar_g_vehicle_spiderbot_rocket_refire2; +float autocvar_g_vehicle_spiderbot_rocket_reload; +float autocvar_g_vehicle_spiderbot_rocket_health; +float autocvar_g_vehicle_spiderbot_rocket_noise; +float autocvar_g_vehicle_spiderbot_rocket_turnrate; +float autocvar_g_vehicle_spiderbot_rocket_lifetime; + +vector autocvar_g_vehicle_spiderbot_bouncepain; + +void spiderbot_rocket_artillery() +{ + self.nextthink = time; + UpdateCSQCProjectile(self); +} + +void spiderbot_rocket_unguided() +{ + vector newdir, olddir; + + self.nextthink = time; + + olddir = normalize(self.velocity); + newdir = normalize(self.pos1 - self.origin) + randomvec() * autocvar_g_vehicle_spiderbot_rocket_noise; + self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_spiderbot_rocket_turnrate) * autocvar_g_vehicle_spiderbot_rocket_speed; + + UpdateCSQCProjectile(self); + + if (self.owner.deadflag != DEAD_NO || self.cnt < time || vlen(self.pos1 - self.origin) < 16) + self.use(); +} + +void spiderbot_rocket_guided() +{ + vector newdir, olddir; + + self.nextthink = time; + + if not (self.realowner.vehicle) + self.think = spiderbot_rocket_unguided; + + crosshair_trace(self.realowner); + olddir = normalize(self.velocity); + newdir = normalize(trace_endpos - self.origin) + randomvec() * autocvar_g_vehicle_spiderbot_rocket_noise; + self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_spiderbot_rocket_turnrate) * autocvar_g_vehicle_spiderbot_rocket_speed; + + UpdateCSQCProjectile(self); + + if (self.owner.deadflag != DEAD_NO || self.cnt < time) + self.use(); +} + +void spiderbot_guide_release() +{ + entity rkt; + rkt = findchainentity(realowner, self.owner); + if not (rkt) + return; + + crosshair_trace(self.owner); + while(rkt) + { + if(rkt.think == spiderbot_rocket_guided) + { + rkt.pos1 = trace_endpos; + rkt.think = spiderbot_rocket_unguided; + } + rkt = rkt.chain; + } +} + +float spiberbot_calcartillery_flighttime; +vector spiberbot_calcartillery(vector org, vector tgt, float ht) +{ + float grav, sdist, zdist, vs, vz, jumpheight; + vector sdir; + + grav = autocvar_sv_gravity; + zdist = tgt_z - org_z; + sdist = vlen(tgt - org - zdist * '0 0 1'); + sdir = normalize(tgt - org - zdist * '0 0 1'); + + // how high do we need to go? + jumpheight = fabs(ht); + if(zdist > 0) + jumpheight = jumpheight + zdist; + + // push so high... + vz = sqrt(2 * grav * jumpheight); // NOTE: sqrt(positive)! + + // we start with downwards velocity only if it's a downjump and the jump apex should be outside the jump! + if(ht < 0) + if(zdist < 0) + vz = -vz; + + vector solution; + solution = solve_quadratic(0.5 * grav, -vz, zdist); // equation "z(ti) = zdist" + // ALWAYS solvable because jumpheight >= zdist + if(!solution_z) + solution_y = solution_x; // just in case it is not solvable due to roundoff errors, assume two equal solutions at their center (this is mainly for the usual case with ht == 0) + if(zdist == 0) + solution_x = solution_y; // solution_x is 0 in this case, so don't use it, but rather use solution_y (which will be sqrt(0.5 * jumpheight / grav), actually) + + if(zdist < 0) + { + // down-jump + if(ht < 0) + { + // almost straight line type + // jump apex is before the jump + // we must take the larger one + spiberbot_calcartillery_flighttime = solution_y; + } + else + { + // regular jump + // jump apex is during the jump + // we must take the larger one too + spiberbot_calcartillery_flighttime = solution_y; + } + } + else + { + // up-jump + if(ht < 0) + { + // almost straight line type + // jump apex is after the jump + // we must take the smaller one + spiberbot_calcartillery_flighttime = solution_x; + } + else + { + // regular jump + // jump apex is during the jump + // we must take the larger one + spiberbot_calcartillery_flighttime = solution_y; + } + } + vs = sdist / spiberbot_calcartillery_flighttime; + + // finally calculate the velocity + return sdir * vs + '0 0 1' * vz; +} + +void spiderbot_rocket_do() +{ + vector v; + entity rocket = world; + + if (self.wait != -10) + { + if (self.owner.BUTTON_ATCK2 && self.vehicle_weapon2mode == SBRM_GUIDE) + { + if (self.wait == 1) + if (self.tur_head.frame == 9 || self.tur_head.frame == 1) + { + if(self.gun2.cnt < time && self.tur_head.frame == 9) + self.tur_head.frame = 1; + + return; + } + self.wait = 1; + } + else + { + if(self.wait) + spiderbot_guide_release(); + + self.wait = 0; + } + } + + if(self.gun2.cnt > time) + return; + + if (self.tur_head.frame >= 9) + { + self.tur_head.frame = 1; + self.wait = 0; + } + + if (self.wait != -10) + if not (self.owner.BUTTON_ATCK2) + return; + + + v = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire")); + + switch(self.vehicle_weapon2mode) + { + case SBRM_VOLLY: + rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav", + v, normalize(randomvec() * autocvar_g_vehicle_spiderbot_rocket_spread + v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed, + autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1, + DEATH_VH_SPID_ROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, TRUE, self.owner); + crosshair_trace(self.owner); + float _dist = (random() * autocvar_g_vehicle_spiderbot_rocket_radius) + vlen(v - trace_endpos); + _dist -= (random() * autocvar_g_vehicle_spiderbot_rocket_radius) ; + rocket.nextthink = time + (_dist / autocvar_g_vehicle_spiderbot_rocket_speed); + rocket.think = vehicles_projectile_explode; + + if(self.owner.BUTTON_ATCK2 && self.tur_head.frame == 1) + self.wait = -10; + break; + case SBRM_GUIDE: + rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav", + v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed, + autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1, + DEATH_VH_SPID_ROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, FALSE, self.owner); + crosshair_trace(self.owner); + rocket.pos1 = trace_endpos; + rocket.nextthink = time; + rocket.think = spiderbot_rocket_guided; + + + break; + case SBRM_ARTILLERY: + rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav", + v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed, + autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1, + DEATH_VH_SPID_ROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, TRUE, self.owner); + + crosshair_trace(self.owner); + + rocket.pos1 = trace_endpos + randomvec() * (0.75 * autocvar_g_vehicle_spiderbot_rocket_radius); + rocket.pos1_z = trace_endpos_z; + + traceline(v, v + '0 0 1' * MAX_SHOT_DISTANCE, MOVE_WORLDONLY, self); + float h1 = 0.75 * vlen(v - trace_endpos); + + //v = trace_endpos; + traceline(v , rocket.pos1 + '0 0 1' * MAX_SHOT_DISTANCE, MOVE_WORLDONLY, self); + float h2 = 0.75 * vlen(rocket.pos1 - v); + + rocket.velocity = spiberbot_calcartillery(v, rocket.pos1, ((h1 < h2) ? h1 : h2)); + rocket.movetype = MOVETYPE_TOSS; + rocket.gravity = 1; + //rocket.think = spiderbot_rocket_artillery; + break; + } + rocket.classname = "spiderbot_rocket"; + + rocket.cnt = time + autocvar_g_vehicle_spiderbot_rocket_lifetime; + + self.tur_head.frame += 1; + if (self.tur_head.frame == 9) + self.attack_finished_single = autocvar_g_vehicle_spiderbot_rocket_reload; + else + self.attack_finished_single = ((self.vehicle_weapon2mode == SBRM_VOLLY) ? autocvar_g_vehicle_spiderbot_rocket_refire2 : autocvar_g_vehicle_spiderbot_rocket_refire); + + self.gun2.cnt = time + self.attack_finished_single; +} + +float spiderbot_frame() +{ + vector ad, vf; + entity player, spider; + float ftmp; + + if(intermission_running) + return 1; + + player = self; + spider = self.vehicle; + self = spider; + + vehicles_painframe(); + + player.BUTTON_ZOOM = 0; + player.BUTTON_CROUCH = 0; + player.switchweapon = 0; + + +#if 1 // 0 to enable per-gun impact aux crosshairs + // Avarage gun impact point's -> aux cross + ad = gettaginfo(spider.tur_head, gettagindex(spider.tur_head, "tag_hardpoint01")); + vf = v_forward; + ad += gettaginfo(spider.tur_head, gettagindex(spider.tur_head, "tag_hardpoint02")); + vf += v_forward; + ad = ad * 0.5; + v_forward = vf * 0.5; + traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, spider); + UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload1) + ('0 1 0' * (1 - player.vehicle_reload1)), 0); +#else + ad = gettaginfo(spider.gun1, gettagindex(spider.gun1, "barrels")); + traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, spider); + UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload1) + ('0 1 0' * (1 - player.vehicle_reload1)), 0); + vf = ad; + ad = gettaginfo(spider.gun2, gettagindex(spider.gun2, "barrels")); + traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, spider); + UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload1) + ('0 1 0' * (1 - player.vehicle_reload1)), 1); + ad = 0.5 * (ad + vf); +#endif + + crosshair_trace(player); + ad = vectoangles(normalize(trace_endpos - ad)); + ad = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(spider.angles), AnglesTransform_FromAngles(ad))) - spider.tur_head.angles; + ad = AnglesTransform_Normalize(ad, TRUE); + //UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload2) + ('0 1 0' * (1 - player.vehicle_reload2)), 2); + + // Rotate head + ftmp = autocvar_g_vehicle_spiderbot_head_turnspeed * sys_frametime; + ad_y = bound(-ftmp, ad_y, ftmp); + spider.tur_head.angles_y = bound(autocvar_g_vehicle_spiderbot_head_turnlimit * -1, spider.tur_head.angles_y + ad_y, autocvar_g_vehicle_spiderbot_head_turnlimit); + + // Pitch head + ad_x = bound(ftmp * -1, ad_x, ftmp); + spider.tur_head.angles_x = bound(autocvar_g_vehicle_spiderbot_head_pitchlimit_down, spider.tur_head.angles_x + ad_x, autocvar_g_vehicle_spiderbot_head_pitchlimit_up); + + + //fixedmakevectors(spider.angles); + makevectors(spider.angles + '-2 0 0' * spider.angles_x); + + movelib_groundalign4point(autocvar_g_vehicle_spiderbot_springlength, autocvar_g_vehicle_spiderbot_springup, autocvar_g_vehicle_spiderbot_springblend, autocvar_g_vehicle_spiderbot_tiltlimit); + + if(spider.flags & FL_ONGROUND) + { + if(spider.frame == 4 && self.tur_head.wait != 0) + { + sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_land.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + spider.frame = 5; + } + + if(player.BUTTON_JUMP && self.tur_head.wait < time) + { + sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_jump.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + //dprint("spiderbot_jump:", ftos(soundlength("vehicles/spiderbot_jump.wav")), "\n"); + self.delay = 0; + + self.tur_head.wait = time + 2; + player.BUTTON_JUMP = 0; + spider.velocity = v_forward * 700 + v_up * 600; + spider.frame = 4; + } + else + { + if(vlen(player.movement) == 0) + { + if(self.sound_nexttime < time || self.delay != 3) + { + self.delay = 3; + self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_idle.wav"); + //dprint("spiderbot_idle:", ftos(soundlength("vehicles/spiderbot_idle.wav")), "\n"); + sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_idle.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + } + movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop); + spider.frame = 5; + } + else + { + // Turn Body + if(player.movement_x == 0 && player.movement_y != 0) + ftmp = autocvar_g_vehicle_spiderbot_turnspeed_strafe * sys_frametime; + else + ftmp = autocvar_g_vehicle_spiderbot_turnspeed * sys_frametime; + + ftmp = bound(-ftmp, spider.tur_head.angles_y, ftmp); + spider.angles_y = anglemods(spider.angles_y + ftmp); + spider.tur_head.angles_y -= ftmp; + + if(player.movement_x != 0) + { + if(player.movement_x > 0) + { + player.movement_x = 1; + spider.frame = 0; + } + else if(player.movement_x < 0) + { + player.movement_x = -1; + spider.frame = 1; + } + player.movement_y = 0; + movelib_move_simple(normalize(v_forward * player.movement_x),autocvar_g_vehicle_spiderbot_speed_walk,autocvar_g_vehicle_spiderbot_movement_inertia); + + if(self.sound_nexttime < time || self.delay != 1) + { + self.delay = 1; + self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_walk.wav"); + sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_walk.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + //dprint("spiderbot_walk:", ftos(soundlength("vehicles/spiderbot_walk.wav")), "\n"); + } + } + else if(player.movement_y != 0) + { + if(player.movement_y < 0) + { + player.movement_y = -1; + spider.frame = 2; + } + else if(player.movement_y > 0) + { + player.movement_y = 1; + spider.frame = 3; + } + movelib_move_simple(normalize(v_right * player.movement_y),autocvar_g_vehicle_spiderbot_speed_strafe,autocvar_g_vehicle_spiderbot_movement_inertia); + if(self.sound_nexttime < time || self.delay != 2) + { + self.delay = 2; + self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_strafe.wav"); + sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_strafe.wav", VOL_VEHICLEENGINE, ATTEN_NORM); + //dprint("spiderbot_strafe:", ftos(soundlength("vehicles/spiderbot_strafe.wav")), "\n"); + } + } + } + } + } + + self.angles_x = bound(-autocvar_g_vehicle_spiderbot_tiltlimit, self.angles_x, autocvar_g_vehicle_spiderbot_tiltlimit); + self.angles_z = bound(-autocvar_g_vehicle_spiderbot_tiltlimit, self.angles_z, autocvar_g_vehicle_spiderbot_tiltlimit); + + if(player.BUTTON_ATCK) + { + spider.cnt = time; + if(spider.vehicle_ammo1 >= autocvar_g_vehicle_spiderbot_minigun_ammo_cost && spider.tur_head.attack_finished_single <= time) + { + entity gun; + vector v; + spider.misc_bulletcounter += 1; + + self = player; + + mod(spider.misc_bulletcounter, 2) ? gun = spider.gun1 : gun = spider.gun2; + v = gettaginfo(gun, gettagindex(gun, "barrels")); + v_forward = normalize(v_forward); + v += v_forward * 50; + +//void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float force, float dtype, float tracereffects, float gravityfactor, float bulletconstant) + + fireBallisticBullet(v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_speed, + 5, autocvar_g_vehicle_spiderbot_minigun_damage, autocvar_g_vehicle_spiderbot_minigun_force, DEATH_VH_SPID_MINIGUN, 0, 1, autocvar_g_vehicle_spiderbot_minigun_bulletconstant); + + endFireBallisticBullet(); + +// fireBullet (v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_damage, +// autocvar_g_vehicle_spiderbot_minigun_spread, DEATH_VH_SPID_MINIGUN, 0); + + sound (gun, CH_WEAPON_A, "weapons/uzi_fire.wav", VOL_BASE, ATTEN_NORM); + //trailparticles(self, particleeffectnum("spiderbot_minigun_trail"), v, trace_endpos); + pointparticles(particleeffectnum("spiderbot_minigun_muzzleflash"), v, v_forward * 2500, 1); + + self = spider; + + spider.vehicle_ammo1 -= autocvar_g_vehicle_spiderbot_minigun_ammo_cost; + spider.tur_head.attack_finished_single = time + autocvar_g_vehicle_spiderbot_minigun_refire; + player.vehicle_ammo1 = (spider.vehicle_ammo1 / autocvar_g_vehicle_spiderbot_minigun_ammo_max) * 100; + spider.gun1.angles_z += 45; + spider.gun2.angles_z -= 45; + if(spider.gun1.angles_z >= 360) + { + spider.gun1.angles_z = 0; + spider.gun2.angles_z = 0; + } + } + } + else + vehicles_regen(spider.cnt, vehicle_ammo1, autocvar_g_vehicle_spiderbot_minigun_ammo_max, + autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause, + autocvar_g_vehicle_spiderbot_minigun_ammo_regen, frametime, FALSE); + + + spiderbot_rocket_do(); + + if(self.vehicle_flags & VHF_SHIELDREGEN) + vehicles_regen(spider.dmg_time, vehicle_shield, autocvar_g_vehicle_spiderbot_shield, autocvar_g_vehicle_spiderbot_shield_regen_pause, autocvar_g_vehicle_spiderbot_shield_regen, frametime, TRUE); + + if(self.vehicle_flags & VHF_HEALTHREGEN) + vehicles_regen(spider.dmg_time, vehicle_health, autocvar_g_vehicle_spiderbot_health, autocvar_g_vehicle_spiderbot_health_regen_pause, autocvar_g_vehicle_spiderbot_health_regen, frametime, FALSE); + + player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; + player.vehicle_ammo2 = spider.tur_head.frame; + + if(spider.gun2.cnt <= time) + player.vehicle_reload2 = 100; + else + player.vehicle_reload2 = 100 - ((spider.gun2.cnt - time) / spider.attack_finished_single) * 100; + + setorigin(player, spider.origin + '0 0 1' * spider.maxs_z); + player.velocity = spider.velocity; + + VEHICLE_UPDATE_PLAYER(player, health, spiderbot); + + if(self.vehicle_flags & VHF_HASSHIELD) + VEHICLE_UPDATE_PLAYER(player, shield, spiderbot); + + self = player; + return 1; +} + +void spiderbot_exit(float eject) +{ + entity e; + vector spot; + + e = findchain(classname,"spiderbot_rocket"); + while(e) + { + if(e.owner == self.owner) + { + e.realowner = self.owner; + e.owner = world; + } + e = e.chain; + } + + self.think = vehicles_think; + self.nextthink = time; + self.frame = 5; + self.movetype = MOVETYPE_WALK; + + if not(self.owner) + return; + + makevectors(self.angles); + if(eject) + { + spot = self.origin + v_forward * 100 + '0 0 64'; + spot = vehicles_findgoodexit(spot); + setorigin(self.owner , spot); + self.owner.velocity = (v_up + v_forward * 0.25) * 750; + self.owner.oldvelocity = self.owner.velocity; + } + else + { + if(vlen(self.velocity) > autocvar_g_vehicle_spiderbot_speed_strafe) + { + self.owner.velocity = normalize(self.velocity) * vlen(self.velocity); + self.owner.velocity_z += 200; + spot = self.origin + v_forward * 128 + '0 0 64'; + spot = vehicles_findgoodexit(spot); + } + else + { + self.owner.velocity = self.velocity * 0.5; + self.owner.velocity_z += 10; + spot = self.origin + v_forward * 256 + '0 0 64'; + spot = vehicles_findgoodexit(spot); + } + self.owner.oldvelocity = self.owner.velocity; + setorigin(self.owner , spot); + } + + antilag_clear(self.owner); + self.owner = world; +} + +void spiderbot_headfade() +{ + self.think = spiderbot_headfade; + self.nextthink = self.fade_time; + self.alpha = 1 - (time - self.fade_time) * self.fade_rate; + + if(self.cnt < time || self.alpha < 0.1) + { + if(self.alpha > 0.1) + { + sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("explosion_big"), self.origin + '0 0 100', '0 0 0', 1); + } + remove(self); + } +} + +void spiderbot_blowup() +{ + if(self.cnt > time) + { + if(random() < 0.1) + { + sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); + pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); + } + self.nextthink = time + 0.1; + return; + } + + entity h, g1, g2, b; + b = spawn(); + h = spawn(); + g1 = spawn(); + g2 = spawn(); + + setmodel(b, "models/vehicles/spiderbot.dpm"); + setmodel(h, "models/vehicles/spiderbot_top.dpm"); + setmodel(g1, "models/vehicles/spiderbot_barrels.dpm"); + setmodel(g2, "models/vehicles/spiderbot_barrels.dpm"); + + setorigin(b, self.origin); + b.frame = 11; + b.angles = self.angles; + setsize(b, self.mins, self.maxs); + + setorigin(h, gettaginfo(self, gettagindex(self, "tag_head"))); + h.movetype = MOVETYPE_BOUNCE; + h.solid = SOLID_BBOX; + h.velocity = v_up * (500 + random() * 500) + randomvec() * 128; + h.modelflags = MF_ROCKET; + h.effects = EF_FLAME | EF_LOWPRECISION; + h.avelocity = randomvec() * 360; + + h.alpha = 1; + h.cnt = time + (3.5 * random()); + h.fade_rate = 1 / min(self.respawntime, 10); + h.fade_time = time; + h.think = spiderbot_headfade; + h.nextthink = time; + + setorigin(g1, gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_hardpoint01"))); + g1.movetype = MOVETYPE_TOSS; + g1.solid = SOLID_CORPSE; + g1.velocity = v_forward * 700 + (randomvec() * 32); + g1.avelocity = randomvec() * 180; + + setorigin(g2, gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_hardpoint02"))); + g2.movetype = MOVETYPE_TOSS; + g2.solid = SOLID_CORPSE; + g2.velocity = v_forward * 700 + (randomvec() * 32); + g2.avelocity = randomvec() * 180; + + h.colormod = b.colormod = g1.colormod = g2.colormod = '-2 -2 -2'; + + SUB_SetFade(b, time + 5, min(self.respawntime, 1)); + //SUB_SetFade(h, time, min(self.respawntime, 10)); + SUB_SetFade(g1, time, min(self.respawntime, 10)); + SUB_SetFade(g2, time, min(self.respawntime, 10)); + + RadiusDamage (self, self.enemy, 250, 15, 250, world, 250, DEATH_VH_SPID_DEATH, world); + + self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = -1; + self.movetype = MOVETYPE_NONE; + self.deadflag = DEAD_DEAD; + self.solid = SOLID_NOT; + self.tur_head.effects &= ~EF_FLAME; + self.vehicle_hudmodel.viewmodelforclient = self; +} + +float spiderbot_impulse(float _imp) +{ + switch(_imp) + { + case 10: + case 15: + case 18: + self.vehicle.vehicle_weapon2mode += 1; + if(self.vehicle.vehicle_weapon2mode > SBRM_LAST) + self.vehicle.vehicle_weapon2mode = SBRM_FIRST; + + //centerprint(self, strcat("Rocket mode is ", ftos(self.vehicle.vehicle_weapon2mode))); + CSQCVehicleSetup(self, 0); + return TRUE; + case 12: + case 16: + case 19: + self.vehicle.vehicle_weapon2mode -= 1; + if(self.vehicle.vehicle_weapon2mode < SBRM_FIRST) + self.vehicle.vehicle_weapon2mode = SBRM_LAST; + + //centerprint(self, strcat("Rocket mode is ", ftos(self.vehicle.vehicle_weapon2mode))); + CSQCVehicleSetup(self, 0); + return TRUE; + + /* + case 17: // toss gun, could be used to exit? + break; + case 20: // Manual minigun reload? + break; + */ + } + return FALSE; +} + +void spawnfunc_vehicle_spiderbot() +{ + if not(autocvar_g_vehicle_spiderbot) { remove(self); return; } + if not(vehicle_initialize(VEH_SPIDERBOT, FALSE)) { remove(self); return; } +} + +float v_spiderbot(float req) +{ + switch(req) + { + case VR_IMPACT: + { + if(autocvar_g_vehicle_spiderbot_bouncepain) + vehicles_impact(autocvar_g_vehicle_spiderbot_bouncepain_x, autocvar_g_vehicle_spiderbot_bouncepain_y, autocvar_g_vehicle_spiderbot_bouncepain_z); + + return TRUE; + } + case VR_ENTER: + { + self.vehicle_weapon2mode = SBRM_GUIDE; + self.movetype = MOVETYPE_WALK; + CSQCVehicleSetup(self.owner, 0); + self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_spiderbot_health) * 100; + self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_spiderbot_shield) * 100; + + if(self.owner.flagcarried) + { + setattachment(self.owner.flagcarried, self.tur_head, ""); + setorigin(self.owner.flagcarried, '-20 0 120'); + } + + return TRUE; + } + case VR_THINK: + { + if(self.flags & FL_ONGROUND) + movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop); + + return TRUE; + } + case VR_DEATH: + { + self.health = 0; + self.event_damage = func_null; + self.takedamage = DAMAGE_NO; + self.touch = func_null; + self.cnt = 3.4 + time + random() * 2; + self.think = spiderbot_blowup; + self.nextthink = time; + self.deadflag = DEAD_DYING; + self.frame = 5; + self.tur_head.effects |= EF_FLAME; + self.colormod = self.tur_head.colormod = '-1 -1 -1'; + self.frame = 10; + self.movetype = MOVETYPE_TOSS; + + return TRUE; + } + case VR_SPAWN: + { + if not(self.gun1) + { + self.vehicles_impulse = spiderbot_impulse; + self.gun1 = spawn(); + self.gun2 = spawn(); + setmodel(self.gun1, "models/vehicles/spiderbot_barrels.dpm"); + setmodel(self.gun2, "models/vehicles/spiderbot_barrels.dpm"); + setattachment(self.gun1, self.tur_head, "tag_hardpoint01"); + setattachment(self.gun2, self.tur_head, "tag_hardpoint02"); + self.gravity = 2; + self.mass = 5000; + } + + self.frame = 5; + self.tur_head.frame = 1; + self.movetype = MOVETYPE_WALK; + self.solid = SOLID_SLIDEBOX; + self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = 1; + self.tur_head.angles = '0 0 0'; + self.vehicle_exit = spiderbot_exit; + + setorigin(self, self.pos1 + '0 0 128'); + self.angles = self.pos2; + self.damageforcescale = 0.03; + self.vehicle_health = autocvar_g_vehicle_spiderbot_health; + self.vehicle_shield = autocvar_g_vehicle_spiderbot_shield; + + self.PlayerPhysplug = spiderbot_frame; + + return TRUE; + } + case VR_SETUP: + { + if(autocvar_g_vehicle_spiderbot_shield) + self.vehicle_flags |= VHF_HASSHIELD; + + if(autocvar_g_vehicle_spiderbot_shield_regen) + self.vehicle_flags |= VHF_SHIELDREGEN; + + if(autocvar_g_vehicle_spiderbot_health_regen) + self.vehicle_flags |= VHF_HEALTHREGEN; + + self.respawntime = autocvar_g_vehicle_spiderbot_respawntime; + self.vehicle_health = autocvar_g_vehicle_spiderbot_health; + self.vehicle_shield = autocvar_g_vehicle_spiderbot_shield; + self.max_health = self.vehicle_health; + + return TRUE; + } + case VR_PRECACHE: + { + precache_model ("models/vhshield.md3"); + precache_model ("models/vehicles/spiderbot.dpm"); + precache_model ("models/vehicles/spiderbot_top.dpm"); + precache_model ("models/vehicles/spiderbot_barrels.dpm"); + precache_model ("models/vehicles/spiderbot_cockpit.dpm"); + precache_model ( "models/uziflash.md3"); + + precache_sound ("weapons/uzi_fire.wav" ); + precache_sound ("weapons/rocket_impact.wav"); + + precache_sound ("vehicles/spiderbot_die.wav"); + precache_sound ("vehicles/spiderbot_idle.wav"); + precache_sound ("vehicles/spiderbot_jump.wav"); + precache_sound ("vehicles/spiderbot_strafe.wav"); + precache_sound ("vehicles/spiderbot_walk.wav"); + precache_sound ("vehicles/spiderbot_land.wav"); + return TRUE; + } + } + + return TRUE; +} + +#endif // SVQC +#ifdef CSQC + +#define spider_ico "gfx/vehicles/sbot.tga" +#define spider_rkt "gfx/vehicles/sbot_rpods.tga" +#define spider_mgun "gfx/vehicles/sbot_mguns.tga" +string spider_xhair; // = "gfx/vehicles/axh-special1.tga"; + +float v_spiderbot(float req) +{ + switch(req) + { + case VR_HUD: + { + if(autocvar_r_letterbox) + return TRUE; + + vector picsize, hudloc = '0 0 0', pic2size, picloc; + float i; + + // Fetch health & ammo stats + HUD_GETVEHICLESTATS + + picsize = draw_getimagesize(hud_bg) * autocvar_cl_vehicles_hudscale; + hudloc_y = vid_conheight - picsize_y; + hudloc_x = vid_conwidth * 0.5 - picsize_x * 0.5; + + drawpic(hudloc, hud_bg, picsize, '1 1 1', autocvar_cl_vehicles_hudalpha, DRAWFLAG_NORMAL); + + ammo1 *= 0.01; + shield *= 0.01; + vh_health *= 0.01; + reload2 *= 0.01; + + pic2size = draw_getimagesize(spider_ico) * (autocvar_cl_vehicles_hudscale * 0.8); + picloc = picsize * 0.5 - pic2size * 0.5; + if(vh_health < 0.25) + drawpic(hudloc + picloc, spider_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, spider_ico, pic2size, '1 1 1' * vh_health + '1 0 0' * (1 - vh_health), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, spider_rkt, pic2size, '1 1 1' * reload2 + '1 0 0' * (1 - reload2), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, spider_mgun, pic2size, '1 1 1' * ammo1 + '1 0 0' * (1 - ammo1), 1, DRAWFLAG_NORMAL); + drawpic(hudloc + picloc, hud_sh, pic2size, '1 1 1', shield, DRAWFLAG_NORMAL); + + // Health bar + picsize = draw_getimagesize(hud_hp_bar) * autocvar_cl_vehicles_hudscale; + picloc = '69 69 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - vh_health)), 0, vid_conwidth, vid_conheight); + drawpic(hudloc + picloc, hud_hp_bar, picsize, '1 1 1', 1 , DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picsize = draw_getimagesize(hud_hp_ico) * autocvar_cl_vehicles_hudscale; + picloc = '37 65 0' * autocvar_cl_vehicles_hudscale; + if(vh_health < 0.25) + { + if(alarm1time < time) + { + alarm1time = time + 2; + sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE); + } + drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + } + else + { + drawpic(hudloc + picloc, hud_hp_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + if(alarm1time) + { + sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); + alarm1time = 0; + } + } + // Shield bar + picsize = draw_getimagesize(hud_sh_bar) * autocvar_cl_vehicles_hudscale; + picloc = '69 140 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x + (picsize_x * (1 - shield)), 0, vid_conwidth, vid_conheight); + drawpic(hudloc + picloc, hud_sh_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picloc = '40 136 0' * autocvar_cl_vehicles_hudscale; + picsize = draw_getimagesize(hud_sh_ico) * autocvar_cl_vehicles_hudscale; + if(shield < 0.25) + { + if(alarm2time < time) + { + alarm2time = time + 1; + sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE); + } + drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + } + else + { + drawpic(hudloc + picloc, hud_sh_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + if(alarm2time) + { + sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE); + alarm2time = 0; + } + } + + // Minigun bar + picsize = draw_getimagesize(hud_ammo1_bar) * autocvar_cl_vehicles_hudscale; + picloc = '450 69 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x, picloc_y, picsize_x * ammo1, vid_conheight); + drawpic(hudloc + picloc, hud_ammo1_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + // .. and icon + picsize = draw_getimagesize(hud_ammo1_ico) * autocvar_cl_vehicles_hudscale; + picloc = '664 60 0' * autocvar_cl_vehicles_hudscale; + if(ammo1 < 0.2) + drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, hud_ammo1_ico, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + + // Rocket ammo bar + picsize = draw_getimagesize(hud_ammo2_bar) * autocvar_cl_vehicles_hudscale; + ammo1 = picsize_x / 8; + picloc = '450 140 0' * autocvar_cl_vehicles_hudscale; + drawsetcliparea(hudloc_x + picloc_x, hudloc_y + picloc_y, picsize_x * reload2, vid_conheight); + drawpic(hudloc + picloc, hud_ammo2_bar, picsize, '1 1 1', 1, DRAWFLAG_NORMAL); + drawresetcliparea(); + + // .. and icons + pic2size = 0.35 * draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale; + picloc_x -= pic2size_x; + picloc_y += pic2size_y * 2.25; + if(ammo2 == 9) + { + for(i = 1; i < 9; ++i) + { + picloc_x += ammo1; + drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, ((8 * reload2 <= i) ? '0 0 0' : '1 1 1'), 0.75, DRAWFLAG_NORMAL); + } + } + else + { + for(i = 1; i < 9; ++i) + { + picloc_x += ammo1; + drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, ((i >= ammo2) ? '1 1 1' : '0 0 0'), 0.75, DRAWFLAG_NORMAL); + } + } + pic2size = draw_getimagesize(hud_ammo2_ico) * autocvar_cl_vehicles_hudscale; + picloc = '664 130 0' * autocvar_cl_vehicles_hudscale; + if(ammo2 == 9) + drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 0 0' + '0 1 1' * sin(time * 8), 1, DRAWFLAG_NORMAL); + else + drawpic(hudloc + picloc, hud_ammo2_ico, pic2size, '1 1 1', 1, DRAWFLAG_NORMAL); + + if (scoreboard_showscores) + HUD_DrawScoreboard(); + else + { + switch(weapon2mode) + { + case SBRM_VOLLY: + spider_xhair = "gfx/vehicles/axh-bracket.tga"; + break; + case SBRM_GUIDE: + spider_xhair = "gfx/vehicles/axh-cross.tga"; + break; + case SBRM_ARTILLERY: + spider_xhair = "gfx/vehicles/axh-tag.tga"; + break; + default: + spider_xhair= "gfx/vehicles/axh-tag.tga"; + } + + picsize = draw_getimagesize(spider_xhair); + picsize_x *= autocvar_cl_vehicle_spiderbot_cross_size; + picsize_y *= autocvar_cl_vehicle_spiderbot_cross_size; + + drawpic('0.5 0 0' * (vid_conwidth - picsize_x) + '0 0.5 0' * (vid_conheight - picsize_y), spider_xhair, picsize, '1 1 1', autocvar_cl_vehicle_spiderbot_cross_alpha, DRAWFLAG_ADDITIVE); + } + + return TRUE; + } + case VR_SETUP: + { + // Minigun1 + AuxiliaryXhair[0].axh_image = "gfx/vehicles/axh-ring.tga"; + AuxiliaryXhair[0].axh_scale = 0.25; + // Minigun2 + AuxiliaryXhair[1].axh_image = "gfx/vehicles/axh-ring.tga"; + AuxiliaryXhair[1].axh_scale = 0.25; + // Rocket + AuxiliaryXhair[2].axh_image = "gfx/vehicles/axh-special1.tga"; + AuxiliaryXhair[2].axh_scale = 0.5; + + return TRUE; + } + case VR_PRECACHE: + { + precache_model ("models/vhshield.md3"); + precache_model ("models/vehicles/spiderbot.dpm"); + precache_model ("models/vehicles/spiderbot_top.dpm"); + precache_model ("models/vehicles/spiderbot_barrels.dpm"); + precache_model ("models/vehicles/spiderbot_cockpit.dpm"); + return TRUE; + } + } + + return TRUE; +} + +#endif // CSQC +#endif // REGISTER_VEHICLE diff --git a/qcsrc/common/vehicles/vehicles.qc b/qcsrc/common/vehicles/vehicles.qc new file mode 100644 index 0000000000..91540d3154 --- /dev/null +++ b/qcsrc/common/vehicles/vehicles.qc @@ -0,0 +1,86 @@ +#include "all.qh" + +// VEHICLE PLUGIN SYSTEM +entity vehicle_info[VEH_MAXCOUNT]; +entity dummy_vehicle_info; + +void vehicles_common_initialize() +{ +#ifdef CSQC + precache_model("models/vehicles/bomblet.md3"); + precache_model("models/vehicles/clusterbomb.md3"); + precache_model("models/vehicles/clusterbomb_fragment.md3"); + precache_model("models/vehicles/rocket01.md3"); + precache_model("models/vehicles/rocket02.md3"); + + precache_sound ("vehicles/alarm.wav"); + precache_sound ("vehicles/alarm_shield.wav"); +#endif // CSQC +#ifdef SVQC + precache_sound("onslaught/ons_hit2.wav"); + precache_sound("onslaught/electricity_explode.wav"); + + addstat(STAT_HUD, AS_INT, hud); + addstat(STAT_VEHICLESTAT_HEALTH, AS_INT, vehicle_health); + addstat(STAT_VEHICLESTAT_SHIELD, AS_INT, vehicle_shield); + addstat(STAT_VEHICLESTAT_ENERGY, AS_INT, vehicle_energy); + + addstat(STAT_VEHICLESTAT_AMMO1, AS_INT, vehicle_ammo1); + addstat(STAT_VEHICLESTAT_RELOAD1, AS_INT, vehicle_reload1); + + addstat(STAT_VEHICLESTAT_AMMO2, AS_INT, vehicle_ammo2); + addstat(STAT_VEHICLESTAT_RELOAD2, AS_INT, vehicle_reload2); +#endif // SVQC +} + +void register_vehicle(float id, float(float) func, float vehicleflags, vector min_s, vector max_s, string modelname, string headmodelname, string hudmodelname, string headtag, string hudtag, string viewtag, string shortname, string vname) +{ + entity e; + vehicle_info[id - 1] = e = spawn(); + e.classname = "vehicle_info"; + e.vehicleid = id; + e.netname = shortname; + e.vehicle_name = vname; + e.vehicle_func = func; + e.mdl = modelname; + e.spawnflags = vehicleflags; + e.mins = min_s; + e.maxs = max_s; + e.model = modelname; + e.head_model = headmodelname; + e.hud_model = hudmodelname; + e.tag_head = headtag; + e.tag_hud = hudtag; + e.tag_view = viewtag; + + #ifndef MENUQC + vehicles_common_initialize(); + func(VR_PRECACHE); + #endif +} +float v_null(float dummy) { return 0; } +void register_vehicles_done() +{ + dummy_vehicle_info = spawn(); + dummy_vehicle_info.classname = "vehicle_info"; + dummy_vehicle_info.vehicleid = 0; // you can recognize dummies by this + dummy_vehicle_info.netname = ""; + dummy_vehicle_info.vehicle_name = "Vehicle"; + dummy_vehicle_info.vehicle_func = v_null; + dummy_vehicle_info.mdl = ""; + dummy_vehicle_info.mins = '-0 -0 -0'; + dummy_vehicle_info.maxs = '0 0 0'; + dummy_vehicle_info.model = ""; + dummy_vehicle_info.head_model = ""; + dummy_vehicle_info.hud_model = ""; +} +entity get_vehicleinfo(float id) +{ + entity m; + if(id < VEH_FIRST || id > VEH_LAST) + return dummy_vehicle_info; + m = vehicle_info[id - 1]; + if(m) + return m; + return dummy_vehicle_info; +} diff --git a/qcsrc/common/vehicles/vehicles.qh b/qcsrc/common/vehicles/vehicles.qh new file mode 100644 index 0000000000..db5bb8ddcc --- /dev/null +++ b/qcsrc/common/vehicles/vehicles.qh @@ -0,0 +1,89 @@ +// vehicle requests +#define VR_SETUP 1 // (BOTH) setup vehicle data +#define VR_THINK 2 // (SERVER) logic to run every frame +#define VR_DEATH 3 // (SERVER) called when vehicle dies +#define VR_PRECACHE 4 // (BOTH) precaches models/sounds used by this vehicle +#define VR_ENTER 5 // (SERVER) called when a player enters this vehicle +#define VR_SPAWN 6 // (SERVER) called when the vehicle re-spawns +#define VR_IMPACT 7 // (SERVER) called when a vehicle hits something +#define VR_HUD 8 // (CLIENT) logic to run every frame + +// functions: +entity get_vehicleinfo(float id); + +// fields: +.entity tur_head; + +// flags: +.float vehicle_flags; +const float VHF_ISVEHICLE = 2; /// Indicates vehicle +const float VHF_HASSHIELD = 4; /// Vehicle has shileding +const float VHF_SHIELDREGEN = 8; /// Vehicles shield regenerates +const float VHF_HEALTHREGEN = 16; /// Vehicles health regenerates +const float VHF_ENERGYREGEN = 32; /// Vehicles energy regenerates +const float VHF_DEATHEJECT = 64; /// Vehicle ejects pilot upon fatal damage +const float VHF_MOVE_GROUND = 128; /// Vehicle moves on gound +const float VHF_MOVE_HOVER = 256; /// Vehicle hover close to gound +const float VHF_MOVE_FLY = 512; /// Vehicle is airborn +const float VHF_DMGSHAKE = 1024; /// Add random velocity each frame if health < 50% +const float VHF_DMGROLL = 2048; /// Add random angles each frame if health < 50% +const float VHF_DMGHEADROLL = 4096; /// Add random head angles each frame if health < 50% +const float VHF_MULTISLOT = 8192; /// Vehicle has multiple player slots +const float VHF_PLAYERSLOT = 16384; /// This ent is a player slot on a multi-person vehicle + + +// entity properties of vehicleinfo: +.float vehicleid; // VEH_... +.string netname; // short name +.string vehicle_name; // human readable name +.float(float) vehicle_func; // v_... +.string mdl; // currently a copy of the model +.string model; // full name of model +.string head_model; // full name of tur_head model +.string hud_model; // cockpit model +.string tag_head; // tur_head model tag +.string tag_hud; // hud model tag +.string tag_view; // cockpit model tag +.float() PlayerPhysplug; // player physics mod +.float spawnflags; +.vector mins, maxs; // vehicle hitbox size + +// other useful macros +#define VEH_ACTION(vehicletype,mrequest) (get_vehicleinfo(vehicletype)).vehicle_func(mrequest) +#define VEH_NAME(vehicletype) (get_vehicleinfo(vehicletype)).vehicle_name + +// ===================== +// Vehicle Registration +// ===================== + +float v_null(float dummy); +void register_vehicle(float id, float(float) func, float vehicleflags, vector min_s, vector max_s, string modelname, string headmodelname, string hudmodelname, string headtag, string hudtag, string viewtag, string shortname, string vname); +void register_vehicles_done(); + +const float VEH_MAXCOUNT = 24; +#define VEH_FIRST 1 +float VEH_COUNT; +float VEH_LAST; + +#define REGISTER_VEHICLE_2(id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) \ + float id; \ + float func(float); \ + void RegisterVehicles_##id() \ + { \ + VEH_LAST = (id = VEH_FIRST + VEH_COUNT); \ + ++VEH_COUNT; \ + register_vehicle(id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname); \ + } \ + ACCUMULATE_FUNCTION(RegisterVehicles, RegisterVehicles_##id) +#ifdef MENUQC +#define REGISTER_VEHICLE(id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) \ + REGISTER_VEHICLE_2(VEH_##id,v_null,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) +#else +#define REGISTER_VEHICLE(id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) \ + REGISTER_VEHICLE_2(VEH_##id,func,vehicleflags,min_s,max_s,modelname,headmodelname,hudmodelname,headtag,hudtag,viewtag,shortname,vname) +#endif + +#include "all.qh" + +#undef REGISTER_VEHICLE +ACCUMULATE_FUNCTION(RegisterVehicles, register_vehicles_done); diff --git a/qcsrc/common/vehicles/vehicles_include.qc b/qcsrc/common/vehicles/vehicles_include.qc new file mode 100644 index 0000000000..fb83198812 --- /dev/null +++ b/qcsrc/common/vehicles/vehicles_include.qc @@ -0,0 +1,10 @@ +#ifdef VEHICLES_ENABLED +#ifdef CSQC +#include "cl_vehicles.qc" +#include "vehicles.qc" +#endif // CSQC +#ifdef SVQC +#include "sv_vehicles.qc" +#include "vehicles.qc" +#endif // SVQC +#endif // VEHICLES_ENABLED diff --git a/qcsrc/common/vehicles/vehicles_include.qh b/qcsrc/common/vehicles/vehicles_include.qh new file mode 100644 index 0000000000..574100a3f4 --- /dev/null +++ b/qcsrc/common/vehicles/vehicles_include.qh @@ -0,0 +1,12 @@ +#define VEHICLES_ENABLED + +#ifdef VEHICLES_ENABLED +#ifdef CSQC +#include "vehicles.qh" +#include "cl_vehicles.qh" +#endif // CSQC +#ifdef SVQC +#include "vehicles.qh" +#include "sv_vehicles.qh" +#endif // SVQC +#endif // VEHICLES_ENABLED diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 1ab2b7ab51..08a0f027b0 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -1610,7 +1610,11 @@ void player_regen (void) // if player rotted to death... die! if(self.health < 1) + { + if(self.vehicle) + vehicles_exit(VHEF_RELESE); self.event_damage(self, self, 1, DEATH_ROT, self.origin, '0 0 0'); + } } if not(self.items & IT_UNLIMITED_WEAPON_AMMO) @@ -2133,6 +2137,7 @@ void SpectatorThink() self.flags |= FL_CLIENT | FL_NOTARGET; } +void vehicles_enter (entity pl, entity veh); void PlayerUseKey() { if not(IS_PLAYER(self)) @@ -2143,6 +2148,34 @@ void PlayerUseKey() vehicles_exit(VHEF_NORMAL); return; } + else if(autocvar_g_vehicles_enter) + { + if not(self.freezetag_frozen) + if(self.deadflag == DEAD_NO) + { + entity head, closest_target = world; + head = WarpZone_FindRadius(self.origin, autocvar_g_vehicles_enter_radius, TRUE); + + while(head) // find the closest acceptable target to enter + { + if(head.vehicle_flags & VHF_ISVEHICLE) + if(head.deadflag == DEAD_NO) + if not(head.owner) + { + if(closest_target) + { + if(vlen(self.origin - head.origin) < vlen(self.origin - closest_target.origin)) + { closest_target = head; } + } + else { closest_target = head; } + } + + head = head.chain; + } + + if(closest_target) { vehicles_enter(self, closest_target); return; } + } + } // a use key was pressed; call handlers MUTATOR_CALLHOOK(PlayerUseKey); @@ -2158,6 +2191,7 @@ Called every frame for each client before the physics are run .float usekeypressed; void() nexball_setstatus; .float items_added; +.float last_vehiclecheck; void PlayerPreThink (void) { WarpZone_PlayerPhysics_FixVAngle(); @@ -2236,6 +2270,26 @@ void PlayerPreThink (void) #endif MUTATOR_CALLHOOK(PlayerPreThink); + + if(autocvar_g_vehicles_enter) + if(time > self.last_vehiclecheck) + if(IS_PLAYER(self)) + if not(self.freezetag_frozen) + if not(self.vehicle) + if(self.deadflag == DEAD_NO) + { + entity veh; + for(veh = world; (veh = findflags(veh, vehicle_flags, VHF_ISVEHICLE)); ) + if(vlen(veh.origin - self.origin) < autocvar_g_vehicles_enter_radius) + if(veh.deadflag == DEAD_NO) + if not(veh.owner) + if(!veh.team || SAME_TEAM(self, veh)) + Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_VEHICLE_ENTER); + else if(autocvar_g_vehicles_steal) + Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_VEHICLE_ENTER_STEAL); + + self.last_vehiclecheck = time + 1; + } if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button { diff --git a/qcsrc/server/cl_impulse.qc b/qcsrc/server/cl_impulse.qc index a94ba29015..2535444966 100644 --- a/qcsrc/server/cl_impulse.qc +++ b/qcsrc/server/cl_impulse.qc @@ -55,8 +55,8 @@ void ImpulseCommands (void) if(self.vehicle) if(self.vehicle.deadflag == DEAD_NO) - if(self.vehicle.vehicles_impusle) - if(self.vehicle.vehicles_impusle(imp)) + if(self.vehicle.vehicles_impulse) + if(self.vehicle.vehicles_impulse(imp)) return; if(CheatImpulse(imp)) diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 68532192ec..f8c5a820f0 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -544,6 +544,7 @@ void spawnfunc___init_dedicated_server(void) // needs to be done so early because of the constants they create CALL_ACCUMULATED_FUNCTION(RegisterWeapons); + CALL_ACCUMULATED_FUNCTION(RegisterVehicles); CALL_ACCUMULATED_FUNCTION(RegisterGametypes); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); @@ -592,6 +593,7 @@ void spawnfunc_worldspawn (void) // needs to be done so early because of the constants they create CALL_ACCUMULATED_FUNCTION(RegisterWeapons); + CALL_ACCUMULATED_FUNCTION(RegisterVehicles); CALL_ACCUMULATED_FUNCTION(RegisterGametypes); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); diff --git a/qcsrc/server/mutators/gamemode_assault.qc b/qcsrc/server/mutators/gamemode_assault.qc index 94e104728f..b41729a10a 100644 --- a/qcsrc/server/mutators/gamemode_assault.qc +++ b/qcsrc/server/mutators/gamemode_assault.qc @@ -212,7 +212,7 @@ void assault_wall_think() // trigger new round // reset objectives, toggle spawnpoints, reset triggers, ... -void vehicles_clearrturn(); +void vehicles_clearreturn(entity veh); void vehicles_spawn(); void assault_new_round() { @@ -230,7 +230,7 @@ void assault_new_round() self = findchainflags(vehicle_flags, VHF_ISVEHICLE); while(self) { - vehicles_clearrturn(); + vehicles_clearreturn(self); vehicles_spawn(); self = self.chain; } diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index 8980f77594..b884444d12 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -34,6 +34,8 @@ defs.qh // Should rename this, it has fields and globals ../common/notifications.qh // must be after autocvars ../common/deathtypes.qh // must be after notifications +../common/vehicles/vehicles_include.qh + mutators/base.qh mutators/mutators.qh mutators/gamemode_assault.qh @@ -50,7 +52,6 @@ mutators/mutator_nades.qh //// tZork Turrets //// tturrets/include/turrets_early.qh -vehicles/vehicles_def.qh campaign.qh ../common/campaign_common.qh @@ -197,7 +198,6 @@ race.qc //// tZork Turrets //// tturrets/include/turrets.qh -vehicles/vehicles.qh scores.qc @@ -211,6 +211,7 @@ target_music.qc ../common/items.qc +../common/vehicles/vehicles_include.qc accuracy.qc ../csqcmodellib/sv_model.qc diff --git a/qcsrc/server/vehicles/bumblebee.qc b/qcsrc/server/vehicles/bumblebee.qc deleted file mode 100644 index dff26d6ea3..0000000000 --- a/qcsrc/server/vehicles/bumblebee.qc +++ /dev/null @@ -1,1061 +0,0 @@ -#define BRG_SETUP 2 -#define BRG_START 4 -#define BRG_END 8 - -#ifdef SVQC -// Auto cvars -float autocvar_g_vehicle_bumblebee_speed_forward; -float autocvar_g_vehicle_bumblebee_speed_strafe; -float autocvar_g_vehicle_bumblebee_speed_up; -float autocvar_g_vehicle_bumblebee_speed_down; -float autocvar_g_vehicle_bumblebee_turnspeed; -float autocvar_g_vehicle_bumblebee_pitchspeed; -float autocvar_g_vehicle_bumblebee_pitchlimit; -float autocvar_g_vehicle_bumblebee_friction; - -float autocvar_g_vehicle_bumblebee_energy; -float autocvar_g_vehicle_bumblebee_energy_regen; -float autocvar_g_vehicle_bumblebee_energy_regen_pause; - -float autocvar_g_vehicle_bumblebee_health; -float autocvar_g_vehicle_bumblebee_health_regen; -float autocvar_g_vehicle_bumblebee_health_regen_pause; - -float autocvar_g_vehicle_bumblebee_shield; -float autocvar_g_vehicle_bumblebee_shield_regen; -float autocvar_g_vehicle_bumblebee_shield_regen_pause; - -float autocvar_g_vehicle_bumblebee_cannon_cost; -float autocvar_g_vehicle_bumblebee_cannon_damage; -float autocvar_g_vehicle_bumblebee_cannon_radius; -float autocvar_g_vehicle_bumblebee_cannon_refire; -float autocvar_g_vehicle_bumblebee_cannon_speed; -float autocvar_g_vehicle_bumblebee_cannon_spread; -float autocvar_g_vehicle_bumblebee_cannon_force; - -float autocvar_g_vehicle_bumblebee_cannon_ammo; -float autocvar_g_vehicle_bumblebee_cannon_ammo_regen; -float autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause; - -var float autocvar_g_vehicle_bumblebee_cannon_lock = 0; - -float autocvar_g_vehicle_bumblebee_cannon_turnspeed; -float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down; -float autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up; -float autocvar_g_vehicle_bumblebee_cannon_turnlimit_in; -float autocvar_g_vehicle_bumblebee_cannon_turnlimit_out; - - -float autocvar_g_vehicle_bumblebee_raygun_turnspeed; -float autocvar_g_vehicle_bumblebee_raygun_pitchlimit_down; -float autocvar_g_vehicle_bumblebee_raygun_pitchlimit_up; -float autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides; - -float autocvar_g_vehicle_bumblebee_raygun_range; -float autocvar_g_vehicle_bumblebee_raygun_dps; -float autocvar_g_vehicle_bumblebee_raygun_aps; -float autocvar_g_vehicle_bumblebee_raygun_fps; - -float autocvar_g_vehicle_bumblebee_raygun; -float autocvar_g_vehicle_bumblebee_healgun_hps; -float autocvar_g_vehicle_bumblebee_healgun_hmax; -float autocvar_g_vehicle_bumblebee_healgun_aps; -float autocvar_g_vehicle_bumblebee_healgun_amax; -float autocvar_g_vehicle_bumblebee_healgun_sps; -float autocvar_g_vehicle_bumblebee_healgun_locktime; - -float autocvar_g_vehicle_bumblebee_respawntime; - -float autocvar_g_vehicle_bumblebee_blowup_radius; -float autocvar_g_vehicle_bumblebee_blowup_coredamage; -float autocvar_g_vehicle_bumblebee_blowup_edgedamage; -float autocvar_g_vehicle_bumblebee_blowup_forceintensity; -var vector autocvar_g_vehicle_bumblebee_bouncepain; - -var float autocvar_g_vehicle_bumblebee = 0; - - -float bumble_raygun_send(entity to, float sf); - -#define BUMB_MIN '-130 -130 -130' -#define BUMB_MAX '130 130 130' - -void bumb_fire_cannon(entity _gun, string _tagname, entity _owner) -{ - vector v = gettaginfo(_gun, gettagindex(_gun, _tagname)); - vehicles_projectile("bigplasma_muzzleflash", "weapons/flacexp3.wav", - v, normalize(v_forward + randomvec() * autocvar_g_vehicle_bumblebee_cannon_spread) * autocvar_g_vehicle_bumblebee_cannon_speed, - autocvar_g_vehicle_bumblebee_cannon_damage, autocvar_g_vehicle_bumblebee_cannon_radius, autocvar_g_vehicle_bumblebee_cannon_force, 0, - DEATH_VH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, TRUE, TRUE, _owner); -} - -float bumb_gunner_frame() -{ - entity vehic = self.vehicle.owner; - entity gun = self.vehicle; - entity gunner = self; - self = vehic; - - - - - vehic.solid = SOLID_NOT; - //setorigin(gunner, vehic.origin); - gunner.velocity = vehic.velocity; - - float _in, _out; - vehic.angles_x *= -1; - makevectors(vehic.angles); - vehic.angles_x *= -1; - if((gun == vehic.gun1)) - { - _in = autocvar_g_vehicle_bumblebee_cannon_turnlimit_in; - _out = autocvar_g_vehicle_bumblebee_cannon_turnlimit_out; - setorigin(gunner, vehic.origin + v_up * -16 + v_forward * -16 + v_right * 128); - } - else - { - _in = autocvar_g_vehicle_bumblebee_cannon_turnlimit_out; - _out = autocvar_g_vehicle_bumblebee_cannon_turnlimit_in; - setorigin(gunner, vehic.origin + v_up * -16 + v_forward * -16 + v_right * -128); - } - - crosshair_trace(gunner); - vector _ct = trace_endpos; - vector ad; - - if(autocvar_g_vehicle_bumblebee_cannon_lock) - { - if(gun.lock_time < time) - gun.enemy = world; - - if(trace_ent) - if(trace_ent.movetype) - if(trace_ent.takedamage) - if(!trace_ent.deadflag) - { - if(teamplay) - { - if(trace_ent.team != gunner.team) - { - gun.enemy = trace_ent; - gun.lock_time = time + 5; - } - } - else - { - gun.enemy = trace_ent; - gun.lock_time = time + 5; - } - } - } - - if(gun.enemy) - { - float i, distance, impact_time; - - vector vf = real_origin(gun.enemy); - vector _vel = gun.enemy.velocity; - if(gun.enemy.movetype == MOVETYPE_WALK) - _vel_z *= 0.1; - - - ad = vf; - for(i = 0; i < 4; ++i) - { - distance = vlen(ad - gunner.origin); - impact_time = distance / autocvar_g_vehicle_bumblebee_cannon_speed; - ad = vf + _vel * impact_time; - } - trace_endpos = ad; - - - UpdateAuxiliaryXhair(gunner, ad, '1 0 1', 1); - vehicle_aimturret(vehic, trace_endpos, gun, "fire", - autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up, - _out * -1, _in, autocvar_g_vehicle_bumblebee_cannon_turnspeed); - - } - else - vehicle_aimturret(vehic, _ct, gun, "fire", - autocvar_g_vehicle_bumblebee_cannon_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_cannon_pitchlimit_up, - _out * -1, _in, autocvar_g_vehicle_bumblebee_cannon_turnspeed); - - if(gunner.BUTTON_ATCK) - if(time > gun.attack_finished_single) - if(gun.vehicle_energy >= autocvar_g_vehicle_bumblebee_cannon_cost) - { - gun.vehicle_energy -= autocvar_g_vehicle_bumblebee_cannon_cost; - bumb_fire_cannon(gun, "fire", gunner); - gun.delay = time; - gun.attack_finished_single = time + autocvar_g_vehicle_bumblebee_cannon_refire; - } - - VEHICLE_UPDATE_PLAYER(gunner, health, bumblebee); - - if(vehic.vehicle_flags & VHF_HASSHIELD) - VEHICLE_UPDATE_PLAYER(gunner, shield, bumblebee); - - ad = gettaginfo(gun, gettagindex(gun, "fire")); - traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, gun); - - UpdateAuxiliaryXhair(gunner, trace_endpos, ('1 0 0' * gunner.vehicle_reload1) + ('0 1 0' *(1 - gunner.vehicle_reload1)), 0); - - if(vehic.owner) - UpdateAuxiliaryXhair(vehic.owner, trace_endpos, ('1 0 0' * gunner.vehicle_reload1) + ('0 1 0' *(1 - gunner.vehicle_reload1)), ((gunner == vehic.gunner1) ? 1 : 2)); - - vehic.solid = SOLID_BBOX; - gunner.BUTTON_ATCK = gunner.BUTTON_ATCK2 = gunner.BUTTON_CROUCH = 0; - gunner.vehicle_energy = (gun.vehicle_energy / autocvar_g_vehicle_bumblebee_cannon_ammo) * 100; - - self = gunner; - return 1; -} - -void bumb_gunner_exit(float _exitflag) -{ - if(IS_REAL_CLIENT(self)) - { - msg_entity = self; - WriteByte(MSG_ONE, SVC_SETVIEWPORT); - WriteEntity(MSG_ONE, self); - - WriteByte(MSG_ONE, SVC_SETVIEWANGLES); - WriteAngle(MSG_ONE, 0); - WriteAngle(MSG_ONE, self.vehicle.angles_y); - WriteAngle(MSG_ONE, 0); - } - - CSQCVehicleSetup(self, HUD_NORMAL); - setsize(self, PL_MIN, PL_MAX); - - self.takedamage = DAMAGE_AIM; - self.solid = SOLID_SLIDEBOX; - self.movetype = MOVETYPE_WALK; - self.effects &= ~EF_NODRAW; - self.alpha = 1; - self.PlayerPhysplug = func_null; - self.view_ofs = PL_VIEW_OFS; - self.event_damage = PlayerDamage; - self.hud = HUD_NORMAL; - self.switchweapon = self.vehicle.switchweapon; - - vh_player = self; - vh_vehicle = self.vehicle; - MUTATOR_CALLHOOK(VehicleExit); - self = vh_player; - self.vehicle = vh_vehicle; - - self.vehicle.vehicle_hudmodel.viewmodelforclient = self.vehicle; - - fixedmakevectors(self.vehicle.owner.angles); - - if(self == self.vehicle.owner.gunner1) - { - self.vehicle.owner.gunner1 = world; - } - else if(self == self.vehicle.owner.gunner2) - { - self.vehicle.owner.gunner2 = world; - v_right *= -1; - } - else - dprint("^1self != gunner1 or gunner2, this is a BIG PROBLEM, tell tZork this happend.\n"); - - vector spot = self.vehicle.owner.origin + + v_up * 128 + v_right * 300; - spot = vehicles_findgoodexit(spot); - //setorigin(self , spot); - - self.velocity = 0.75 * self.vehicle.owner.velocity + normalize(spot - self.vehicle.owner.origin) * 200; - self.velocity_z += 10; - - self.vehicle.phase = time + 5; - self.vehicle = world; -} - -float bumb_gunner_enter() -{ - RemoveGrapplingHook(other); - entity _gun, _gunner; - if(!self.gunner1) - { - _gun = self.gun1; - _gunner = self.gunner1; - self.gunner1 = other; - } - else if(!self.gunner2) - { - _gun = self.gun2; - _gunner = self.gunner2; - self.gunner2 = other; - } - else - { - dprint("^1ERROR:^7Tried to enter a fully occupied vehicle!\n"); - return FALSE; - } - - _gunner = other; - _gunner.vehicle = _gun; - _gun.switchweapon = other.switchweapon; - _gun.vehicle_exit = bumb_gunner_exit; - - other.angles = self.angles; - other.takedamage = DAMAGE_NO; - other.solid = SOLID_NOT; - other.movetype = MOVETYPE_NOCLIP; - other.alpha = -1; - other.event_damage = func_null; - other.view_ofs = '0 0 0'; - other.hud = _gun.hud; - other.PlayerPhysplug = _gun.PlayerPhysplug; - other.vehicle_ammo1 = self.vehicle_ammo1; - other.vehicle_ammo2 = self.vehicle_ammo2; - other.vehicle_reload1 = self.vehicle_reload1; - other.vehicle_reload2 = self.vehicle_reload2; - other.vehicle_energy = self.vehicle_energy; - other.PlayerPhysplug = bumb_gunner_frame; - other.flags &= ~FL_ONGROUND; - - msg_entity = other; - WriteByte(MSG_ONE, SVC_SETVIEWPORT); - WriteEntity(MSG_ONE, _gun.vehicle_viewport); - WriteByte(MSG_ONE, SVC_SETVIEWANGLES); - WriteAngle(MSG_ONE, _gun.angles_x + self.angles_x); // tilt - WriteAngle(MSG_ONE, _gun.angles_y + self.angles_y); // yaw - WriteAngle(MSG_ONE, 0); // roll - _gun.vehicle_hudmodel.viewmodelforclient = other; - - CSQCVehicleSetup(other, other.hud); - - vh_player = other; - vh_vehicle = _gun; - MUTATOR_CALLHOOK(VehicleEnter); - other = vh_player; - _gun = vh_vehicle; - - return TRUE; -} - -float vehicles_valid_pilot() -{ - if not(IS_PLAYER(other)) - return FALSE; - - if(other.deadflag != DEAD_NO) - return FALSE; - - if(other.vehicle != world) - return FALSE; - - if not(IS_REAL_CLIENT(other)) - if(!autocvar_g_vehicles_allow_bots) - return FALSE; - - if(teamplay && other.team != self.team) - return FALSE; - - return TRUE; -} - -void bumb_touch() -{ - - if(self.gunner1 != world && self.gunner2 != world) - { - vehicles_touch(); - return; - } - - if(vehicles_valid_pilot()) - { - if(self.gun1.phase <= time) - if(bumb_gunner_enter()) - return; - - if(self.gun2.phase <= time) - if(bumb_gunner_enter()) - return; - } - - vehicles_touch(); -} - -void bumb_regen() -{ - if(self.gun1.delay + autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause < time) - self.gun1.vehicle_energy = min(autocvar_g_vehicle_bumblebee_cannon_ammo, - self.gun1.vehicle_energy + autocvar_g_vehicle_bumblebee_cannon_ammo_regen * frametime); - - if(self.gun2.delay + autocvar_g_vehicle_bumblebee_cannon_ammo_regen_pause < time) - self.gun2.vehicle_energy = min(autocvar_g_vehicle_bumblebee_cannon_ammo, - self.gun2.vehicle_energy + autocvar_g_vehicle_bumblebee_cannon_ammo_regen * frametime); - - if(self.vehicle_flags & VHF_SHIELDREGEN) - vehicles_regen(self.dmg_time, vehicle_shield, autocvar_g_vehicle_bumblebee_shield, autocvar_g_vehicle_bumblebee_shield_regen_pause, autocvar_g_vehicle_bumblebee_shield_regen, frametime, TRUE); - - if(self.vehicle_flags & VHF_HEALTHREGEN) - vehicles_regen(self.dmg_time, vehicle_health, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_health_regen_pause, autocvar_g_vehicle_bumblebee_health_regen, frametime, FALSE); - - if(self.vehicle_flags & VHF_ENERGYREGEN) - vehicles_regen(self.wait, vehicle_energy, autocvar_g_vehicle_bumblebee_energy, autocvar_g_vehicle_bumblebee_energy_regen_pause, autocvar_g_vehicle_bumblebee_energy_regen, frametime, FALSE); - -} - -float bumb_pilot_frame() -{ - entity pilot, vehic; - vector newvel; - - pilot = self; - vehic = self.vehicle; - self = vehic; - - - if(vehic.deadflag != DEAD_NO) - { - self = pilot; - pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = 0; - return 1; - } - - bumb_regen(); - - crosshair_trace(pilot); - - vector vang; - float ftmp; - - vang = vehic.angles; - newvel = vectoangles(normalize(trace_endpos - self.origin + '0 0 32')); - vang_x *= -1; - newvel_x *= -1; - if(newvel_x > 180) newvel_x -= 360; - if(newvel_x < -180) newvel_x += 360; - if(newvel_y > 180) newvel_y -= 360; - if(newvel_y < -180) newvel_y += 360; - - ftmp = shortangle_f(pilot.v_angle_y - vang_y, vang_y); - if(ftmp > 180) ftmp -= 360; - if(ftmp < -180) ftmp += 360; - vehic.avelocity_y = bound(-autocvar_g_vehicle_bumblebee_turnspeed, ftmp + vehic.avelocity_y * 0.9, autocvar_g_vehicle_bumblebee_turnspeed); - - // Pitch - ftmp = 0; - if(pilot.movement_x > 0 && vang_x < autocvar_g_vehicle_bumblebee_pitchlimit) - ftmp = 4; - else if(pilot.movement_x < 0 && vang_x > -autocvar_g_vehicle_bumblebee_pitchlimit) - ftmp = -8; - - newvel_x = bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x , autocvar_g_vehicle_bumblebee_pitchlimit); - ftmp = vang_x - bound(-autocvar_g_vehicle_bumblebee_pitchlimit, newvel_x + ftmp, autocvar_g_vehicle_bumblebee_pitchlimit); - vehic.avelocity_x = bound(-autocvar_g_vehicle_bumblebee_pitchspeed, ftmp + vehic.avelocity_x * 0.9, autocvar_g_vehicle_bumblebee_pitchspeed); - - vehic.angles_x = anglemods(vehic.angles_x); - vehic.angles_y = anglemods(vehic.angles_y); - vehic.angles_z = anglemods(vehic.angles_z); - - makevectors('0 1 0' * vehic.angles_y); - newvel = vehic.velocity * -autocvar_g_vehicle_bumblebee_friction; - - if(pilot.movement_x != 0) - { - if(pilot.movement_x > 0) - newvel += v_forward * autocvar_g_vehicle_bumblebee_speed_forward; - else if(pilot.movement_x < 0) - newvel -= v_forward * autocvar_g_vehicle_bumblebee_speed_forward; - } - - if(pilot.movement_y != 0) - { - if(pilot.movement_y < 0) - newvel -= v_right * autocvar_g_vehicle_bumblebee_speed_strafe; - else if(pilot.movement_y > 0) - newvel += v_right * autocvar_g_vehicle_bumblebee_speed_strafe; - ftmp = newvel * v_right; - ftmp *= frametime * 0.1; - vehic.angles_z = bound(-15, vehic.angles_z + ftmp, 15); - } - else - { - vehic.angles_z *= 0.95; - if(vehic.angles_z >= -1 && vehic.angles_z <= -1) - vehic.angles_z = 0; - } - - if(pilot.BUTTON_CROUCH) - newvel -= v_up * autocvar_g_vehicle_bumblebee_speed_down; - else if(pilot.BUTTON_JUMP) - newvel += v_up * autocvar_g_vehicle_bumblebee_speed_up; - - vehic.velocity += newvel * frametime; - pilot.velocity = pilot.movement = vehic.velocity; - - - if(autocvar_g_vehicle_bumblebee_healgun_locktime) - { - if(vehic.tur_head.lock_time < time || vehic.tur_head.enemy.deadflag) - vehic.tur_head.enemy = world; - - if(trace_ent) - if(trace_ent.movetype) - if(trace_ent.takedamage) - if(!trace_ent.deadflag) - { - if(teamplay) - { - if(trace_ent.team == pilot.team) - { - vehic.tur_head.enemy = trace_ent; - vehic.tur_head.lock_time = time + autocvar_g_vehicle_bumblebee_healgun_locktime; - } - } - else - { - vehic.tur_head.enemy = trace_ent; - vehic.tur_head.lock_time = time + autocvar_g_vehicle_bumblebee_healgun_locktime; - } - } - - if(vehic.tur_head.enemy) - { - trace_endpos = real_origin(vehic.tur_head.enemy); - UpdateAuxiliaryXhair(pilot, trace_endpos, '0 0.75 0', 0); - } - } - - vang = vehicle_aimturret(vehic, trace_endpos, self.gun3, "fire", - autocvar_g_vehicle_bumblebee_raygun_pitchlimit_down * -1, autocvar_g_vehicle_bumblebee_raygun_pitchlimit_up, - autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides * -1, autocvar_g_vehicle_bumblebee_raygun_turnlimit_sides, autocvar_g_vehicle_bumblebee_raygun_turnspeed); - - if((pilot.BUTTON_ATCK || pilot.BUTTON_ATCK2) && (vehic.vehicle_energy > autocvar_g_vehicle_bumblebee_raygun_dps * sys_frametime || autocvar_g_vehicle_bumblebee_raygun == 0)) - { - vehic.gun3.enemy.realowner = pilot; - vehic.gun3.enemy.effects &= ~EF_NODRAW; - - vehic.gun3.enemy.hook_start = gettaginfo(vehic.gun3, gettagindex(vehic.gun3, "fire")); - vehic.gun3.enemy.SendFlags |= BRG_START; - - traceline(vehic.gun3.enemy.hook_start, vehic.gun3.enemy.hook_start + v_forward * autocvar_g_vehicle_bumblebee_raygun_range, MOVE_NORMAL, vehic); - - if(trace_ent) - { - if(autocvar_g_vehicle_bumblebee_raygun) - { - Damage(trace_ent, vehic, pilot, autocvar_g_vehicle_bumblebee_raygun_dps * sys_frametime, DEATH_GENERIC, trace_endpos, v_forward * autocvar_g_vehicle_bumblebee_raygun_fps * sys_frametime); - vehic.vehicle_energy -= autocvar_g_vehicle_bumblebee_raygun_aps * sys_frametime; - } - else - { - if(trace_ent.deadflag == DEAD_NO) - if((teamplay && trace_ent.team == pilot.team) || !teamplay) - { - - if(trace_ent.vehicle_flags & VHF_ISVEHICLE) - { - if(autocvar_g_vehicle_bumblebee_healgun_sps && trace_ent.vehicle_health <= trace_ent.tur_health) - trace_ent.vehicle_shield = min(trace_ent.vehicle_shield + autocvar_g_vehicle_bumblebee_healgun_sps * frametime, trace_ent.tur_head.tur_health); - - if(autocvar_g_vehicle_bumblebee_healgun_hps) - trace_ent.vehicle_health = min(trace_ent.vehicle_health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, trace_ent.tur_health); - } - else if(IS_CLIENT(trace_ent)) - { - if(trace_ent.health <= autocvar_g_vehicle_bumblebee_healgun_hmax && autocvar_g_vehicle_bumblebee_healgun_hps) - trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, autocvar_g_vehicle_bumblebee_healgun_hmax); - - if(trace_ent.armorvalue <= autocvar_g_vehicle_bumblebee_healgun_amax && autocvar_g_vehicle_bumblebee_healgun_aps) - trace_ent.armorvalue = min(trace_ent.armorvalue + autocvar_g_vehicle_bumblebee_healgun_aps * frametime, autocvar_g_vehicle_bumblebee_healgun_amax); - - trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, autocvar_g_vehicle_bumblebee_healgun_hmax); - } - else if(trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET) - { - if(trace_ent.health <= trace_ent.tur_health && autocvar_g_vehicle_bumblebee_healgun_hps) - trace_ent.health = min(trace_ent.health + autocvar_g_vehicle_bumblebee_healgun_hps * frametime, trace_ent.tur_health); - //else ..hmmm what? ammo? - - trace_ent.SendFlags |= TNSF_STATUS; - } - } - } - } - - vehic.gun3.enemy.hook_end = trace_endpos; - setorigin(vehic.gun3.enemy, trace_endpos); - vehic.gun3.enemy.SendFlags |= BRG_END; - - vehic.wait = time + 1; - } - else - vehic.gun3.enemy.effects |= EF_NODRAW; - /*{ - if(vehic.gun3.enemy) - remove(vehic.gun3.enemy); - - vehic.gun3.enemy = world; - } - */ - - VEHICLE_UPDATE_PLAYER(pilot, health, bumblebee); - VEHICLE_UPDATE_PLAYER(pilot, energy, bumblebee); - - pilot.vehicle_ammo1 = (vehic.gun1.vehicle_energy / autocvar_g_vehicle_bumblebee_cannon_ammo) * 100; - pilot.vehicle_ammo2 = (vehic.gun2.vehicle_energy / autocvar_g_vehicle_bumblebee_cannon_ammo) * 100; - - if(vehic.vehicle_flags & VHF_HASSHIELD) - VEHICLE_UPDATE_PLAYER(pilot, shield, bumblebee); - - vehic.angles_x *= -1; - makevectors(vehic.angles); - vehic.angles_x *= -1; - setorigin(pilot, vehic.origin + v_up * 48 + v_forward * 160); - - pilot.BUTTON_ATCK = pilot.BUTTON_ATCK2 = pilot.BUTTON_CROUCH = 0; - self = pilot; - - return 1; -} - -void bumb_think() -{ - self.movetype = MOVETYPE_TOSS; - - //self.velocity = self.velocity * 0.5; - self.angles_z *= 0.8; - self.angles_x *= 0.8; - - self.nextthink = time + 0.05; - - if(!self.owner) - { - entity oldself = self; - if(self.gunner1) - { - self = self.gunner1; - oldself.gun1.vehicle_exit(VHEF_EJECT); - entity oldother = other; - other = self; - self = oldself; - self.phase = 0; - self.touch(); - other = oldother; - return; - } - - if(self.gunner2) - { - self = self.gunner2; - oldself.gun2.vehicle_exit(VHEF_EJECT); - entity oldother = other; - other = self; - self = oldself; - self.phase = 0; - self.touch(); - other = oldother; - return; - } - } - -} - -void bumb_enter() -{ - self.touch = bumb_touch; - self.nextthink = 0; - self.movetype = MOVETYPE_BOUNCEMISSILE; - //setattachment(self.owner, self.vehicle_viewport, ""); -} - -void bumb_exit(float eject) -{ - self.touch = vehicles_touch; - self.think = bumb_think; - self.nextthink = time; - - if(!self.owner) - return; - - fixedmakevectors(self.angles); - vector spot; - if(vlen(self.velocity) > autocvar_g_vehicle_bumblebee_speed_forward * 0.5) - spot = self.origin + v_up * 128 + v_forward * 200; - else - spot = self.origin + v_up * 128 - v_forward * 200; - - spot = vehicles_findgoodexit(spot); - - // Hide beam - if(self.gun3.enemy || !wasfreed(self.gun3.enemy)) { - self.gun3.enemy.effects |= EF_NODRAW; - } - - self.owner.velocity = 0.75 * self.vehicle.velocity + normalize(spot - self.vehicle.origin) * 200; - self.owner.velocity_z += 10; - setorigin(self.owner, spot); - - antilag_clear(self.owner); - self.owner = world; -} - -void bumb_blowup() -{ - RadiusDamage(self, self.enemy, autocvar_g_vehicle_bumblebee_blowup_coredamage, - autocvar_g_vehicle_bumblebee_blowup_edgedamage, - autocvar_g_vehicle_bumblebee_blowup_radius, self, - autocvar_g_vehicle_bumblebee_blowup_forceintensity, - DEATH_VH_BUMB_DEATH, world); - - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("explosion_large"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); - - if(self.owner.deadflag == DEAD_DYING) - self.owner.deadflag = DEAD_DEAD; - - remove(self); -} - -void bumb_diethink() -{ - if(time >= self.wait) - self.think = bumb_blowup; - - if(random() < 0.1) - { - sound(self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); - } - - self.nextthink = time + 0.1; -} - -void bumb_die() -{ - entity oldself = self; - - // Hide beam - if(self.gun3.enemy || !wasfreed(self.gun3.enemy)) - self.gun3.enemy.effects |= EF_NODRAW; - - if(self.gunner1) - { - self = self.gunner1; - oldself.gun1.vehicle_exit(VHEF_EJECT); - self = oldself; - } - - if(self.gunner2) - { - self = self.gunner2; - oldself.gun2.vehicle_exit(VHEF_EJECT); - self = oldself; - } - - self.vehicle_exit(VHEF_EJECT); - - fixedmakevectors(self.angles); - vehicle_tossgib(self.gun1, self.velocity + v_right * 300 + v_up * 100 + randomvec() * 200, "cannon_right", rint(random()), rint(random()), 6, randomvec() * 200); - vehicle_tossgib(self.gun2, self.velocity + v_right * -300 + v_up * 100 + randomvec() * 200, "cannon_left", rint(random()), rint(random()), 6, randomvec() * 200); - vehicle_tossgib(self.gun3, self.velocity + v_forward * 300 + v_up * -100 + randomvec() * 200, "raygun", rint(random()), rint(random()), 6, randomvec() * 300); - - entity _body = vehicle_tossgib(self, self.velocity + randomvec() * 200, "", rint(random()), rint(random()), 6, randomvec() * 100); - - if(random() > 0.5) - _body.touch = bumb_blowup; - else - _body.touch = func_null; - - _body.think = bumb_diethink; - _body.nextthink = time; - _body.wait = time + 2 + (random() * 8); - _body.owner = self; - _body.enemy = self.enemy; - - pointparticles(particleeffectnum("explosion_medium"), findbetterlocation(self.origin, 16), '0 0 0', 1); - - self.health = 0; - self.event_damage = func_null; - self.solid = SOLID_CORPSE; - self.takedamage = DAMAGE_NO; - self.deadflag = DEAD_DYING; - self.movetype = MOVETYPE_NONE; - self.effects = EF_NODRAW; - self.colormod = '0 0 0'; - self.avelocity = '0 0 0'; - self.velocity = '0 0 0'; - self.touch = func_null; - self.nextthink = 0; - - setorigin(self, self.pos1); - -} - -void bumb_impact() -{ - if(autocvar_g_vehicle_bumblebee_bouncepain_x) - vehilces_impact(autocvar_g_vehicle_bumblebee_bouncepain_x, - autocvar_g_vehicle_bumblebee_bouncepain_y, - autocvar_g_vehicle_bumblebee_bouncepain_z); -} - -void bumb_spawn(float _f) -{ - /* - float i; - for(i=1; gettaginfo(self.gun1, i), gettaginfo_name; ++i) - { - - dprint(" ------- ^1gettaginfo_name^2(",ftos(i),") ^3=", gettaginfo_name, "\n"); - } - */ - if(!self.gun1) - { - // for some reason, autosizing of the shiled entity refuses to work for this one so set it up in advance. - self.vehicle_shieldent = spawn(); - self.vehicle_shieldent.effects = EF_LOWPRECISION; - setmodel(self.vehicle_shieldent, "models/vhshield.md3"); - setattachment(self.vehicle_shieldent, self, ""); - setorigin(self.vehicle_shieldent, real_origin(self) - self.origin); - self.vehicle_shieldent.scale = 512 / vlen(self.maxs - self.mins); - self.vehicle_shieldent.think = shieldhit_think; - self.vehicle_shieldent.alpha = -1; - self.vehicle_shieldent.effects = EF_LOWPRECISION | EF_NODRAW; - - self.gun1 = spawn(); - self.gun2 = spawn(); - self.gun3 = spawn(); - - self.vehicle_flags |= VHF_MULTISLOT; - - self.gun1.owner = self; - self.gun2.owner = self; - self.gun3.owner = self; - - setmodel(self.gun1, "models/vehicles/bumblebee_plasma_right.dpm"); - setmodel(self.gun2, "models/vehicles/bumblebee_plasma_left.dpm"); - setmodel(self.gun3, "models/vehicles/bumblebee_ray.dpm"); - - setattachment(self.gun1, self, "cannon_right"); - setattachment(self.gun2, self, "cannon_left"); - - // Angled bones are no fun, messes up gun-aim; so work arround it. - self.gun3.pos1 = self.angles; - self.angles = '0 0 0'; - vector ofs = gettaginfo(self, gettagindex(self, "raygun")); - ofs -= self.origin; - setattachment(self.gun3, self, ""); - setorigin(self.gun3, ofs); - self.angles = self.gun3.pos1; - - vehicle_addplayerslot(self, self.gun1, HUD_BUMBLEBEE_GUN, "models/vehicles/wakizashi_cockpit.dpm", bumb_gunner_frame, bumb_gunner_exit); - vehicle_addplayerslot(self, self.gun2, HUD_BUMBLEBEE_GUN, "models/vehicles/wakizashi_cockpit.dpm", bumb_gunner_frame, bumb_gunner_exit); - - setorigin(self.vehicle_hudmodel, '50 0 -5'); // Move cockpit forward - down. - setorigin(self.vehicle_viewport, '5 0 2'); // Move camera forward up - - //fixme-model-bones - setorigin(self.gun1.vehicle_hudmodel, '90 -27 -23'); - setorigin(self.gun1.vehicle_viewport, '-85 0 50'); - //fixme-model-bones - setorigin(self.gun2.vehicle_hudmodel, '90 27 -23'); - setorigin(self.gun2.vehicle_viewport, '-85 0 50'); - - self.scale = 1.5; - - // Raygun beam - if(self.gun3.enemy == world) - { - self.gun3.enemy = spawn(); - Net_LinkEntity(self.gun3.enemy, TRUE, 0, bumble_raygun_send); - self.gun3.enemy.SendFlags = BRG_SETUP; - self.gun3.enemy.cnt = autocvar_g_vehicle_bumblebee_raygun; - self.gun3.enemy.effects = EF_NODRAW | EF_LOWPRECISION; - } - } - - self.vehicle_health = autocvar_g_vehicle_bumblebee_health; - self.vehicle_shield = autocvar_g_vehicle_bumblebee_shield; - self.solid = SOLID_BBOX; - //self.movetype = MOVETYPE_BOUNCEMISSILE; - self.movetype = MOVETYPE_TOSS; - self.vehicle_impact = bumb_impact; - self.damageforcescale = 0.025; - - setorigin(self, self.origin + '0 0 25'); -} - -void spawnfunc_vehicle_bumblebee() -{ - if(!autocvar_g_vehicle_bumblebee) - { - remove(self); - return; - } - - precache_model("models/vehicles/bumblebee_body.dpm"); - precache_model("models/vehicles/bumblebee_plasma_left.dpm"); - precache_model("models/vehicles/bumblebee_plasma_right.dpm"); - precache_model("models/vehicles/bumblebee_ray.dpm"); - precache_model("models/vehicles/wakizashi_cockpit.dpm"); - precache_model("models/vehicles/spiderbot_cockpit.dpm"); - precache_model("models/vehicles/raptor_cockpit.dpm"); - - if(autocvar_g_vehicle_bumblebee_energy) - if(autocvar_g_vehicle_bumblebee_energy_regen) - self.vehicle_flags |= VHF_ENERGYREGEN; - - if(autocvar_g_vehicle_bumblebee_shield) - self.vehicle_flags |= VHF_HASSHIELD; - - if(autocvar_g_vehicle_bumblebee_shield_regen) - self.vehicle_flags |= VHF_SHIELDREGEN; - - if(autocvar_g_vehicle_bumblebee_health_regen) - self.vehicle_flags |= VHF_HEALTHREGEN; - - if not(vehicle_initialize( - "Bumblebee", "models/vehicles/bumblebee_body.dpm", - "", "models/vehicles/spiderbot_cockpit.dpm", "", "", "tag_viewport", - HUD_BUMBLEBEE, BUMB_MIN, BUMB_MAX, FALSE, - bumb_spawn, autocvar_g_vehicle_bumblebee_respawntime, - bumb_pilot_frame, bumb_enter, bumb_exit, - bumb_die, bumb_think, FALSE, autocvar_g_vehicle_bumblebee_health, autocvar_g_vehicle_bumblebee_shield)) - { - remove(self); - return; - } -} - -float bumble_raygun_send(entity to, float sf) -{ - WriteByte(MSG_ENTITY, ENT_CLIENT_BUMBLE_RAYGUN); - - WriteByte(MSG_ENTITY, sf); - if(sf & BRG_SETUP) - { - WriteByte(MSG_ENTITY, num_for_edict(self.realowner)); - WriteByte(MSG_ENTITY, self.realowner.team); - WriteByte(MSG_ENTITY, self.cnt); - } - - if(sf & BRG_START) - { - WriteCoord(MSG_ENTITY, self.hook_start_x); - WriteCoord(MSG_ENTITY, self.hook_start_y); - WriteCoord(MSG_ENTITY, self.hook_start_z); - } - - if(sf & BRG_END) - { - WriteCoord(MSG_ENTITY, self.hook_end_x); - WriteCoord(MSG_ENTITY, self.hook_end_y); - WriteCoord(MSG_ENTITY, self.hook_end_z); - } - - return TRUE; -} -#endif // SVQC - -#ifdef CSQC -/* -.vector raygun_l1 -.vector raygun_l2; -.vector raygun_l3; -*/ - -void bumble_raygun_draw() -{ - float _len; - vector _dir; - vector _vtmp1, _vtmp2; - - _len = vlen(self.origin - self.move_origin); - _dir = normalize(self.move_origin - self.origin); - - if(self.total_damages < time) - { - boxparticles(self.traileffect, self, self.origin, self.origin + _dir * -64, _dir * -_len , _dir * -_len, 1, PARTICLES_USEALPHA); - boxparticles(self.lip, self, self.move_origin, self.move_origin + _dir * -64, _dir * -200 , _dir * -200, 1, PARTICLES_USEALPHA); - self.total_damages = time + 0.1; - } - - float i, df, sz, al; - for(i = -0.1; i < 0.2; i += 0.1) - { - df = DRAWFLAG_NORMAL; //((random() < 0.5) ? DRAWFLAG_ADDITIVE : DRAWFLAG_SCREEN); - sz = 5 + random() * 5; - al = 0.25 + random() * 0.5; - _vtmp1 = self.origin + _dir * _len * (0.25 + i); - _vtmp1 += (randomvec() * (_len * 0.2) * (frametime * 2)); //self.raygun_l1; - Draw_CylindricLine(self.origin, _vtmp1, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin); - - _vtmp2 = self.origin + _dir * _len * (0.5 + i); - _vtmp2 += (randomvec() * (_len * 0.2) * (frametime * 5)); //self.raygun_l2; - Draw_CylindricLine(_vtmp1, _vtmp2, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin); - - _vtmp1 = self.origin + _dir * _len * (0.75 + i); - _vtmp1 += randomvec() * (_len * 0.2) * (frametime * 10); //self.raygun_l3; - Draw_CylindricLine(_vtmp2, _vtmp1, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin); - - Draw_CylindricLine(_vtmp1, self.move_origin + randomvec() * 32, sz, "gfx/colors/white.tga", 1, 1, self.colormod, al, df, view_origin); - } -} - -void bumble_raygun_read(float bIsNew) -{ - float sf = ReadByte(); - - if(sf & BRG_SETUP) - { - self.cnt = ReadByte(); - self.team = ReadByte(); - self.cnt = ReadByte(); - - if(self.cnt) - self.colormod = '1 0 0'; - else - self.colormod = '0 1 0'; - - self.traileffect = particleeffectnum("healray_muzzleflash"); - self.lip = particleeffectnum("healray_impact"); - - self.draw = bumble_raygun_draw; - } - - - if(sf & BRG_START) - { - self.origin_x = ReadCoord(); - self.origin_y = ReadCoord(); - self.origin_z = ReadCoord(); - setorigin(self, self.origin); - } - - if(sf & BRG_END) - { - self.move_origin_x = ReadCoord(); - self.move_origin_y = ReadCoord(); - self.move_origin_z = ReadCoord(); - } -} - -void bumblebee_draw() -{ - -} - -void bumblebee_draw2d() -{ - -} - -void bumblebee_read_extra() -{ - -} - -void vehicle_bumblebee_assemble() -{ - -} -#endif //CSQC diff --git a/qcsrc/server/vehicles/racer.qc b/qcsrc/server/vehicles/racer.qc deleted file mode 100644 index 97bf73aed1..0000000000 --- a/qcsrc/server/vehicles/racer.qc +++ /dev/null @@ -1,690 +0,0 @@ -#define RACER_MIN '-120 -120 -40' -#define RACER_MAX '120 120 40' - -#ifdef SVQC -void racer_exit(float eject); -void racer_enter(); - -// Auto cvars -float autocvar_g_vehicle_racer; - -float autocvar_g_vehicle_racer_speed_afterburn; -float autocvar_g_vehicle_racer_afterburn_cost; - -float autocvar_g_vehicle_racer_anglestabilizer; -float autocvar_g_vehicle_racer_downforce; - -float autocvar_g_vehicle_racer_speed_forward; -float autocvar_g_vehicle_racer_speed_strafe; -float autocvar_g_vehicle_racer_springlength; -float autocvar_g_vehicle_racer_upforcedamper; -float autocvar_g_vehicle_racer_friction; - -float autocvar_g_vehicle_racer_hovertype; -float autocvar_g_vehicle_racer_hoverpower; - -float autocvar_g_vehicle_racer_turnroll; -float autocvar_g_vehicle_racer_turnspeed; -float autocvar_g_vehicle_racer_pitchspeed; - -float autocvar_g_vehicle_racer_energy; -float autocvar_g_vehicle_racer_energy_regen; -float autocvar_g_vehicle_racer_energy_regen_pause; - -float autocvar_g_vehicle_racer_health; -float autocvar_g_vehicle_racer_health_regen; -float autocvar_g_vehicle_racer_health_regen_pause; - -float autocvar_g_vehicle_racer_shield; -float autocvar_g_vehicle_racer_shield_regen; -float autocvar_g_vehicle_racer_shield_regen_pause; - -float autocvar_g_vehicle_racer_cannon_cost; -float autocvar_g_vehicle_racer_cannon_damage; -float autocvar_g_vehicle_racer_cannon_radius; -float autocvar_g_vehicle_racer_cannon_refire; -float autocvar_g_vehicle_racer_cannon_speed; -float autocvar_g_vehicle_racer_cannon_spread; -float autocvar_g_vehicle_racer_cannon_force; - -float autocvar_g_vehicle_racer_rocket_accel; -float autocvar_g_vehicle_racer_rocket_damage; -float autocvar_g_vehicle_racer_rocket_radius; -float autocvar_g_vehicle_racer_rocket_force; -float autocvar_g_vehicle_racer_rocket_refire; -float autocvar_g_vehicle_racer_rocket_speed; -float autocvar_g_vehicle_racer_rocket_turnrate; - -float autocvar_g_vehicle_racer_rocket_locktarget; -float autocvar_g_vehicle_racer_rocket_locking_time; -float autocvar_g_vehicle_racer_rocket_locking_releasetime; -float autocvar_g_vehicle_racer_rocket_locked_time; -float autocvar_g_vehicle_racer_rocket_locked_maxangle; -float autocvar_g_vehicle_racer_rocket_climbspeed; - -float autocvar_g_vehicle_racer_respawntime; - -float autocvar_g_vehicle_racer_blowup_radius; -float autocvar_g_vehicle_racer_blowup_coredamage; -float autocvar_g_vehicle_racer_blowup_edgedamage; -float autocvar_g_vehicle_racer_blowup_forceintensity; - -float autocvar_g_vehicle_racer_bouncefactor; -float autocvar_g_vehicle_racer_bouncestop; -vector autocvar_g_vehicle_racer_bouncepain; - -var vector racer_force_from_tag(string tag_name, float spring_length, float max_power); -void racer_spawn_default(); - -void racer_align4point(float _delta) -{ - vector push_vector; - float fl_push, fr_push, bl_push, br_push; - - push_vector = racer_force_from_tag("tag_engine_fr", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower); - fr_push = force_fromtag_normpower; - //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier); - - push_vector += racer_force_from_tag("tag_engine_fl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower); - fl_push = force_fromtag_normpower; - //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier); - - push_vector += racer_force_from_tag("tag_engine_br", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower); - br_push = force_fromtag_normpower; - //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier); - - push_vector += racer_force_from_tag("tag_engine_bl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower); - bl_push = force_fromtag_normpower; - //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier); - - self.velocity += push_vector * _delta; - - // Anti ocilation - if(self.velocity_z > 0) - self.velocity_z *= 1 - autocvar_g_vehicle_racer_upforcedamper * _delta; - - push_vector_x = (fl_push - bl_push); - push_vector_x += (fr_push - br_push); - push_vector_x *= 360; - - push_vector_z = (fr_push - fl_push); - push_vector_z += (br_push - bl_push); - push_vector_z *= 360; - - // Apply angle diffrance - self.angles_z += push_vector_z * _delta; - self.angles_x += push_vector_x * _delta; - - // Apply stabilizer - self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta); - self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta); -} - -void racer_fire_cannon(string tagname) -{ - vector v; - entity bolt; - - v = gettaginfo(self, gettagindex(self, tagname)); - bolt = vehicles_projectile("wakizashi_gun_muzzleflash", "weapons/lasergun_fire.wav", - v, normalize(v_forward + randomvec() * autocvar_g_vehicle_racer_cannon_spread) * autocvar_g_vehicle_racer_cannon_speed, - autocvar_g_vehicle_racer_cannon_damage, autocvar_g_vehicle_racer_cannon_radius, autocvar_g_vehicle_racer_cannon_force, 0, - DEATH_VH_WAKI_GUN, PROJECTILE_WAKICANNON, 0, TRUE, TRUE, self.owner); - - // Fix z-aim (for chase mode) - v = normalize(trace_endpos - bolt.origin); - v_forward_z = v_z * 0.5; - bolt.velocity = v_forward * autocvar_g_vehicle_racer_cannon_speed; -} - -void racer_rocket_groundhugger() -{ - vector olddir, newdir; - float oldvel, newvel; - - self.nextthink = time; - - if(self.owner.deadflag != DEAD_NO || self.cnt < time) - { - self.use(); - return; - } - - if not (self.realowner.vehicle) - { - UpdateCSQCProjectile(self); - return; - } - - olddir = normalize(self.velocity); - oldvel = vlen(self.velocity); - newvel = oldvel + self.lip; - - tracebox(self.origin, self.mins, self.maxs, self.origin + olddir * 64, MOVE_WORLDONLY,self); - if(trace_fraction <= 0.5) - { - // Hitting somethign soon, just speed ahead - self.velocity = olddir * newvel; - UpdateCSQCProjectile(self); - return; - } - - traceline(trace_endpos, trace_endpos - '0 0 64', MOVE_NORMAL, self); - if(trace_fraction != 1.0) - { - newdir = normalize(trace_endpos + '0 0 64' - self.origin) * autocvar_g_vehicle_racer_rocket_turnrate; - self.velocity = normalize(olddir + newdir) * newvel; - } - else - { - self.velocity = olddir * newvel; - self.velocity_z -= 1600 * sys_frametime; // 2x grav looks better for this one - } - - UpdateCSQCProjectile(self); - return; -} - -void racer_rocket_tracker() -{ - vector olddir, newdir; - float oldvel, newvel; - - self.nextthink = time; - - if (self.owner.deadflag != DEAD_NO || self.cnt < time) - { - self.use(); - return; - } - - if not (self.realowner.vehicle) - { - UpdateCSQCProjectile(self); - return; - } - - olddir = normalize(self.velocity); - oldvel = vlen(self.velocity); - newvel = oldvel + self.lip; - makevectors(vectoangles(olddir)); - - float time_to_impact = min(vlen(self.enemy.origin - self.origin) / vlen(self.velocity), 1); - vector predicted_origin = self.enemy.origin + self.enemy.velocity * time_to_impact; - - traceline(self.origin, self.origin + v_forward * 64 - '0 0 32', MOVE_NORMAL, self); - newdir = normalize(predicted_origin - self.origin); - - //vector - float height_diff = predicted_origin_z - self.origin_z; - - if(vlen(newdir - v_forward) > autocvar_g_vehicle_racer_rocket_locked_maxangle) - { - //bprint("Target lost!\n"); - //dprint("OF:", ftos(vlen(newdir - v_forward)), "\n"); - self.think = racer_rocket_groundhugger; - return; - } - - if(trace_fraction != 1.0 && trace_ent != self.enemy) - newdir_z += 16 * sys_frametime; - - self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_racer_rocket_turnrate) * newvel; - self.velocity_z -= 800 * sys_frametime; - self.velocity_z += max(height_diff, autocvar_g_vehicle_racer_rocket_climbspeed) * sys_frametime ; - - UpdateCSQCProjectile(self); - return; -} - -void racer_fire_rocket(string tagname, entity trg) -{ - vector v = gettaginfo(self, gettagindex(self, tagname)); - entity rocket = rocket = vehicles_projectile("wakizashi_rocket_launch", "weapons/rocket_fire.wav", - v, v_forward * autocvar_g_vehicle_racer_rocket_speed, - autocvar_g_vehicle_racer_rocket_damage, autocvar_g_vehicle_racer_rocket_radius, autocvar_g_vehicle_racer_rocket_force, 3, - DEATH_VH_WAKI_ROCKET, PROJECTILE_WAKIROCKET, 20, FALSE, FALSE, self.owner); - - rocket.lip = autocvar_g_vehicle_racer_rocket_accel * sys_frametime; - rocket.wait = autocvar_g_vehicle_racer_rocket_turnrate; - rocket.nextthink = time; - rocket.enemy = trg; - rocket.cnt = time + 15; - - if(trg) - rocket.think = racer_rocket_tracker; - else - rocket.think = racer_rocket_groundhugger; -} - -float racer_frame() -{ - entity player, racer; - vector df; - float ftmp; - - if(intermission_running) - return 1; - - player = self; - racer = self.vehicle; - self = racer; - - player.BUTTON_ZOOM = player.BUTTON_CROUCH = 0; - - vehicles_painframe(); - - if(racer.deadflag != DEAD_NO) - { - self = player; - player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; - return 1; - } - - racer_align4point(frametime); - - crosshair_trace(player); - - racer.angles_x *= -1; - - // Yaw - ftmp = autocvar_g_vehicle_racer_turnspeed * frametime; - ftmp = bound(-ftmp, shortangle_f(player.v_angle_y - racer.angles_y, racer.angles_y), ftmp); - racer.angles_y = anglemods(racer.angles_y + ftmp); - - // Roll - racer.angles_z += -ftmp * autocvar_g_vehicle_racer_turnroll * frametime; - - // Pitch - ftmp = autocvar_g_vehicle_racer_pitchspeed * frametime; - ftmp = bound(-ftmp, shortangle_f(player.v_angle_x - racer.angles_x, racer.angles_x), ftmp); - racer.angles_x = bound(-30, anglemods(racer.angles_x + ftmp), 30); - - makevectors(racer.angles); - racer.angles_x *= -1; - - //ftmp = racer.velocity_z; - df = racer.velocity * -autocvar_g_vehicle_racer_friction; - //racer.velocity_z = ftmp; - - if(vlen(player.movement) != 0) - { - if(player.movement_x) - df += v_forward * ((player.movement_x > 0) ? autocvar_g_vehicle_racer_speed_forward : -autocvar_g_vehicle_racer_speed_forward); - - if(player.movement_y) - df += v_right * ((player.movement_y > 0) ? autocvar_g_vehicle_racer_speed_strafe : -autocvar_g_vehicle_racer_speed_strafe); - - if(self.sound_nexttime < time || self.sounds != 1) - { - self.sounds = 1; - self.sound_nexttime = time + 10.922667; //soundlength("vehicles/racer_move.wav"); - sound (self, CH_TRIGGER_SINGLE, "vehicles/racer_move.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - } - } - else - { - if(self.sound_nexttime < time || self.sounds != 0) - { - self.sounds = 0; - self.sound_nexttime = time + 11.888604; //soundlength("vehicles/racer_idle.wav"); - sound (self, CH_TRIGGER_SINGLE, "vehicles/racer_idle.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - } - } - - // Afterburn - if (player.BUTTON_JUMP && racer.vehicle_energy >= (autocvar_g_vehicle_racer_afterburn_cost * frametime)) - { - if(time - racer.wait > 0.2) - pointparticles(particleeffectnum("wakizashi_booster_smoke"), self.origin - v_forward * 32, v_forward * vlen(self.velocity), 1); - - racer.wait = time; - racer.vehicle_energy -= autocvar_g_vehicle_racer_afterburn_cost * frametime; - df += (v_forward * autocvar_g_vehicle_racer_speed_afterburn); - - if(racer.invincible_finished < time) - { - traceline(racer.origin, racer.origin - '0 0 256', MOVE_NORMAL, self); - if(trace_fraction != 1.0) - pointparticles(particleeffectnum("smoke_small"), trace_endpos, '0 0 0', 1); - - racer.invincible_finished = time + 0.1 + (random() * 0.1); - } - - if(racer.strength_finished < time) - { - racer.strength_finished = time + 10.922667; //soundlength("vehicles/racer_boost.wav"); - sound (racer.tur_head, CH_TRIGGER_SINGLE, "vehicles/racer_boost.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - } - } - else - { - racer.strength_finished = 0; - sound (racer.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - } - - df -= v_up * (vlen(racer.velocity) * autocvar_g_vehicle_racer_downforce); - player.movement = racer.velocity += df * frametime; - - if(player.BUTTON_ATCK) - if(time > racer.attack_finished_single) - if(racer.vehicle_energy >= autocvar_g_vehicle_racer_cannon_cost) - { - racer.vehicle_energy -= autocvar_g_vehicle_racer_cannon_cost; - racer.wait = time; - - crosshair_trace(player); - if(racer.cnt) - { - racer_fire_cannon("tag_fire1"); - racer.cnt = 0; - } - else - { - racer_fire_cannon("tag_fire2"); - racer.cnt = 1; - } - racer.attack_finished_single = time + autocvar_g_vehicle_racer_cannon_refire; - } - - if(autocvar_g_vehicle_racer_rocket_locktarget) - { - vehicles_locktarget((1 / autocvar_g_vehicle_racer_rocket_locking_time) * frametime, - (1 / autocvar_g_vehicle_racer_rocket_locking_releasetime) * frametime, - autocvar_g_vehicle_racer_rocket_locked_time); - - if(self.lock_target) - { - if(racer.lock_strength == 1) - UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '1 0 0', 0); - else if(self.lock_strength > 0.5) - UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '0 1 0', 0); - else if(self.lock_strength < 0.5) - UpdateAuxiliaryXhair(player, real_origin(self.lock_target), '0 0 1', 0); - } - } - - if(time > racer.delay) - if(player.BUTTON_ATCK2) - { - racer.misc_bulletcounter += 1; - racer.delay = time + 0.3; - - if(racer.misc_bulletcounter == 1) - racer_fire_rocket("tag_rocket_r", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world); - else if(racer.misc_bulletcounter == 2) - { - racer_fire_rocket("tag_rocket_l", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world); - racer.lock_strength = 0; - racer.lock_target = world; - racer.misc_bulletcounter = 0; - - racer.delay = time + autocvar_g_vehicle_racer_rocket_refire; - racer.lip = time; - } - } - player.vehicle_reload1 = bound(0, 100 * ((time - racer.lip) / (racer.delay - racer.lip)), 100); - - if(racer.vehicle_flags & VHF_SHIELDREGEN) - vehicles_regen(racer.dmg_time, vehicle_shield, autocvar_g_vehicle_racer_shield, autocvar_g_vehicle_racer_shield_regen_pause, autocvar_g_vehicle_racer_shield_regen, frametime, TRUE); - - if(racer.vehicle_flags & VHF_HEALTHREGEN) - vehicles_regen(racer.dmg_time, vehicle_health, autocvar_g_vehicle_racer_health, autocvar_g_vehicle_racer_health_regen_pause, autocvar_g_vehicle_racer_health_regen, frametime, FALSE); - - if(racer.vehicle_flags & VHF_ENERGYREGEN) - vehicles_regen(racer.wait, vehicle_energy, autocvar_g_vehicle_racer_energy, autocvar_g_vehicle_racer_energy_regen_pause, autocvar_g_vehicle_racer_energy_regen, frametime, FALSE); - - - VEHICLE_UPDATE_PLAYER(player, health, racer); - VEHICLE_UPDATE_PLAYER(player, energy, racer); - - if(racer.vehicle_flags & VHF_HASSHIELD) - VEHICLE_UPDATE_PLAYER(player, shield, racer); - - player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; - setorigin(player,racer.origin + '0 0 32'); - player.velocity = racer.velocity; - - self = player; - return 1; -} - -void racer_think() -{ - self.nextthink = time; - - float pushdeltatime = time - self.lastpushtime; - if (pushdeltatime > 0.15) pushdeltatime = 0; - self.lastpushtime = time; - if(!pushdeltatime) return; - - tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * autocvar_g_vehicle_racer_springlength), MOVE_NORMAL, self); - - vector df = self.velocity * -autocvar_g_vehicle_racer_friction; - df_z += (1 - trace_fraction) * autocvar_g_vehicle_racer_hoverpower + sin(time * 2) * (autocvar_g_vehicle_racer_springlength * 2); - - self.velocity += df * pushdeltatime; - if(self.velocity_z > 0) - self.velocity_z *= 1 - autocvar_g_vehicle_racer_upforcedamper * pushdeltatime; - - self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime); - self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime); -} - -void racer_enter() -{ - self.movetype = MOVETYPE_BOUNCE; - self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_racer_health) * 100; - self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_racer_shield) * 100; - - if(self.owner.flagcarried) - setorigin(self.owner.flagcarried, '-190 0 96'); - - //targetdrone_spawn(self.origin + '0 0 512' + randomvec() * 256, 1); -} - -void racer_exit(float eject) -{ - vector spot; - - self.think = racer_think; - self.nextthink = time; - self.movetype = MOVETYPE_BOUNCE; - sound (self.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - - if not (self.owner) - return; - - makevectors(self.angles); - if(eject) - { - spot = self.origin + v_forward * 100 + '0 0 64'; - spot = vehicles_findgoodexit(spot); - setorigin(self.owner , spot); - self.owner.velocity = (v_up + v_forward * 0.25) * 750; - self.owner.oldvelocity = self.owner.velocity; - } - else - { - if(vlen(self.velocity) > 2 * autocvar_sv_maxairspeed) - { - self.owner.velocity = normalize(self.velocity) * autocvar_sv_maxairspeed * 2; - self.owner.velocity_z += 200; - spot = self.origin + v_forward * 32 + '0 0 32'; - spot = vehicles_findgoodexit(spot); - } - else - { - self.owner.velocity = self.velocity * 0.5; - self.owner.velocity_z += 10; - spot = self.origin - v_forward * 200 + '0 0 32'; - spot = vehicles_findgoodexit(spot); - } - self.owner.oldvelocity = self.owner.velocity; - setorigin(self.owner , spot); - } - antilag_clear(self.owner); - self.owner = world; -} - -void racer_impact() -{ - if(autocvar_g_vehicle_racer_bouncepain_x) - vehilces_impact(autocvar_g_vehicle_racer_bouncepain_x, autocvar_g_vehicle_racer_bouncepain_y, autocvar_g_vehicle_racer_bouncepain_z); -} - -void racer_blowup() -{ - self.deadflag = DEAD_DEAD; - self.vehicle_exit(VHEF_NORMAL); - - RadiusDamage (self, self.enemy, autocvar_g_vehicle_racer_blowup_coredamage, - autocvar_g_vehicle_racer_blowup_edgedamage, - autocvar_g_vehicle_racer_blowup_radius, world, - autocvar_g_vehicle_racer_blowup_forceintensity, - DEATH_VH_WAKI_DEATH, world); - - self.nextthink = time + autocvar_g_vehicle_racer_respawntime; - self.think = racer_spawn_default; - self.movetype = MOVETYPE_NONE; - self.effects = EF_NODRAW; - - self.colormod = '0 0 0'; - self.avelocity = '0 0 0'; - self.velocity = '0 0 0'; - - setorigin(self, self.pos1); -} - -void racer_deadtouch() -{ - self.avelocity_x *= 0.7; - self.cnt -= 1; - if(self.cnt <= 0) - racer_blowup(); -} - -void racer_die() -{ - self.health = 0; - self.event_damage = func_null; - self.solid = SOLID_CORPSE; - self.takedamage = DAMAGE_NO; - self.deadflag = DEAD_DYING; - self.movetype = MOVETYPE_BOUNCE; - self.wait = time; - self.cnt = 1 + random() * 2; - self.touch = racer_deadtouch; - - pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1); - - if(random() < 0.5) - self.avelocity_z = 32; - else - self.avelocity_z = -32; - - self.avelocity_x = -vlen(self.velocity) * 0.2; - self.velocity += '0 0 700'; - self.colormod = '-0.5 -0.5 -0.5'; - - self.think = racer_blowup; - self.nextthink = 2 + time + random() * 3; -} -void racer_spawn(float _spawnflag) -{ - if(self.scale != 0.5) - { - if(autocvar_g_vehicle_racer_hovertype != 0) - racer_force_from_tag = vehicles_force_fromtag_maglev; - else - racer_force_from_tag = vehicles_force_fromtag_hover; - - // FIXME: this be hakkz, fix the models insted (scale body, add tag_viewport to the hudmodel). - self.scale = 0.5; - setattachment(self.vehicle_hudmodel, self, ""); - setattachment(self.vehicle_viewport, self, "tag_viewport"); - - self.mass = 900; - } - - self.think = racer_think; - self.nextthink = time; - self.vehicle_health = autocvar_g_vehicle_racer_health; - self.vehicle_shield = autocvar_g_vehicle_racer_shield; - - self.movetype = MOVETYPE_TOSS; - self.solid = SOLID_SLIDEBOX; - self.delay = time; - self.scale = 0.5; - - setsize(self, RACER_MIN * 0.5, RACER_MAX * 0.5); - self.bouncefactor = autocvar_g_vehicle_racer_bouncefactor; - self.bouncestop = autocvar_g_vehicle_racer_bouncestop; - self.vehicle_impact = racer_impact; - self.damageforcescale = 0.5; - //self.destvec = autocvar_g_vehicle_racer_bouncepain; -} -void racer_spawn_default() -{ - racer_spawn(0); -} - - - -void spawnfunc_vehicle_racer() -{ - if(!autocvar_g_vehicle_racer) - { - remove(self); - return; - } - - self.vehicle_flags |= VHF_DMGSHAKE; - self.vehicle_flags |= VHF_DMGROLL; - - precache_sound ("weapons/lasergun_fire.wav"); - precache_sound ("weapons/rocket_fire.wav"); - - precache_sound ("vehicles/racer_idle.wav"); - precache_sound ("vehicles/racer_move.wav"); - precache_sound ("vehicles/racer_boost.wav"); - - precache_model ("models/vhshield.md3"); - precache_model ("models/vehicles/wakizashi.dpm"); - precache_model ("models/vehicles/wakizashi_cockpit.dpm"); - - if(autocvar_g_vehicle_racer_energy) - if(autocvar_g_vehicle_racer_energy_regen) - self.vehicle_flags |= VHF_ENERGYREGEN; - - if(autocvar_g_vehicle_racer_shield) - self.vehicle_flags |= VHF_HASSHIELD; - - if(autocvar_g_vehicle_racer_shield_regen) - self.vehicle_flags |= VHF_SHIELDREGEN; - - if(autocvar_g_vehicle_racer_health_regen) - self.vehicle_flags |= VHF_HEALTHREGEN; - - if not (vehicle_initialize( - "Wakizashi", - "models/vehicles/wakizashi.dpm", - "null", // we need this so tur_head is networked and usable for sounds - "models/vehicles/wakizashi_cockpit.dpm", - "", "", "tag_viewport", - HUD_WAKIZASHI, - 0.5 * RACER_MIN, 0.5 * RACER_MAX, - FALSE, - racer_spawn, autocvar_g_vehicle_racer_respawntime, - racer_frame, - racer_enter, racer_exit, - racer_die, racer_think, - TRUE, - autocvar_g_vehicle_racer_health, - autocvar_g_vehicle_racer_shield)) - { - remove(self); - return; - } -} -#endif // SVQC diff --git a/qcsrc/server/vehicles/raptor.qc b/qcsrc/server/vehicles/raptor.qc deleted file mode 100644 index ecad45b67c..0000000000 --- a/qcsrc/server/vehicles/raptor.qc +++ /dev/null @@ -1,940 +0,0 @@ -#define RSM_FIRST 0 -#define RSM_BOMB 0 -#define RSM_FLARE 1 -#define RSM_LAST 1 - -#define RAPTOR_MIN '-80 -80 0' -#define RAPTOR_MAX '80 80 70' - -#ifdef SVQC -float autocvar_g_vehicle_raptor; - -float autocvar_g_vehicle_raptor_respawntime; -float autocvar_g_vehicle_raptor_takeofftime; - -float autocvar_g_vehicle_raptor_movestyle; -float autocvar_g_vehicle_raptor_turnspeed; -float autocvar_g_vehicle_raptor_pitchspeed; -float autocvar_g_vehicle_raptor_pitchlimit; - -float autocvar_g_vehicle_raptor_speed_forward; -float autocvar_g_vehicle_raptor_speed_strafe; -float autocvar_g_vehicle_raptor_speed_up; -float autocvar_g_vehicle_raptor_speed_down; -float autocvar_g_vehicle_raptor_friction; - -float autocvar_g_vehicle_raptor_bomblets; -float autocvar_g_vehicle_raptor_bomblet_alt; -float autocvar_g_vehicle_raptor_bomblet_time; -float autocvar_g_vehicle_raptor_bomblet_damage; -float autocvar_g_vehicle_raptor_bomblet_spread; -float autocvar_g_vehicle_raptor_bomblet_edgedamage; -float autocvar_g_vehicle_raptor_bomblet_radius; -float autocvar_g_vehicle_raptor_bomblet_force; -float autocvar_g_vehicle_raptor_bomblet_explode_delay; -float autocvar_g_vehicle_raptor_bombs_refire; - -float autocvar_g_vehicle_raptor_flare_refire; -float autocvar_g_vehicle_raptor_flare_lifetime; -float autocvar_g_vehicle_raptor_flare_chase; -float autocvar_g_vehicle_raptor_flare_range; - -float autocvar_g_vehicle_raptor_cannon_turnspeed; -float autocvar_g_vehicle_raptor_cannon_turnlimit; -float autocvar_g_vehicle_raptor_cannon_pitchlimit_up; -float autocvar_g_vehicle_raptor_cannon_pitchlimit_down; - -float autocvar_g_vehicle_raptor_cannon_locktarget; -float autocvar_g_vehicle_raptor_cannon_locking_time; -float autocvar_g_vehicle_raptor_cannon_locking_releasetime; -float autocvar_g_vehicle_raptor_cannon_locked_time; -float autocvar_g_vehicle_raptor_cannon_predicttarget; - -float autocvar_g_vehicle_raptor_cannon_cost; -float autocvar_g_vehicle_raptor_cannon_damage; -float autocvar_g_vehicle_raptor_cannon_radius; -float autocvar_g_vehicle_raptor_cannon_refire; -float autocvar_g_vehicle_raptor_cannon_speed; -float autocvar_g_vehicle_raptor_cannon_spread; -float autocvar_g_vehicle_raptor_cannon_force; - -float autocvar_g_vehicle_raptor_energy; -float autocvar_g_vehicle_raptor_energy_regen; -float autocvar_g_vehicle_raptor_energy_regen_pause; - -float autocvar_g_vehicle_raptor_health; -float autocvar_g_vehicle_raptor_health_regen; -float autocvar_g_vehicle_raptor_health_regen_pause; - -float autocvar_g_vehicle_raptor_shield; -float autocvar_g_vehicle_raptor_shield_regen; -float autocvar_g_vehicle_raptor_shield_regen_pause; - -float autocvar_g_vehicle_raptor_bouncefactor; -float autocvar_g_vehicle_raptor_bouncestop; -vector autocvar_g_vehicle_raptor_bouncepain; - -void raptor_spawn(float); -float raptor_frame(); -float raptor_takeoff(); - -.entity bomb1; -.entity bomb2; - -float raptor_altitude(float amax) -{ - tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * amax), MOVE_WORLDONLY, self); - return vlen(self.origin - trace_endpos); -} - - -void raptor_bomblet_boom() -{ - RadiusDamage (self, self.realowner, autocvar_g_vehicle_raptor_bomblet_damage, - autocvar_g_vehicle_raptor_bomblet_edgedamage, - autocvar_g_vehicle_raptor_bomblet_radius, world, - autocvar_g_vehicle_raptor_bomblet_force, DEATH_VH_RAPT_BOMB, world); - remove(self); -} - -void raptor_bomblet_touch() -{ - if(other == self.owner) - return; - - PROJECTILE_TOUCH; - self.think = raptor_bomblet_boom; - self.nextthink = time + random() * autocvar_g_vehicle_raptor_bomblet_explode_delay; -} - -void raptor_bomb_burst() -{ - if(self.cnt > time) - if(autocvar_g_vehicle_raptor_bomblet_alt) - { - self.nextthink = time; - traceline(self.origin, self.origin + (normalize(self.velocity) * autocvar_g_vehicle_raptor_bomblet_alt), MOVE_NORMAL, self); - if((trace_fraction == 1.0) || (vlen(self.origin - self.owner.origin) < autocvar_g_vehicle_raptor_bomblet_radius)) - { - UpdateCSQCProjectile(self); - return; - } - } - - entity bomblet; - float i; - - Damage_DamageInfo(self.origin, 0, 0, 0, '0 0 0', DEATH_VH_RAPT_FRAGMENT, 0, self); - - for(i = 0; i < autocvar_g_vehicle_raptor_bomblets; ++i) - { - bomblet = spawn(); - setorigin(bomblet, self.origin); - - bomblet.movetype = MOVETYPE_TOSS; - bomblet.touch = raptor_bomblet_touch; - bomblet.think = raptor_bomblet_boom; - bomblet.nextthink = time + 5; - bomblet.owner = self.owner; - bomblet.realowner = self.realowner; - bomblet.velocity = normalize(normalize(self.velocity) + (randomvec() * autocvar_g_vehicle_raptor_bomblet_spread)) * vlen(self.velocity); - - PROJECTILE_MAKETRIGGER(bomblet); - CSQCProjectile(bomblet, TRUE, PROJECTILE_RAPTORBOMBLET, TRUE); - } - - remove(self); -} - -void raptor_bombdrop() -{ - entity bomb_1, bomb_2; - - bomb_1 = spawn(); - bomb_2 = spawn(); - - setorigin(bomb_1, gettaginfo(self, gettagindex(self, "bombmount_left"))); - setorigin(bomb_2, gettaginfo(self, gettagindex(self, "bombmount_right"))); - - bomb_1.movetype = bomb_2.movetype = MOVETYPE_BOUNCE; - bomb_1.velocity = bomb_2.velocity = self.velocity; - bomb_1.touch = bomb_2.touch = raptor_bomb_burst; - bomb_1.think = bomb_2.think = raptor_bomb_burst; - bomb_1.cnt = bomb_2.cnt = time + 10; - - if(autocvar_g_vehicle_raptor_bomblet_alt) - bomb_1.nextthink = bomb_2.nextthink = time; - else - bomb_1.nextthink = bomb_2.nextthink = time + autocvar_g_vehicle_raptor_bomblet_time; - - bomb_1.owner = bomb_2.owner = self; - bomb_1.realowner = bomb_2.realowner = self.owner; - bomb_1.solid = bomb_2.solid = SOLID_BBOX; - bomb_1.gravity = bomb_2.gravity = 1; - - PROJECTILE_MAKETRIGGER(bomb_1); - PROJECTILE_MAKETRIGGER(bomb_2); - - CSQCProjectile(bomb_1, TRUE, PROJECTILE_RAPTORBOMB, TRUE); - CSQCProjectile(bomb_2, TRUE, PROJECTILE_RAPTORBOMB, TRUE); -} - - -void raptor_fire_cannon(entity gun, string tagname) -{ - vehicles_projectile("raptor_cannon_muzzleflash", "weapons/lasergun_fire.wav", - gettaginfo(gun, gettagindex(gun, tagname)), normalize(v_forward + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed, - autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force, 0, - DEATH_VH_RAPT_CANNON, PROJECTILE_RAPTORCANNON, 0, TRUE, TRUE, self.owner); -} - -void raptor_think() -{ -} - -void raptor_enter() -{ - self.vehicle_weapon2mode = RSM_BOMB; - self.owner.PlayerPhysplug = raptor_takeoff; - self.movetype = MOVETYPE_BOUNCEMISSILE; - self.solid = SOLID_SLIDEBOX; - self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_raptor_health) * 100; - self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_raptor_shield) * 100; - self.velocity_z = 1; // Nudge upwards to takeoff sequense can work. - self.tur_head.exteriormodeltoclient = self.owner; - - self.delay = time + autocvar_g_vehicle_raptor_bombs_refire; - self.lip = time; - - if(self.owner.flagcarried) - setorigin(self.owner.flagcarried, '-20 0 96'); - - CSQCVehicleSetup(self.owner, 0); -} - -void raptor_land() -{ - float hgt; - - hgt = raptor_altitude(512); - self.velocity = (self.velocity * 0.9) + ('0 0 -1800' * (hgt / 256) * sys_frametime); - self.angles_x *= 0.95; - self.angles_z *= 0.95; - - if(hgt < 128) - if(hgt > 0) - self.frame = (hgt / 128) * 25; - - self.bomb1.gun1.avelocity_y = 90 + ((self.frame / 25) * 2000); - self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y; - - if(hgt < 16) - { - self.movetype = MOVETYPE_TOSS; - self.think = raptor_think; - self.frame = 0; - } - - self.nextthink = time; -} - -void raptor_exit(float eject) -{ - vector spot; - self.tur_head.exteriormodeltoclient = world; - - if(self.deadflag == DEAD_NO) - { - self.think = raptor_land; - self.nextthink = time; - } - - if not (self.owner) - return; - - makevectors(self.angles); - if(eject) - { - spot = self.origin + v_forward * 100 + '0 0 64'; - spot = vehicles_findgoodexit(spot); - setorigin(self.owner , spot); - self.owner.velocity = (v_up + v_forward * 0.25) * 750; - self.owner.oldvelocity = self.owner.velocity; - } - else - { - if(vlen(self.velocity) > 2 * autocvar_sv_maxairspeed) - { - self.owner.velocity = normalize(self.velocity) * autocvar_sv_maxairspeed * 2; - self.owner.velocity_z += 200; - spot = self.origin + v_forward * 32 + '0 0 64'; - spot = vehicles_findgoodexit(spot); - } - else - { - self.owner.velocity = self.velocity * 0.5; - self.owner.velocity_z += 10; - spot = self.origin - v_forward * 200 + '0 0 64'; - spot = vehicles_findgoodexit(spot); - } - self.owner.oldvelocity = self.owner.velocity; - setorigin(self.owner , spot); - } - - antilag_clear(self.owner); - self.owner = world; -} - -float raptor_takeoff() -{ - entity player, raptor; - - player = self; - raptor = self.vehicle; - self = raptor; - if(self.sound_nexttime < time) - { - self.sound_nexttime = time + 7.955812; //soundlength("vehicles/raptor_fly.wav"); - sound (self, CH_TRIGGER_SINGLE, "vehicles/raptor_speed.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - } - - // Takeoff sequense - if(raptor.frame < 25) - { - raptor.frame += 25 / (autocvar_g_vehicle_raptor_takeofftime / sys_frametime); - raptor.velocity_z = min(raptor.velocity_z * 1.5, 256); - self.bomb1.gun1.avelocity_y = 90 + ((raptor.frame / 25) * 25000); - self.bomb1.gun2.avelocity_y = -self.bomb1.gun1.avelocity_y; - player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0; - - setorigin(player, raptor.origin + '0 0 32'); - } - else - player.PlayerPhysplug = raptor_frame; - - if(self.vehicle_flags & VHF_SHIELDREGEN) - vehicles_regen(raptor.dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime, TRUE); - - if(self.vehicle_flags & VHF_HEALTHREGEN) - vehicles_regen(raptor.dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime, FALSE); - - if(self.vehicle_flags & VHF_ENERGYREGEN) - vehicles_regen(raptor.cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime, FALSE); - - - raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip); - player.vehicle_reload2 = bound(0, raptor.bomb1.alpha * 100, 100); - - VEHICLE_UPDATE_PLAYER(player, health, raptor); - VEHICLE_UPDATE_PLAYER(player, energy, raptor); - if(self.vehicle_flags & VHF_HASSHIELD) - VEHICLE_UPDATE_PLAYER(player, shield, raptor); - - player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0; - self = player; - return 1; -} - -void raptor_flare_touch() -{ - remove(self); -} - -void raptor_flare_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) -{ - self.health -= damage; - if(self.health <= 0) - remove(self); -} - -void raptor_flare_think() -{ - self.nextthink = time + 0.1; - entity _missile = findchainentity(enemy, self.owner); - while(_missile) - { - if(_missile.flags & FL_PROJECTILE) - if(vlen(self.origin - _missile.origin) < autocvar_g_vehicle_raptor_flare_range) - if(random() > autocvar_g_vehicle_raptor_flare_chase) - _missile.enemy = self; - _missile = _missile.chain; - } - - if(self.tur_impacttime < time) - remove(self); -} - -float raptor_frame() -{ - entity player, raptor; - float ftmp = 0; - vector df; - - if(intermission_running) - return 1; - - player = self; - raptor = self.vehicle; - self = raptor; - vehicles_painframe(); - /* - ftmp = vlen(self.velocity); - if(ftmp > autocvar_g_vehicle_raptor_speed_forward) - ftmp = 1; - else - ftmp = ftmp / autocvar_g_vehicle_raptor_speed_forward; - */ - - if(self.sound_nexttime < time) - { - self.sound_nexttime = time + 7.955812; - //sound (self.tur_head, CH_TRIGGER_SINGLE, "vehicles/raptor_fly.wav", 1 - ftmp, ATTEN_NORM ); - sound (self, CH_TRIGGER_SINGLE, "vehicles/raptor_speed.wav", 1, ATTEN_NORM); - self.wait = ftmp; - } - /* - else if(fabs(ftmp - self.wait) > 0.2) - { - sound (self.tur_head, CH_TRIGGER_SINGLE, "", 1 - ftmp, ATTEN_NORM ); - sound (self, CH_TRIGGER_SINGLE, "", ftmp, ATTEN_NORM); - self.wait = ftmp; - } - */ - - if(raptor.deadflag != DEAD_NO) - { - self = player; - player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; - return 1; - } - crosshair_trace(player); - - vector vang; - vang = raptor.angles; - df = vectoangles(normalize(trace_endpos - self.origin + '0 0 32')); - vang_x *= -1; - df_x *= -1; - if(df_x > 180) df_x -= 360; - if(df_x < -180) df_x += 360; - if(df_y > 180) df_y -= 360; - if(df_y < -180) df_y += 360; - - ftmp = shortangle_f(player.v_angle_y - vang_y, vang_y); - if(ftmp > 180) ftmp -= 360; if(ftmp < -180) ftmp += 360; - raptor.avelocity_y = bound(-autocvar_g_vehicle_raptor_turnspeed, ftmp + raptor.avelocity_y * 0.9, autocvar_g_vehicle_raptor_turnspeed); - - // Pitch - ftmp = 0; - if(player.movement_x > 0 && vang_x < autocvar_g_vehicle_raptor_pitchlimit) ftmp = 5; - else if(player.movement_x < 0 && vang_x > -autocvar_g_vehicle_raptor_pitchlimit) ftmp = -20; - - df_x = bound(-autocvar_g_vehicle_raptor_pitchlimit, df_x , autocvar_g_vehicle_raptor_pitchlimit); - ftmp = vang_x - bound(-autocvar_g_vehicle_raptor_pitchlimit, df_x + ftmp, autocvar_g_vehicle_raptor_pitchlimit); - raptor.avelocity_x = bound(-autocvar_g_vehicle_raptor_pitchspeed, ftmp + raptor.avelocity_x * 0.9, autocvar_g_vehicle_raptor_pitchspeed); - - raptor.angles_x = anglemods(raptor.angles_x); - raptor.angles_y = anglemods(raptor.angles_y); - raptor.angles_z = anglemods(raptor.angles_z); - - if(autocvar_g_vehicle_raptor_movestyle == 1) - makevectors('0 1 0' * raptor.angles_y); - else - makevectors(player.v_angle); - - df = raptor.velocity * -autocvar_g_vehicle_raptor_friction; - - if(player.movement_x != 0) - { - if(player.movement_x > 0) - df += v_forward * autocvar_g_vehicle_raptor_speed_forward; - else if(player.movement_x < 0) - df -= v_forward * autocvar_g_vehicle_raptor_speed_forward; - } - - if(player.movement_y != 0) - { - if(player.movement_y < 0) - df -= v_right * autocvar_g_vehicle_raptor_speed_strafe; - else if(player.movement_y > 0) - df += v_right * autocvar_g_vehicle_raptor_speed_strafe; - - raptor.angles_z = bound(-30,raptor.angles_z + (player.movement_y / autocvar_g_vehicle_raptor_speed_strafe),30); - } - else - { - raptor.angles_z *= 0.95; - if(raptor.angles_z >= -1 && raptor.angles_z <= -1) - raptor.angles_z = 0; - } - - if(player.BUTTON_CROUCH) - df -= v_up * autocvar_g_vehicle_raptor_speed_down; - else if (player.BUTTON_JUMP) - df += v_up * autocvar_g_vehicle_raptor_speed_up; - - raptor.velocity += df * frametime; - player.velocity = player.movement = raptor.velocity; - setorigin(player, raptor.origin + '0 0 32'); - - vector vf, ad; - // Target lock & predict - if(autocvar_g_vehicle_raptor_cannon_locktarget == 2) - { - if(raptor.gun1.lock_time < time || raptor.gun1.enemy.deadflag) - raptor.gun1.enemy = world; - - if(trace_ent) - if(trace_ent.movetype) - if(trace_ent.takedamage) - if(!trace_ent.deadflag) - { - if(teamplay) - { - if(trace_ent.team != player.team) - { - raptor.gun1.enemy = trace_ent; - raptor.gun1.lock_time = time + 5; - } - } - else - { - raptor.gun1.enemy = trace_ent; - raptor.gun1.lock_time = time + 0.5; - } - } - - if(raptor.gun1.enemy) - { - float i, distance, impact_time; - - vf = real_origin(raptor.gun1.enemy); - UpdateAuxiliaryXhair(player, vf, '1 0 0', 1); - vector _vel = raptor.gun1.enemy.velocity; - if(raptor.gun1.enemy.movetype == MOVETYPE_WALK) - _vel_z *= 0.1; - - if(autocvar_g_vehicle_raptor_cannon_predicttarget) - { - ad = vf; - for(i = 0; i < 4; ++i) - { - distance = vlen(ad - player.origin); - impact_time = distance / autocvar_g_vehicle_raptor_cannon_speed; - ad = vf + _vel * impact_time; - } - trace_endpos = ad; - } - else - trace_endpos = vf; - } - } - else if(autocvar_g_vehicle_raptor_cannon_locktarget == 1) - { - - vehicles_locktarget((1 / autocvar_g_vehicle_raptor_cannon_locking_time) * frametime, - (1 / autocvar_g_vehicle_raptor_cannon_locking_releasetime) * frametime, - autocvar_g_vehicle_raptor_cannon_locked_time); - - if(self.lock_target != world) - if(autocvar_g_vehicle_raptor_cannon_predicttarget) - if(self.lock_strength == 1) - { - float i, distance, impact_time; - - vf = real_origin(raptor.lock_target); - ad = vf; - for(i = 0; i < 4; ++i) - { - distance = vlen(ad - raptor.origin); - impact_time = distance / autocvar_g_vehicle_raptor_cannon_speed; - ad = vf + raptor.lock_target.velocity * impact_time; - } - trace_endpos = ad; - } - - if(self.lock_target) - { - if(raptor.lock_strength == 1) - UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '1 0 0', 1); - else if(self.lock_strength > 0.5) - UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '0 1 0', 1); - else if(self.lock_strength < 0.5) - UpdateAuxiliaryXhair(player, real_origin(raptor.lock_target), '0 0 1', 1); - } - } - - - vehicle_aimturret(raptor, trace_endpos, raptor.gun1, "fire1", - autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1, autocvar_g_vehicle_raptor_cannon_pitchlimit_up, - autocvar_g_vehicle_raptor_cannon_turnlimit * -1, autocvar_g_vehicle_raptor_cannon_turnlimit, autocvar_g_vehicle_raptor_cannon_turnspeed); - - vehicle_aimturret(raptor, trace_endpos, raptor.gun2, "fire1", - autocvar_g_vehicle_raptor_cannon_pitchlimit_down * -1, autocvar_g_vehicle_raptor_cannon_pitchlimit_up, - autocvar_g_vehicle_raptor_cannon_turnlimit * -1, autocvar_g_vehicle_raptor_cannon_turnlimit, autocvar_g_vehicle_raptor_cannon_turnspeed); - - /* - ad = ad * 0.5; - v_forward = vf * 0.5; - traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, raptor); - UpdateAuxiliaryXhair(player, trace_endpos, '0 1 0', 0); - */ - - if(player.BUTTON_ATCK) - if(raptor.attack_finished_single <= time) - if(raptor.vehicle_energy > autocvar_g_vehicle_raptor_cannon_cost) - { - raptor.misc_bulletcounter += 1; - raptor.attack_finished_single = time + autocvar_g_vehicle_raptor_cannon_refire; - if(raptor.misc_bulletcounter <= 2) - raptor_fire_cannon(self.gun1, "fire1"); - else if(raptor.misc_bulletcounter == 3) - raptor_fire_cannon(self.gun2, "fire1"); - else - { - raptor.attack_finished_single = time + autocvar_g_vehicle_raptor_cannon_refire * 2; - raptor_fire_cannon(self.gun2, "fire1"); - raptor.misc_bulletcounter = 0; - } - raptor.vehicle_energy -= autocvar_g_vehicle_raptor_cannon_cost; - self.cnt = time; - } - - if(self.vehicle_flags & VHF_SHIELDREGEN) - vehicles_regen(raptor.dmg_time, vehicle_shield, autocvar_g_vehicle_raptor_shield, autocvar_g_vehicle_raptor_shield_regen_pause, autocvar_g_vehicle_raptor_shield_regen, frametime, TRUE); - - if(self.vehicle_flags & VHF_HEALTHREGEN) - vehicles_regen(raptor.dmg_time, vehicle_health, autocvar_g_vehicle_raptor_health, autocvar_g_vehicle_raptor_health_regen_pause, autocvar_g_vehicle_raptor_health_regen, frametime, FALSE); - - if(self.vehicle_flags & VHF_ENERGYREGEN) - vehicles_regen(raptor.cnt, vehicle_energy, autocvar_g_vehicle_raptor_energy, autocvar_g_vehicle_raptor_energy_regen_pause, autocvar_g_vehicle_raptor_energy_regen, frametime, FALSE); - - if(raptor.vehicle_weapon2mode == RSM_BOMB) - { - if(time > raptor.lip + autocvar_g_vehicle_raptor_bombs_refire) - if(player.BUTTON_ATCK2) - { - raptor_bombdrop(); - raptor.delay = time + autocvar_g_vehicle_raptor_bombs_refire; - raptor.lip = time; - } - } - else - { - if(time > raptor.lip + autocvar_g_vehicle_raptor_flare_refire) - if(player.BUTTON_ATCK2) - { - float i; - entity _flare; - - for(i = 0; i < 3; ++i) - { - _flare = spawn(); - setmodel(_flare, "models/runematch/rune.mdl"); - _flare.effects = EF_LOWPRECISION | EF_FLAME; - _flare.scale = 0.5; - setorigin(_flare, self.origin - '0 0 16'); - _flare.movetype = MOVETYPE_TOSS; - _flare.gravity = 0.15; - _flare.velocity = 0.25 * raptor.velocity + (v_forward + randomvec() * 0.25)* -500; - _flare.think = raptor_flare_think; - _flare.nextthink = time; - _flare.owner = raptor; - _flare.solid = SOLID_CORPSE; - _flare.takedamage = DAMAGE_YES; - _flare.event_damage = raptor_flare_damage; - _flare.health = 20; - _flare.tur_impacttime = time + autocvar_g_vehicle_raptor_flare_lifetime; - _flare.touch = raptor_flare_touch; - } - raptor.delay = time + autocvar_g_vehicle_raptor_flare_refire; - raptor.lip = time; - } - } - - raptor.bomb1.alpha = raptor.bomb2.alpha = (time - raptor.lip) / (raptor.delay - raptor.lip); - player.vehicle_reload2 = bound(0, raptor.bomb1.alpha * 100, 100); - - if(self.bomb1.cnt < time) - { - entity _missile = findchainentity(enemy, raptor); - float _incomming = 0; - while(_missile) - { - if(_missile.flags & FL_PROJECTILE) - if(MISSILE_IS_TRACKING(_missile)) - if(vlen(self.origin - _missile.origin) < 2 * autocvar_g_vehicle_raptor_flare_range) - ++_incomming; - - _missile = _missile.chain; - } - - if(_incomming) - sound(self, CH_PAIN_SINGLE, "vehicles/missile_alarm.wav", VOL_BASE, ATTEN_NONE); - - self.bomb1.cnt = time + 1; - } - - - VEHICLE_UPDATE_PLAYER(player, health, raptor); - VEHICLE_UPDATE_PLAYER(player, energy, raptor); - if(self.vehicle_flags & VHF_HASSHIELD) - VEHICLE_UPDATE_PLAYER(player, shield, raptor); - - player.BUTTON_ATCK = player.BUTTON_ATCK2 = player.BUTTON_CROUCH = 0; - - self = player; - return 1; -} - -void raptor_blowup() -{ - self.deadflag = DEAD_DEAD; - self.vehicle_exit(VHEF_NORMAL); - RadiusDamage (self, self.enemy, 250, 15, 250, world, 250, DEATH_VH_RAPT_DEATH, world); - - self.alpha = -1; - self.movetype = MOVETYPE_NONE; - self.effects = EF_NODRAW; - self.colormod = '0 0 0'; - self.avelocity = '0 0 0'; - self.velocity = '0 0 0'; - - setorigin(self, self.pos1); - self.touch = func_null; - self.nextthink = 0; -} - -void raptor_diethink() -{ - if(time >= self.wait) - self.think = raptor_blowup; - - if(random() < 0.1) - { - sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); - } - self.nextthink = time + 0.1; -} - -void raptor_die() -{ - self.health = 0; - self.event_damage = func_null; - self.solid = SOLID_CORPSE; - self.takedamage = DAMAGE_NO; - self.deadflag = DEAD_DYING; - self.movetype = MOVETYPE_BOUNCE; - self.think = raptor_diethink; - self.nextthink = time; - self.wait = time + 5 + (random() * 5); - - pointparticles(particleeffectnum("explosion_medium"), findbetterlocation (self.origin, 16), '0 0 0', 1); - - self.velocity_z += 600; - - self.avelocity = '0 0.5 1' * (random() * 400); - self.avelocity -= '0 0.5 1' * (random() * 400); - - self.colormod = '-0.5 -0.5 -0.5'; - self.touch = raptor_blowup; -} - -void raptor_impact() -{ - if(autocvar_g_vehicle_raptor_bouncepain_x) - vehilces_impact(autocvar_g_vehicle_raptor_bouncepain_x, autocvar_g_vehicle_raptor_bouncepain_y, autocvar_g_vehicle_raptor_bouncepain_z); -} - -// If we dont do this ever now and then, the raptors rotors -// stop working, presumably due to angle overflow. cute. -void raptor_rotor_anglefix() -{ - self.gun1.angles_y = anglemods(self.gun1.angles_y); - self.gun2.angles_y = anglemods(self.gun2.angles_y); - self.nextthink = time + 15; -} - -float raptor_impulse(float _imp) -{ - switch(_imp) - { - case 10: - case 15: - case 18: - self.vehicle.vehicle_weapon2mode += 1; - if(self.vehicle.vehicle_weapon2mode > RSM_LAST) - self.vehicle.vehicle_weapon2mode = RSM_FIRST; - - CSQCVehicleSetup(self, 0); - return TRUE; - case 12: - case 16: - case 19: - self.vehicle.vehicle_weapon2mode -= 1; - if(self.vehicle.vehicle_weapon2mode < RSM_FIRST) - self.vehicle.vehicle_weapon2mode = RSM_LAST; - - CSQCVehicleSetup(self, 0); - return TRUE; - - /* - case 17: // toss gun, could be used to exit? - break; - case 20: // Manual minigun reload? - break; - */ - } - return FALSE; -} - -void raptor_spawn(float _f) -{ - if(!self.gun1) - { - entity spinner; - vector ofs; - - //FIXME: Camera is in a bad place in HUD model. - //setorigin(self.vehicle_viewport, '25 0 5'); - - self.vehicles_impusle = raptor_impulse; - - self.frame = 0; - - self.bomb1 = spawn(); - self.bomb2 = spawn(); - self.gun1 = spawn(); - self.gun2 = spawn(); - - setmodel(self.bomb1,"models/vehicles/clusterbomb_folded.md3"); - setmodel(self.bomb2,"models/vehicles/clusterbomb_folded.md3"); - setmodel(self.gun1, "models/vehicles/raptor_gun.dpm"); - setmodel(self.gun2, "models/vehicles/raptor_gun.dpm"); - setmodel(self.tur_head, "models/vehicles/raptor_body.dpm"); - - setattachment(self.bomb1, self, "bombmount_left"); - setattachment(self.bomb2, self, "bombmount_right"); - setattachment(self.tur_head, self,"root"); - - // FIXMODEL Guns mounts to angled bones - self.bomb1.angles = self.angles; - self.angles = '0 0 0'; - // This messes up gun-aim, so work arround it. - //setattachment(self.gun1, self, "gunmount_left"); - ofs = gettaginfo(self, gettagindex(self, "gunmount_left")); - ofs -= self.origin; - setattachment(self.gun1, self, ""); - setorigin(self.gun1, ofs); - - //setattachment(self.gun2, self, "gunmount_right"); - ofs = gettaginfo(self, gettagindex(self, "gunmount_right")); - ofs -= self.origin; - setattachment(self.gun2, self, ""); - setorigin(self.gun2, ofs); - - self.angles = self.bomb1.angles; - self.bomb1.angles = '0 0 0'; - - spinner = spawn(); - spinner.owner = self; - setmodel(spinner,"models/vehicles/spinner.dpm"); - setattachment(spinner, self, "engine_left"); - spinner.movetype = MOVETYPE_NOCLIP; - spinner.avelocity = '0 90 0'; - self.bomb1.gun1 = spinner; - - spinner = spawn(); - spinner.owner = self; - setmodel(spinner,"models/vehicles/spinner.dpm"); - setattachment(spinner, self, "engine_right"); - spinner.movetype = MOVETYPE_NOCLIP; - spinner.avelocity = '0 -90 0'; - self.bomb1.gun2 = spinner; - - // Sigh. - self.bomb1.think = raptor_rotor_anglefix; - self.bomb1.nextthink = time; - - self.mass = 1 ; - } - - - self.frame = 0; - self.vehicle_health = autocvar_g_vehicle_raptor_health; - self.vehicle_shield = autocvar_g_vehicle_raptor_shield; - self.movetype = MOVETYPE_TOSS; - self.solid = SOLID_SLIDEBOX; - self.vehicle_energy = 1; - - self.bomb1.gun1.avelocity_y = 90; - self.bomb1.gun2.avelocity_y = -90; - - setsize(self, RAPTOR_MIN, RAPTOR_MAX ); - self.delay = time; - - self.bouncefactor = autocvar_g_vehicle_raptor_bouncefactor; - self.bouncestop = autocvar_g_vehicle_raptor_bouncestop; - self.vehicle_impact = raptor_impact; - self.damageforcescale = 0.25; -} - -void spawnfunc_vehicle_raptor() -{ - if(!autocvar_g_vehicle_raptor) - { - remove(self); - return; - } - - self.vehicle_flags |= VHF_DMGSHAKE; - self.vehicle_flags |= VHF_DMGROLL; - - if(autocvar_g_vehicle_raptor_shield) - self.vehicle_flags |= VHF_HASSHIELD; - - if(autocvar_g_vehicle_raptor_shield_regen) - self.vehicle_flags |= VHF_SHIELDREGEN; - - if(autocvar_g_vehicle_raptor_health_regen) - self.vehicle_flags |= VHF_HEALTHREGEN; - - if(autocvar_g_vehicle_raptor_energy_regen) - self.vehicle_flags |= VHF_ENERGYREGEN; - - precache_model ("models/vehicles/raptor.dpm"); - precache_model ("models/vehicles/raptor_gun.dpm"); - precache_model ("models/vehicles/spinner.dpm"); - precache_model ("models/vehicles/raptor_cockpit.dpm"); - //precache_model ("models/vehicles/clusterbomb.md3"); - precache_model ("models/vehicles/clusterbomb_folded.md3"); - precache_model ("models/vehicles/raptor_body.dpm"); - - precache_sound ("vehicles/raptor_fly.wav"); - precache_sound ("vehicles/raptor_speed.wav"); - precache_sound ("vehicles/missile_alarm.wav"); - - if not (vehicle_initialize( - "Raptor", - "models/vehicles/raptor.dpm", - "", - "models/vehicles/raptor_cockpit.dpm", - "", "tag_hud", "tag_camera", - HUD_RAPTOR, - RAPTOR_MIN, RAPTOR_MAX, - FALSE, - raptor_spawn, autocvar_g_vehicle_raptor_respawntime, - raptor_frame, - raptor_enter, raptor_exit, - raptor_die, raptor_think, - FALSE, - autocvar_g_vehicle_raptor_health, - autocvar_g_vehicle_raptor_shield)) - { - remove(self); - return; - } - - -} -#endif // SVQC diff --git a/qcsrc/server/vehicles/spiderbot.qc b/qcsrc/server/vehicles/spiderbot.qc deleted file mode 100644 index 9dc41952f3..0000000000 --- a/qcsrc/server/vehicles/spiderbot.qc +++ /dev/null @@ -1,879 +0,0 @@ -const vector SPIDERBOT_MIN = '-75 -75 10'; -const vector SPIDERBOT_MAX = '75 75 125'; - -#ifdef SVQC -float autocvar_g_vehicle_spiderbot; - -float autocvar_g_vehicle_spiderbot_respawntime; - -float autocvar_g_vehicle_spiderbot_speed_stop; -float autocvar_g_vehicle_spiderbot_speed_strafe; -float autocvar_g_vehicle_spiderbot_speed_walk; -float autocvar_g_vehicle_spiderbot_turnspeed; -float autocvar_g_vehicle_spiderbot_turnspeed_strafe; -float autocvar_g_vehicle_spiderbot_movement_inertia; - -float autocvar_g_vehicle_spiderbot_springlength; -float autocvar_g_vehicle_spiderbot_springup; -float autocvar_g_vehicle_spiderbot_springblend; -float autocvar_g_vehicle_spiderbot_tiltlimit; - -float autocvar_g_vehicle_spiderbot_head_pitchlimit_down; -float autocvar_g_vehicle_spiderbot_head_pitchlimit_up; -float autocvar_g_vehicle_spiderbot_head_turnlimit; -float autocvar_g_vehicle_spiderbot_head_turnspeed; - -//float autocvar_g_vehicle_spiderbot_energy; -//float autocvar_g_vehicle_spiderbot_energy_regen; -//float autocvar_g_vehicle_spiderbot_energy_regen_pause; - -float autocvar_g_vehicle_spiderbot_health; -float autocvar_g_vehicle_spiderbot_health_regen; -float autocvar_g_vehicle_spiderbot_health_regen_pause; - -float autocvar_g_vehicle_spiderbot_shield; -float autocvar_g_vehicle_spiderbot_shield_regen; -float autocvar_g_vehicle_spiderbot_shield_regen_pause; - -float autocvar_g_vehicle_spiderbot_minigun_damage; -float autocvar_g_vehicle_spiderbot_minigun_refire; -float autocvar_g_vehicle_spiderbot_minigun_spread; -float autocvar_g_vehicle_spiderbot_minigun_ammo_cost; -float autocvar_g_vehicle_spiderbot_minigun_ammo_max; -float autocvar_g_vehicle_spiderbot_minigun_ammo_regen; -float autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause; -float autocvar_g_vehicle_spiderbot_minigun_force; -float autocvar_g_vehicle_spiderbot_minigun_speed; -float autocvar_g_vehicle_spiderbot_minigun_bulletconstant; - -float autocvar_g_vehicle_spiderbot_rocket_damage; -float autocvar_g_vehicle_spiderbot_rocket_force; -float autocvar_g_vehicle_spiderbot_rocket_radius; -float autocvar_g_vehicle_spiderbot_rocket_speed; -float autocvar_g_vehicle_spiderbot_rocket_spread; -float autocvar_g_vehicle_spiderbot_rocket_refire; -float autocvar_g_vehicle_spiderbot_rocket_refire2; -float autocvar_g_vehicle_spiderbot_rocket_reload; -float autocvar_g_vehicle_spiderbot_rocket_health; -float autocvar_g_vehicle_spiderbot_rocket_noise; -float autocvar_g_vehicle_spiderbot_rocket_turnrate; -float autocvar_g_vehicle_spiderbot_rocket_lifetime; - -vector autocvar_g_vehicle_spiderbot_bouncepain; - - -void spiderbot_exit(float eject); -void spiderbot_enter(); -void spiderbot_spawn(float); -#define SBRM_FIRST 0 -#define SBRM_VOLLY 0 -#define SBRM_GUIDE 1 -#define SBRM_ARTILLERY 2 -#define SBRM_LAST 2 - -void spiderbot_rocket_artillery() -{ - self.nextthink = time; - UpdateCSQCProjectile(self); -} - -void spiderbot_rocket_unguided() -{ - vector newdir, olddir; - - self.nextthink = time; - - olddir = normalize(self.velocity); - newdir = normalize(self.pos1 - self.origin) + randomvec() * autocvar_g_vehicle_spiderbot_rocket_noise; - self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_spiderbot_rocket_turnrate) * autocvar_g_vehicle_spiderbot_rocket_speed; - - UpdateCSQCProjectile(self); - - if (self.owner.deadflag != DEAD_NO || self.cnt < time || vlen(self.pos1 - self.origin) < 16) - self.use(); -} - -void spiderbot_rocket_guided() -{ - vector newdir, olddir; - - self.nextthink = time; - - if not (self.realowner.vehicle) - self.think = spiderbot_rocket_unguided; - - crosshair_trace(self.realowner); - olddir = normalize(self.velocity); - newdir = normalize(trace_endpos - self.origin) + randomvec() * autocvar_g_vehicle_spiderbot_rocket_noise; - self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_spiderbot_rocket_turnrate) * autocvar_g_vehicle_spiderbot_rocket_speed; - - UpdateCSQCProjectile(self); - - if (self.owner.deadflag != DEAD_NO || self.cnt < time) - self.use(); -} - -void spiderbot_guide_release() -{ - entity rkt; - rkt = findchainentity(realowner, self.owner); - if not (rkt) - return; - - crosshair_trace(self.owner); - while(rkt) - { - if(rkt.think == spiderbot_rocket_guided) - { - rkt.pos1 = trace_endpos; - rkt.think = spiderbot_rocket_unguided; - } - rkt = rkt.chain; - } -} - -float spiberbot_calcartillery_flighttime; -vector spiberbot_calcartillery(vector org, vector tgt, float ht) -{ - float grav, sdist, zdist, vs, vz, jumpheight; - vector sdir; - - grav = autocvar_sv_gravity; - zdist = tgt_z - org_z; - sdist = vlen(tgt - org - zdist * '0 0 1'); - sdir = normalize(tgt - org - zdist * '0 0 1'); - - // how high do we need to go? - jumpheight = fabs(ht); - if(zdist > 0) - jumpheight = jumpheight + zdist; - - // push so high... - vz = sqrt(2 * grav * jumpheight); // NOTE: sqrt(positive)! - - // we start with downwards velocity only if it's a downjump and the jump apex should be outside the jump! - if(ht < 0) - if(zdist < 0) - vz = -vz; - - vector solution; - solution = solve_quadratic(0.5 * grav, -vz, zdist); // equation "z(ti) = zdist" - // ALWAYS solvable because jumpheight >= zdist - if(!solution_z) - solution_y = solution_x; // just in case it is not solvable due to roundoff errors, assume two equal solutions at their center (this is mainly for the usual case with ht == 0) - if(zdist == 0) - solution_x = solution_y; // solution_x is 0 in this case, so don't use it, but rather use solution_y (which will be sqrt(0.5 * jumpheight / grav), actually) - - if(zdist < 0) - { - // down-jump - if(ht < 0) - { - // almost straight line type - // jump apex is before the jump - // we must take the larger one - spiberbot_calcartillery_flighttime = solution_y; - } - else - { - // regular jump - // jump apex is during the jump - // we must take the larger one too - spiberbot_calcartillery_flighttime = solution_y; - } - } - else - { - // up-jump - if(ht < 0) - { - // almost straight line type - // jump apex is after the jump - // we must take the smaller one - spiberbot_calcartillery_flighttime = solution_x; - } - else - { - // regular jump - // jump apex is during the jump - // we must take the larger one - spiberbot_calcartillery_flighttime = solution_y; - } - } - vs = sdist / spiberbot_calcartillery_flighttime; - - // finally calculate the velocity - return sdir * vs + '0 0 1' * vz; -} - -void spiderbot_rocket_do() -{ - - vector v; - entity rocket = world; - - if (self.wait != -10) - { - if (self.owner.BUTTON_ATCK2 && self.vehicle_weapon2mode == SBRM_GUIDE) - { - if (self.wait == 1) - if (self.tur_head.frame == 9 || self.tur_head.frame == 1) - { - if(self.gun2.cnt < time && self.tur_head.frame == 9) - self.tur_head.frame = 1; - - return; - } - self.wait = 1; - } - else - { - if(self.wait) - spiderbot_guide_release(); - - self.wait = 0; - } - } - - if(self.gun2.cnt > time) - return; - - if (self.tur_head.frame >= 9) - { - self.tur_head.frame = 1; - self.wait = 0; - } - - if (self.wait != -10) - if not (self.owner.BUTTON_ATCK2) - return; - - - v = gettaginfo(self.tur_head,gettagindex(self.tur_head,"tag_fire")); - - switch(self.vehicle_weapon2mode) - { - case SBRM_VOLLY: - rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav", - v, normalize(randomvec() * autocvar_g_vehicle_spiderbot_rocket_spread + v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed, - autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1, - DEATH_VH_SPID_ROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, TRUE, self.owner); - crosshair_trace(self.owner); - float _dist = (random() * autocvar_g_vehicle_spiderbot_rocket_radius) + vlen(v - trace_endpos); - _dist -= (random() * autocvar_g_vehicle_spiderbot_rocket_radius) ; - rocket.nextthink = time + (_dist / autocvar_g_vehicle_spiderbot_rocket_speed); - rocket.think = vehicles_projectile_explode; - - if(self.owner.BUTTON_ATCK2 && self.tur_head.frame == 1) - self.wait = -10; - break; - case SBRM_GUIDE: - rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav", - v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed, - autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1, - DEATH_VH_SPID_ROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, FALSE, self.owner); - crosshair_trace(self.owner); - rocket.pos1 = trace_endpos; - rocket.nextthink = time; - rocket.think = spiderbot_rocket_guided; - - - break; - case SBRM_ARTILLERY: - rocket = vehicles_projectile("spiderbot_rocket_launch", "weapons/rocket_fire.wav", - v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed, - autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1, - DEATH_VH_SPID_ROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, FALSE, TRUE, self.owner); - - crosshair_trace(self.owner); - - rocket.pos1 = trace_endpos + randomvec() * (0.75 * autocvar_g_vehicle_spiderbot_rocket_radius); - rocket.pos1_z = trace_endpos_z; - - traceline(v, v + '0 0 1' * MAX_SHOT_DISTANCE, MOVE_WORLDONLY, self); - float h1 = 0.75 * vlen(v - trace_endpos); - - //v = trace_endpos; - traceline(v , rocket.pos1 + '0 0 1' * MAX_SHOT_DISTANCE, MOVE_WORLDONLY, self); - float h2 = 0.75 * vlen(rocket.pos1 - v); - - rocket.velocity = spiberbot_calcartillery(v, rocket.pos1, ((h1 < h2) ? h1 : h2)); - rocket.movetype = MOVETYPE_TOSS; - rocket.gravity = 1; - //rocket.think = spiderbot_rocket_artillery; - break; - } - rocket.classname = "spiderbot_rocket"; - - rocket.cnt = time + autocvar_g_vehicle_spiderbot_rocket_lifetime; - - self.tur_head.frame += 1; - if (self.tur_head.frame == 9) - self.attack_finished_single = autocvar_g_vehicle_spiderbot_rocket_reload; - else - self.attack_finished_single = ((self.vehicle_weapon2mode == SBRM_VOLLY) ? autocvar_g_vehicle_spiderbot_rocket_refire2 : autocvar_g_vehicle_spiderbot_rocket_refire); - - self.gun2.cnt = time + self.attack_finished_single; -} - -float spiderbot_aiframe() -{ - return FALSE; -} - -float spiderbot_frame() -{ - vector ad, vf; - entity player, spider; - float ftmp; - - if(intermission_running) - return 1; - - player = self; - spider = self.vehicle; - self = spider; - - vehicles_painframe(); - - player.BUTTON_ZOOM = 0; - player.BUTTON_CROUCH = 0; - player.switchweapon = 0; - - -#if 1 // 0 to enable per-gun impact aux crosshairs - // Avarage gun impact point's -> aux cross - ad = gettaginfo(spider.tur_head, gettagindex(spider.tur_head, "tag_hardpoint01")); - vf = v_forward; - ad += gettaginfo(spider.tur_head, gettagindex(spider.tur_head, "tag_hardpoint02")); - vf += v_forward; - ad = ad * 0.5; - v_forward = vf * 0.5; - traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, spider); - UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload1) + ('0 1 0' * (1 - player.vehicle_reload1)), 0); -#else - ad = gettaginfo(spider.gun1, gettagindex(spider.gun1, "barrels")); - traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, spider); - UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload1) + ('0 1 0' * (1 - player.vehicle_reload1)), 0); - vf = ad; - ad = gettaginfo(spider.gun2, gettagindex(spider.gun2, "barrels")); - traceline(ad, ad + v_forward * MAX_SHOT_DISTANCE, MOVE_NORMAL, spider); - UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload1) + ('0 1 0' * (1 - player.vehicle_reload1)), 1); - ad = 0.5 * (ad + vf); -#endif - - crosshair_trace(player); - ad = vectoangles(normalize(trace_endpos - ad)); - ad = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(spider.angles), AnglesTransform_FromAngles(ad))) - spider.tur_head.angles; - ad = AnglesTransform_Normalize(ad, TRUE); - //UpdateAuxiliaryXhair(player, trace_endpos, ('1 0 0' * player.vehicle_reload2) + ('0 1 0' * (1 - player.vehicle_reload2)), 2); - - // Rotate head - ftmp = autocvar_g_vehicle_spiderbot_head_turnspeed * sys_frametime; - ad_y = bound(-ftmp, ad_y, ftmp); - spider.tur_head.angles_y = bound(autocvar_g_vehicle_spiderbot_head_turnlimit * -1, spider.tur_head.angles_y + ad_y, autocvar_g_vehicle_spiderbot_head_turnlimit); - - // Pitch head - ad_x = bound(ftmp * -1, ad_x, ftmp); - spider.tur_head.angles_x = bound(autocvar_g_vehicle_spiderbot_head_pitchlimit_down, spider.tur_head.angles_x + ad_x, autocvar_g_vehicle_spiderbot_head_pitchlimit_up); - - - //fixedmakevectors(spider.angles); - makevectors(spider.angles + '-2 0 0' * spider.angles_x); - - movelib_groundalign4point(autocvar_g_vehicle_spiderbot_springlength, autocvar_g_vehicle_spiderbot_springup, autocvar_g_vehicle_spiderbot_springblend, autocvar_g_vehicle_spiderbot_tiltlimit); - - if(spider.flags & FL_ONGROUND) - { - if(spider.frame == 4 && self.tur_head.wait != 0) - { - sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_land.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - spider.frame = 5; - } - - if(player.BUTTON_JUMP && self.tur_head.wait < time) - { - sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_jump.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - //dprint("spiderbot_jump:", ftos(soundlength("vehicles/spiderbot_jump.wav")), "\n"); - self.delay = 0; - - self.tur_head.wait = time + 2; - player.BUTTON_JUMP = 0; - spider.velocity = v_forward * 700 + v_up * 600; - spider.frame = 4; - } - else - { - if(vlen(player.movement) == 0) - { - if(self.sound_nexttime < time || self.delay != 3) - { - self.delay = 3; - self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_idle.wav"); - //dprint("spiderbot_idle:", ftos(soundlength("vehicles/spiderbot_idle.wav")), "\n"); - sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_idle.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - } - movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop); - spider.frame = 5; - } - else - { - // Turn Body - if(player.movement_x == 0 && player.movement_y != 0) - ftmp = autocvar_g_vehicle_spiderbot_turnspeed_strafe * sys_frametime; - else - ftmp = autocvar_g_vehicle_spiderbot_turnspeed * sys_frametime; - - ftmp = bound(-ftmp, spider.tur_head.angles_y, ftmp); - spider.angles_y = anglemods(spider.angles_y + ftmp); - spider.tur_head.angles_y -= ftmp; - - if(player.movement_x != 0) - { - if(player.movement_x > 0) - { - player.movement_x = 1; - spider.frame = 0; - } - else if(player.movement_x < 0) - { - player.movement_x = -1; - spider.frame = 1; - } - player.movement_y = 0; - movelib_move_simple(normalize(v_forward * player.movement_x),autocvar_g_vehicle_spiderbot_speed_walk,autocvar_g_vehicle_spiderbot_movement_inertia); - - if(self.sound_nexttime < time || self.delay != 1) - { - self.delay = 1; - self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_walk.wav"); - sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_walk.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - //dprint("spiderbot_walk:", ftos(soundlength("vehicles/spiderbot_walk.wav")), "\n"); - } - } - else if(player.movement_y != 0) - { - if(player.movement_y < 0) - { - player.movement_y = -1; - spider.frame = 2; - } - else if(player.movement_y > 0) - { - player.movement_y = 1; - spider.frame = 3; - } - movelib_move_simple(normalize(v_right * player.movement_y),autocvar_g_vehicle_spiderbot_speed_strafe,autocvar_g_vehicle_spiderbot_movement_inertia); - if(self.sound_nexttime < time || self.delay != 2) - { - self.delay = 2; - self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_strafe.wav"); - sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_strafe.wav", VOL_VEHICLEENGINE, ATTEN_NORM); - //dprint("spiderbot_strafe:", ftos(soundlength("vehicles/spiderbot_strafe.wav")), "\n"); - } - } - } - } - } - - self.angles_x = bound(-autocvar_g_vehicle_spiderbot_tiltlimit, self.angles_x, autocvar_g_vehicle_spiderbot_tiltlimit); - self.angles_z = bound(-autocvar_g_vehicle_spiderbot_tiltlimit, self.angles_z, autocvar_g_vehicle_spiderbot_tiltlimit); - - if(player.BUTTON_ATCK) - { - spider.cnt = time; - if(spider.vehicle_ammo1 >= autocvar_g_vehicle_spiderbot_minigun_ammo_cost && spider.tur_head.attack_finished_single <= time) - { - entity gun; - vector v; - spider.misc_bulletcounter += 1; - - self = player; - - mod(spider.misc_bulletcounter, 2) ? gun = spider.gun1 : gun = spider.gun2; - v = gettaginfo(gun, gettagindex(gun, "barrels")); - v_forward = normalize(v_forward); - v += v_forward * 50; - -//void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, float lifetime, float damage, float force, float dtype, float tracereffects, float gravityfactor, float bulletconstant) - - fireBallisticBullet(v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_speed, - 5, autocvar_g_vehicle_spiderbot_minigun_damage, autocvar_g_vehicle_spiderbot_minigun_force, DEATH_VH_SPID_MINIGUN, 0, 1, autocvar_g_vehicle_spiderbot_minigun_bulletconstant); - - endFireBallisticBullet(); - -// fireBullet (v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_damage, -// autocvar_g_vehicle_spiderbot_minigun_spread, DEATH_VH_SPID_MINIGUN, 0); - - sound (gun, CH_WEAPON_A, "weapons/uzi_fire.wav", VOL_BASE, ATTEN_NORM); - //trailparticles(self, particleeffectnum("spiderbot_minigun_trail"), v, trace_endpos); - pointparticles(particleeffectnum("spiderbot_minigun_muzzleflash"), v, v_forward * 2500, 1); - - self = spider; - - spider.vehicle_ammo1 -= autocvar_g_vehicle_spiderbot_minigun_ammo_cost; - spider.tur_head.attack_finished_single = time + autocvar_g_vehicle_spiderbot_minigun_refire; - player.vehicle_ammo1 = (spider.vehicle_ammo1 / autocvar_g_vehicle_spiderbot_minigun_ammo_max) * 100; - spider.gun1.angles_z += 45; - spider.gun2.angles_z -= 45; - if(spider.gun1.angles_z >= 360) - { - spider.gun1.angles_z = 0; - spider.gun2.angles_z = 0; - } - } - } - else - vehicles_regen(spider.cnt, vehicle_ammo1, autocvar_g_vehicle_spiderbot_minigun_ammo_max, - autocvar_g_vehicle_spiderbot_minigun_ammo_regen_pause, - autocvar_g_vehicle_spiderbot_minigun_ammo_regen, frametime, FALSE); - - - spiderbot_rocket_do(); - - if(self.vehicle_flags & VHF_SHIELDREGEN) - vehicles_regen(spider.dmg_time, vehicle_shield, autocvar_g_vehicle_spiderbot_shield, autocvar_g_vehicle_spiderbot_shield_regen_pause, autocvar_g_vehicle_spiderbot_shield_regen, frametime, TRUE); - - if(self.vehicle_flags & VHF_HEALTHREGEN) - vehicles_regen(spider.dmg_time, vehicle_health, autocvar_g_vehicle_spiderbot_health, autocvar_g_vehicle_spiderbot_health_regen_pause, autocvar_g_vehicle_spiderbot_health_regen, frametime, FALSE); - - player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0; - player.vehicle_ammo2 = spider.tur_head.frame; - - if(spider.gun2.cnt <= time) - player.vehicle_reload2 = 100; - else - player.vehicle_reload2 = 100 - ((spider.gun2.cnt - time) / spider.attack_finished_single) * 100; - - setorigin(player, spider.origin + '0 0 1' * SPIDERBOT_MAX_z); - player.velocity = spider.velocity; - - VEHICLE_UPDATE_PLAYER(player, health, spiderbot); - - if(self.vehicle_flags & VHF_HASSHIELD) - VEHICLE_UPDATE_PLAYER(player, shield, spiderbot); - - self = player; - return 1; -} -void spiderbot_think() -{ - if(self.flags & FL_ONGROUND) - movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop); - - self.nextthink = time; -} - -void spiderbot_enter() -{ - self.vehicle_weapon2mode = SBRM_GUIDE; - self.movetype = MOVETYPE_WALK; - CSQCVehicleSetup(self.owner, 0); - self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_spiderbot_health) * 100; - self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_spiderbot_shield) * 100; - - if(self.owner.flagcarried) - { - setattachment(self.owner.flagcarried, self.tur_head, ""); - setorigin(self.owner.flagcarried, '-20 0 120'); - } -} - -void spiderbot_exit(float eject) -{ - entity e; - vector spot; - - e = findchain(classname,"spiderbot_rocket"); - while(e) - { - if(e.owner == self.owner) - { - e.realowner = self.owner; - e.owner = world; - } - e = e.chain; - } - - //self.velocity = '0 0 0'; - self.think = spiderbot_think; - self.nextthink = time; - self.frame = 5; - self.movetype = MOVETYPE_WALK; - - if not (self.owner) - return; - - makevectors(self.angles); - if(eject) - { - spot = self.origin + v_forward * 100 + '0 0 64'; - spot = vehicles_findgoodexit(spot); - setorigin(self.owner , spot); - self.owner.velocity = (v_up + v_forward * 0.25) * 750; - self.owner.oldvelocity = self.owner.velocity; - } - else - { - if(vlen(self.velocity) > autocvar_g_vehicle_spiderbot_speed_strafe) - { - self.owner.velocity = normalize(self.velocity) * vlen(self.velocity); - self.owner.velocity_z += 200; - spot = self.origin + v_forward * 128 + '0 0 64'; - spot = vehicles_findgoodexit(spot); - } - else - { - self.owner.velocity = self.velocity * 0.5; - self.owner.velocity_z += 10; - spot = self.origin + v_forward * 256 + '0 0 64'; - spot = vehicles_findgoodexit(spot); - } - self.owner.oldvelocity = self.owner.velocity; - setorigin(self.owner , spot); - } - - antilag_clear(self.owner); - self.owner = world; -} - -void spider_impact() -{ - if(autocvar_g_vehicle_spiderbot_bouncepain_x) - vehilces_impact(autocvar_g_vehicle_spiderbot_bouncepain_x, autocvar_g_vehicle_spiderbot_bouncepain_y, autocvar_g_vehicle_spiderbot_bouncepain_z); -} - -void spiderbot_headfade() -{ - self.think = spiderbot_headfade; - self.nextthink = self.fade_time; - self.alpha = 1 - (time - self.fade_time) * self.fade_rate; - - if(self.cnt < time || self.alpha < 0.1) - { - if(self.alpha > 0.1) - { - sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("explosion_big"), self.origin + '0 0 100', '0 0 0', 1); - } - remove(self); - } -} - -void spiderbot_blowup() -{ - if(self.cnt > time) - { - if(random() < 0.1) - { - sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); - } - self.nextthink = time + 0.1; - return; - } - - entity h, g1, g2, b; - b = spawn(); - h = spawn(); - g1 = spawn(); - g2 = spawn(); - - setmodel(b, "models/vehicles/spiderbot.dpm"); - setmodel(h, "models/vehicles/spiderbot_top.dpm"); - setmodel(g1, "models/vehicles/spiderbot_barrels.dpm"); - setmodel(g2, "models/vehicles/spiderbot_barrels.dpm"); - - setorigin(b, self.origin); - b.frame = 11; - b.angles = self.angles; - setsize(b, self.mins, self.maxs); - - setorigin(h, gettaginfo(self, gettagindex(self, "tag_head"))); - h.movetype = MOVETYPE_BOUNCE; - h.solid = SOLID_BBOX; - h.velocity = v_up * (500 + random() * 500) + randomvec() * 128; - h.modelflags = MF_ROCKET; - h.effects = EF_FLAME | EF_LOWPRECISION; - h.avelocity = randomvec() * 360; - - h.alpha = 1; - h.cnt = time + (3.5 * random()); - h.fade_rate = 1 / min(autocvar_g_vehicle_spiderbot_respawntime, 10); - h.fade_time = time; - h.think = spiderbot_headfade; - h.nextthink = time; - - setorigin(g1, gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_hardpoint01"))); - g1.movetype = MOVETYPE_TOSS; - g1.solid = SOLID_CORPSE; - g1.velocity = v_forward * 700 + (randomvec() * 32); - g1.avelocity = randomvec() * 180; - - setorigin(g2, gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_hardpoint02"))); - g2.movetype = MOVETYPE_TOSS; - g2.solid = SOLID_CORPSE; - g2.velocity = v_forward * 700 + (randomvec() * 32); - g2.avelocity = randomvec() * 180; - - h.colormod = b.colormod = g1.colormod = g2.colormod = '-2 -2 -2'; - - SUB_SetFade(b, time + 5, min(autocvar_g_vehicle_spiderbot_respawntime, 1)); - //SUB_SetFade(h, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10)); - SUB_SetFade(g1, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10)); - SUB_SetFade(g2, time, min(autocvar_g_vehicle_spiderbot_respawntime, 10)); - - RadiusDamage (self, self.enemy, 250, 15, 250, world, 250, DEATH_VH_SPID_DEATH, world); - - self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = -1; - self.movetype = MOVETYPE_NONE; - self.deadflag = DEAD_DEAD; - self.solid = SOLID_NOT; - self.tur_head.effects &= ~EF_FLAME; - self.vehicle_hudmodel.viewmodelforclient = self; -} - -void spiderbot_die() -{ - self.health = 0; - self.event_damage = func_null; - self.takedamage = DAMAGE_NO; - self.touch = func_null; - self.cnt = 3.4 + time + random() * 2; - self.think = spiderbot_blowup; - self.nextthink = time; - self.deadflag = DEAD_DYING; - self.frame = 5; - self.tur_head.effects |= EF_FLAME; - self.colormod = self.tur_head.colormod = '-1 -1 -1'; - self.frame = 10; - self.movetype = MOVETYPE_TOSS; -} - -float spiderbot_impulse(float _imp) -{ - switch(_imp) - { - case 10: - case 15: - case 18: - self.vehicle.vehicle_weapon2mode += 1; - if(self.vehicle.vehicle_weapon2mode > SBRM_LAST) - self.vehicle.vehicle_weapon2mode = SBRM_FIRST; - - //centerprint(self, strcat("Rocket mode is ", ftos(self.vehicle.vehicle_weapon2mode))); - CSQCVehicleSetup(self, 0); - return TRUE; - case 12: - case 16: - case 19: - self.vehicle.vehicle_weapon2mode -= 1; - if(self.vehicle.vehicle_weapon2mode < SBRM_FIRST) - self.vehicle.vehicle_weapon2mode = SBRM_LAST; - - //centerprint(self, strcat("Rocket mode is ", ftos(self.vehicle.vehicle_weapon2mode))); - CSQCVehicleSetup(self, 0); - return TRUE; - - /* - case 17: // toss gun, could be used to exit? - break; - case 20: // Manual minigun reload? - break; - */ - } - return FALSE; -} - -void spiderbot_spawn(float _f) -{ - if(!self.gun1) - { - self.vehicles_impusle = spiderbot_impulse; - self.gun1 = spawn(); - self.gun2 = spawn(); - setmodel(self.gun1, "models/vehicles/spiderbot_barrels.dpm"); - setmodel(self.gun2, "models/vehicles/spiderbot_barrels.dpm"); - setattachment(self.gun1, self.tur_head, "tag_hardpoint01"); - setattachment(self.gun2, self.tur_head, "tag_hardpoint02"); - self.gravity = 2; - self.mass = 5000; - } - - self.frame = 5; - self.tur_head.frame = 1; - self.think = spiderbot_think; - self.nextthink = time; - self.vehicle_health = autocvar_g_vehicle_spiderbot_health; - self.vehicle_shield = autocvar_g_vehicle_spiderbot_shield; - self.movetype = MOVETYPE_WALK; - self.solid = SOLID_SLIDEBOX; - self.alpha = self.tur_head.alpha = self.gun1.alpha = self.gun2.alpha = 1; - self.tur_head.angles = '0 0 0'; - - setorigin(self, self.pos1 + '0 0 128'); - self.angles = self.pos2; - self.vehicle_impact = spider_impact; - self.damageforcescale = 0.03; -} - -void spawnfunc_vehicle_spiderbot() -{ - if(!autocvar_g_vehicle_spiderbot) - { - remove(self); - return; - } - - self.vehicle_flags |= VHF_DMGSHAKE; - //self.vehicle_flags |= VHF_DMGROLL; - //self.vehicle_flags |= VHF_DMGHEADROLL; - - precache_model ( "models/vhshield.md3"); - precache_model ( "models/vehicles/spiderbot.dpm"); - precache_model ( "models/vehicles/spiderbot_top.dpm"); - precache_model ( "models/vehicles/spiderbot_barrels.dpm"); - precache_model ( "models/vehicles/spiderbot_cockpit.dpm"); - precache_model ( "models/uziflash.md3"); - - precache_sound ( "weapons/uzi_fire.wav" ); - precache_sound ( "weapons/rocket_impact.wav"); - - precache_sound ( "vehicles/spiderbot_die.wav"); - precache_sound ( "vehicles/spiderbot_idle.wav"); - precache_sound ( "vehicles/spiderbot_jump.wav"); - precache_sound ( "vehicles/spiderbot_strafe.wav"); - precache_sound ( "vehicles/spiderbot_walk.wav"); - precache_sound ( "vehicles/spiderbot_land.wav"); - - if(autocvar_g_vehicle_spiderbot_shield) - self.vehicle_flags |= VHF_HASSHIELD; - - if(autocvar_g_vehicle_spiderbot_shield_regen) - self.vehicle_flags |= VHF_SHIELDREGEN; - - if(autocvar_g_vehicle_spiderbot_health_regen) - self.vehicle_flags |= VHF_HEALTHREGEN; - - if not (vehicle_initialize( - "Spiderbot", - "models/vehicles/spiderbot.dpm", - "models/vehicles/spiderbot_top.dpm", - "models/vehicles/spiderbot_cockpit.dpm", - "tag_head", "tag_hud", "", - HUD_SPIDERBOT, - SPIDERBOT_MIN, SPIDERBOT_MAX, - FALSE, - spiderbot_spawn, autocvar_g_vehicle_spiderbot_respawntime, - spiderbot_frame, - spiderbot_enter, spiderbot_exit, - spiderbot_die, spiderbot_think, - FALSE, - autocvar_g_vehicle_spiderbot_health, - autocvar_g_vehicle_spiderbot_shield)) - { - remove(self); - return; - } -} -#endif // SVQC diff --git a/qcsrc/server/vehicles/vehicles.qc b/qcsrc/server/vehicles/vehicles.qc deleted file mode 100644 index 75fa9407e6..0000000000 --- a/qcsrc/server/vehicles/vehicles.qc +++ /dev/null @@ -1,1416 +0,0 @@ -float autocvar_g_vehicles_crush_dmg; -float autocvar_g_vehicles_crush_force; -float autocvar_g_vehicles_delayspawn; -float autocvar_g_vehicles_delayspawn_jitter; - -var float autocvar_g_vehicles_nex_damagerate = 0.5; -var float autocvar_g_vehicles_uzi_damagerate = 0.5; -var float autocvar_g_vehicles_rifle_damagerate = 0.75; -var float autocvar_g_vehicles_minstanex_damagerate = 0.001; -var float autocvar_g_vehicles_tag_damagerate = 5; - -float autocvar_g_vehicles; - -void vehicles_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force); -void vehicles_return(); -void vehicles_enter(); -void vehicles_touch(); -void vehicles_reset_colors(); -void vehicles_clearrturn(); -void vehicles_setreturn(); - - -/** AuxiliaryXhair* - Send additional points of interest to be drawn, to vehicle owner -**/ -const float MAX_AXH = 4; -.entity AuxiliaryXhair[MAX_AXH]; - -float SendAuxiliaryXhair(entity to, float sf) -{ - - WriteByte(MSG_ENTITY, ENT_CLIENT_AUXILIARYXHAIR); - - WriteByte(MSG_ENTITY, self.cnt); - - WriteCoord(MSG_ENTITY, self.origin_x); - WriteCoord(MSG_ENTITY, self.origin_y); - WriteCoord(MSG_ENTITY, self.origin_z); - - WriteByte(MSG_ENTITY, rint(self.colormod_x * 255)); - WriteByte(MSG_ENTITY, rint(self.colormod_y * 255)); - WriteByte(MSG_ENTITY, rint(self.colormod_z * 255)); - - return TRUE; -} - -void UpdateAuxiliaryXhair(entity own, vector loc, vector clr, float axh_id) -{ - if not(IS_REAL_CLIENT(own)) - return; - - entity axh; - - axh_id = bound(0, axh_id, MAX_AXH); - axh = own.(AuxiliaryXhair[axh_id]); - - if(axh == world || wasfreed(axh)) // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?) - { - axh = spawn(); - axh.cnt = axh_id; - axh.drawonlytoclient = own; - axh.owner = own; - Net_LinkEntity(axh, FALSE, 0, SendAuxiliaryXhair); - } - - setorigin(axh, loc); - axh.colormod = clr; - axh.SendFlags = 0x01; - own.(AuxiliaryXhair[axh_id]) = axh; -} - -/* -// SVC_TEMPENTITY based, horrible with even 50 ping. hm. -// WriteByte(MSG_ONE, SVC_TEMPENTITY) uses reliable messagess, never use for thinsg that need continous updates. -void SendAuxiliaryXhair2(entity own, vector loc, vector clr, float axh_id) -{ - msgexntity = own; - - WriteByte(MSG_ONE, SVC_TEMPENTITY); - WriteByte(MSG_ONE, TE_CSQC_AUXILIARYXHAIR); - - WriteByte(MSG_ONE, axh_id); - - WriteCoord(MSG_ONE, loc_x); - WriteCoord(MSG_ONE, loc_y); - WriteCoord(MSG_ONE, loc_z); - - WriteByte(MSG_ONE, rint(clr_x * 255)); - WriteByte(MSG_ONE, rint(clr_y * 255)); - WriteByte(MSG_ONE, rint(clr_z * 255)); - -} -*/ -// End AuxiliaryXhair - -/** - Notifies the client that he enterd a vehicle, and sends - realavent data. - - only sends vehicle_id atm (wich is a HUD_* constant, ex. HUD_SPIDERBOT) -**/ -void CSQCVehicleSetup(entity own, float vehicle_id) -{ - if not(IS_REAL_CLIENT(own)) - return; - - msg_entity = own; - - WriteByte(MSG_ONE, SVC_TEMPENTITY); - WriteByte(MSG_ONE, TE_CSQC_VEHICLESETUP); - if(vehicle_id != 0) - WriteByte(MSG_ONE, vehicle_id); - else - WriteByte(MSG_ONE, 1 + own.vehicle.vehicle_weapon2mode + HUD_VEHICLE_LAST); -} - -/** vehicles_locktarget - - Generic target locking. - - Figure out if what target is "locked" (if any), for missile tracking as such. - - after calling, "if(self.lock_target != world && self.lock_strength == 1)" mean - you have a locked in target. - - Exspects a crosshair_trace() or equivalent to be - dont before calling. - -**/ -.entity lock_target; -.float lock_strength; -.float lock_time; -.float lock_soundtime; -const float DAMAGE_TARGETDRONE = 10; - -vector targetdrone_getnewspot() -{ - - vector spot; - float i; - for(i = 0; i < 100; ++i) - { - spot = self.origin + randomvec() * 1024; - tracebox(spot, self.mins, self.maxs, spot, MOVE_NORMAL, self); - if(trace_fraction == 1.0 && trace_startsolid == 0 && trace_allsolid == 0) - return spot; - } - return self.origin; -} - -#if 0 -void targetdrone_think(); -void targetdrone_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force); -void targetdrone_renwe() -{ - self.think = targetdrone_think; - self.nextthink = time + 0.1; - setorigin(self, targetdrone_getnewspot()); - self.health = 200; - self.takedamage = DAMAGE_TARGETDRONE; - self.event_damage = targetdrone_damage; - self.solid = SOLID_BBOX; - setmodel(self, "models/runematch/rune.mdl"); - self.effects = EF_LOWPRECISION; - self.scale = 10; - self.movetype = MOVETYPE_BOUNCEMISSILE; - setsize(self, '-100 -100 -100', '100 100 100'); - -} -void targetdrone_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) -{ - self.health -= damage; - if(self.health <= 0) - { - pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1); - - if(!self.cnt) - remove(self); - else - { - self.think = targetdrone_renwe; - self.nextthink = time + 1 + random() * 2; - self.solid = SOLID_NOT; - setmodel(self, ""); - } - } -} -entity targetdrone_getfear() -{ - entity fear; - float i; - - for(i = 64; i <= 1024; i += 64) - { - fear = findradius(self.origin, i); - while(fear) - { - if(fear.bot_dodge) - return fear; - - fear = fear.chain; - } - } - - return world; -} -void targetdrone_think() -{ - self.nextthink = time + 0.1; - - if(self.wp00) - if(self.wp00.deadflag != DEAD_NO) - self.wp00 = targetdrone_getfear(); - - if(!self.wp00) - self.wp00 = targetdrone_getfear(); - - vector newdir; - - if(self.wp00) - newdir = steerlib_push(self.wp00.origin) + randomvec() * 0.75; - else - newdir = randomvec() * 0.75; - - newdir = newdir * 0.5 + normalize(self.velocity) * 0.5; - - if(self.wp00) - self.velocity = normalize(newdir) * (500 + (1024 / min(vlen(self.wp00.origin - self.origin), 1024)) * 700); - else - self.velocity = normalize(newdir) * 750; - - tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 2, MOVE_NORMAL, self); - if(trace_fraction != 1.0) - self.velocity = self.velocity * -1; - - //normalize((normalize(self.velocity) * 0.5 + newdir * 0.5)) * 750; -} - -void targetdrone_spawn(vector _where, float _autorenew) -{ - entity drone = spawn(); - setorigin(drone, _where); - drone.think = targetdrone_renwe; - drone.nextthink = time + 0.1; - drone.cnt = _autorenew; -} -#endif - -void vehicles_locktarget(float incr, float decr, float _lock_time) -{ - if(self.lock_target && self.lock_target.deadflag != DEAD_NO) - { - self.lock_target = world; - self.lock_strength = 0; - self.lock_time = 0; - } - - if(self.lock_time > time) - { - if(self.lock_target) - if(self.lock_soundtime < time) - { - self.lock_soundtime = time + 0.5; - play2(self.owner, "vehicles/locked.wav"); - } - - return; - } - - if(trace_ent != world) - { - if(teamplay && trace_ent.team == self.team) - trace_ent = world; - - if(trace_ent.deadflag != DEAD_NO) - trace_ent = world; - - if not (trace_ent.vehicle_flags & VHF_ISVEHICLE || - trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET || - trace_ent.takedamage == DAMAGE_TARGETDRONE) - trace_ent = world; - } - - if(self.lock_target == world && trace_ent != world) - self.lock_target = trace_ent; - - if(self.lock_target && trace_ent == self.lock_target) - { - if(self.lock_strength != 1 && self.lock_strength + incr >= 1) - { - play2(self.owner, "vehicles/lock.wav"); - self.lock_soundtime = time + 0.8; - } - else if (self.lock_strength != 1 && self.lock_soundtime < time) - { - play2(self.owner, "vehicles/locking.wav"); - self.lock_soundtime = time + 0.3; - } - - } - - // Have a locking target - // Trace hit current target - if(trace_ent == self.lock_target && trace_ent != world) - { - self.lock_strength = min(self.lock_strength + incr, 1); - if(self.lock_strength == 1) - self.lock_time = time + _lock_time; - } - else - { - if(trace_ent) - self.lock_strength = max(self.lock_strength - decr * 2, 0); - else - self.lock_strength = max(self.lock_strength - decr, 0); - - if(self.lock_strength == 0) - self.lock_target = world; - } -} - -#define VEHICLE_UPDATE_PLAYER(ply,fld,vhname) \ -ply.vehicle_##fld = (self.vehicle_##fld / autocvar_g_vehicle_##vhname##_##fld) * 100 - -#define vehicles_sweap_collision(orig,vel,dt,acm,mult) \ -traceline(orig, orig + vel * dt, MOVE_NORMAL, self); \ -if(trace_fraction != 1) \ - acm += normalize(self.origin - trace_endpos) * (vlen(vel) * mult) - -// Hover movement support -float force_fromtag_power; -float force_fromtag_normpower; -vector force_fromtag_origin; -vector vehicles_force_fromtag_hover(string tag_name, float spring_length, float max_power) -{ - force_fromtag_origin = gettaginfo(self, gettagindex(self, tag_name)); - v_forward = normalize(v_forward) * -1; - traceline(force_fromtag_origin, force_fromtag_origin - (v_forward * spring_length), MOVE_NORMAL, self); - - force_fromtag_power = (1 - trace_fraction) * max_power; - force_fromtag_normpower = force_fromtag_power / max_power; - - return v_forward * force_fromtag_power; -} - -// Experimental hovermode wich uses attraction/repulstion from surface insted of gravity/repulsion -// Can possibly be use to move abt any surface (inclusing walls/celings) -vector vehicles_force_fromtag_maglev(string tag_name, float spring_length, float max_power) -{ - - force_fromtag_origin = gettaginfo(self, gettagindex(self, tag_name)); - v_forward = normalize(v_forward) * -1; - traceline(force_fromtag_origin, force_fromtag_origin - (v_forward * spring_length), MOVE_NORMAL, self); - - // TODO - this may NOT be compatible with wall/celing movement, unhardcode 0.25 (engine count multiplier) - if(trace_fraction == 1.0) - { - force_fromtag_normpower = -0.25; - return '0 0 -200'; - } - - force_fromtag_power = ((1 - trace_fraction) - trace_fraction) * max_power; - force_fromtag_normpower = force_fromtag_power / max_power; - - return v_forward * force_fromtag_power; -} - -// Generic vehile projectile system -void vehicles_projectile_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) -{ - // Ignore damage from oterh projectiles from my owner (dont mess up volly's) - if(inflictor.owner == self.owner) - return; - - self.health -= damage; - self.velocity += force; - if(self.health < 1) - { - self.takedamage = DAMAGE_NO; - self.event_damage = func_null; - self.think = self.use; - self.nextthink = time; - } -} - -void vehicles_projectile_explode() -{ - if(self.owner && other != world) - { - if(other == self.owner.vehicle) - return; - - if(other == self.owner.vehicle.tur_head) - return; - } - - PROJECTILE_TOUCH; - - self.event_damage = func_null; - RadiusDamage (self, self.realowner, self.shot_dmg, 0, self.shot_radius, self, self.shot_force, self.totalfrags, other); - - remove (self); -} - -entity vehicles_projectile(string _mzlfx, string _mzlsound, - vector _org, vector _vel, - float _dmg, float _radi, float _force, float _size, - float _deahtype, float _projtype, float _health, - float _cull, float _clianim, entity _owner) -{ - entity proj; - - proj = spawn(); - - PROJECTILE_MAKETRIGGER(proj); - setorigin(proj, _org); - - proj.shot_dmg = _dmg; - proj.shot_radius = _radi; - proj.shot_force = _force; - proj.totalfrags = _deahtype; - proj.solid = SOLID_BBOX; - proj.movetype = MOVETYPE_FLYMISSILE; - proj.flags = FL_PROJECTILE; - proj.bot_dodge = TRUE; - proj.bot_dodgerating = _dmg; - proj.velocity = _vel; - proj.touch = vehicles_projectile_explode; - proj.use = vehicles_projectile_explode; - proj.owner = self; - proj.realowner = _owner; - proj.think = SUB_Remove; - proj.nextthink = time + 30; - - if(_health) - { - proj.takedamage = DAMAGE_AIM; - proj.event_damage = vehicles_projectile_damage; - proj.health = _health; - } - else - proj.flags = FL_PROJECTILE | FL_NOTARGET; - - if(_mzlsound) - sound (self, CH_WEAPON_A, _mzlsound, VOL_BASE, ATTEN_NORM); - - if(_mzlfx) - pointparticles(particleeffectnum(_mzlfx), proj.origin, proj.velocity, 1); - - - setsize (proj, '-1 -1 -1' * _size, '1 1 1' * _size); - - CSQCProjectile(proj, _clianim, _projtype, _cull); - - return proj; -} -// End generic vehile projectile system - -/** vehicles_spawn - Exetuted for all vehicles on (re)spawn. - Sets defaults for newly spawned units. -**/ -void vehicles_spawn() -{ - dprint("Spawning vehicle: ", self.netname, "\n"); - - // De-own & reset - self.vehicle_hudmodel.viewmodelforclient = self; - - self.owner = world; - self.touch = vehicles_touch; - self.event_damage = vehicles_damage; - self.iscreature = TRUE; - self.teleportable = FALSE; // no teleporting for vehicles, too buggy - self.damagedbycontents = TRUE; - self.movetype = MOVETYPE_WALK; - self.solid = SOLID_SLIDEBOX; - self.takedamage = DAMAGE_AIM; - self.deadflag = DEAD_NO; - self.bot_attack = TRUE; - self.flags = FL_NOTARGET; - self.avelocity = '0 0 0'; - self.velocity = '0 0 0'; - - // Reset locking - self.lock_strength = 0; - self.lock_target = world; - self.misc_bulletcounter = 0; - - // Return to spawn - self.angles = self.pos2; - setorigin(self, self.pos1 + '0 0 0'); - // Show it - pointparticles(particleeffectnum("teleport"), self.origin + '0 0 64', '0 0 0', 1); - - if(self.vehicle_controller) - self.team = self.vehicle_controller.team; - - vehicles_reset_colors(); - self.vehicle_spawn(VHSF_NORMAL); -} - -// Better way of determening whats crushable needed! (fl_crushable?) -float vehicles_crushable(entity e) -{ - if(IS_PLAYER(e)) - return TRUE; - - if(e.flags & FL_MONSTER) - return TRUE; - - return FALSE; -} - -void vehilces_impact(float _minspeed, float _speedfac, float _maxpain) -{ - if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT) - return; - - if(self.play_time < time) - { - float wc = vlen(self.velocity - self.oldvelocity); - //dprint("oldvel: ", vtos(self.oldvelocity), "\n"); - //dprint("vel: ", vtos(self.velocity), "\n"); - if(_minspeed < wc) - { - float take = min(_speedfac * wc, _maxpain); - Damage (self, world, world, take, DEATH_FALL, self.origin, '0 0 0'); - self.play_time = time + 0.25; - - //dprint("wc: ", ftos(wc), "\n"); - //dprint("take: ", ftos(take), "\n"); - } - } -} - -.void() vehicle_impact; -void vehicles_touch() -{ - if(MUTATOR_CALLHOOK(VehicleTouch)) - return; - - // Vehicle currently in use - if(self.owner) - { - if(other != world) - if(vehicles_crushable(other)) - { - if(vlen(self.velocity) != 0) - Damage(other, self, self.owner, autocvar_g_vehicles_crush_dmg, DEATH_VH_CRUSH, '0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicles_crush_force); - - return; // Dont do selfdamage when hitting "soft targets". - } - - if(self.play_time < time) - if(self.vehicle_impact) - self.vehicle_impact(); - - return; - } - - if not(IS_PLAYER(other)) - return; - - if(other.deadflag != DEAD_NO) - return; - - if(other.vehicle != world) - return; - - vehicles_enter(); -} -var float autocvar_g_vehicles_allow_bots = 0; -void vehicles_enter() -{ - // Remove this when bots know how to use vehicles - - if (IS_BOT_CLIENT(other)) - if (autocvar_g_vehicles_allow_bots) - dprint("Bot enters vehicle\n"); // This is where we need to disconnect (some, all?) normal bot AI and hand over to vehicle's _aiframe() - else - return; - - if(self.phase > time) - return; - - if(teamplay) - if(self.team) - if(self.team != other.team) - return; - - RemoveGrapplingHook(other); - - self.vehicle_ammo1 = 0; - self.vehicle_ammo2 = 0; - self.vehicle_reload1 = 0; - self.vehicle_reload2 = 0; - self.vehicle_energy = 0; - - self.owner = other; - self.switchweapon = other.switchweapon; - - // .viewmodelforclient works better. - //self.vehicle_hudmodel.drawonlytoclient = self.owner; - - self.vehicle_hudmodel.viewmodelforclient = self.owner; - - self.event_damage = vehicles_damage; - self.nextthink = 0; - self.owner.angles = self.angles; - self.owner.takedamage = DAMAGE_NO; - self.owner.solid = SOLID_NOT; - self.owner.movetype = MOVETYPE_NOCLIP; - self.owner.alpha = -1; - self.owner.vehicle = self; - self.owner.event_damage = func_null; - self.owner.view_ofs = '0 0 0'; - self.colormap = self.owner.colormap; - if(self.tur_head) - self.tur_head.colormap = self.owner.colormap; - - self.owner.hud = self.hud; - self.owner.PlayerPhysplug = self.PlayerPhysplug; - - self.owner.vehicle_ammo1 = self.vehicle_ammo1; - self.owner.vehicle_ammo2 = self.vehicle_ammo2; - self.owner.vehicle_reload1 = self.vehicle_reload1; - self.owner.vehicle_reload2 = self.vehicle_reload2; - - // Cant do this, hides attached objects too. - //self.exteriormodeltoclient = self.owner; - //self.tur_head.exteriormodeltoclient = self.owner; - - other.flags &= ~FL_ONGROUND; - self.flags &= ~FL_ONGROUND; - - self.team = self.owner.team; - self.flags -= FL_NOTARGET; - - if (IS_REAL_CLIENT(other)) - { - msg_entity = other; - WriteByte (MSG_ONE, SVC_SETVIEWPORT); - WriteEntity(MSG_ONE, self.vehicle_viewport); - - WriteByte (MSG_ONE, SVC_SETVIEWANGLES); - if(self.tur_head) - { - WriteAngle(MSG_ONE, self.tur_head.angles_x + self.angles_x); // tilt - WriteAngle(MSG_ONE, self.tur_head.angles_y + self.angles_y); // yaw - WriteAngle(MSG_ONE, 0); // roll - } - else - { - WriteAngle(MSG_ONE, self.angles_x * -1); // tilt - WriteAngle(MSG_ONE, self.angles_y); // yaw - WriteAngle(MSG_ONE, 0); // roll - } - } - - vehicles_clearrturn(); - - CSQCVehicleSetup(self.owner, self.hud); - - vh_player = other; - vh_vehicle = self; - MUTATOR_CALLHOOK(VehicleEnter); - other = vh_player; - self = vh_vehicle; - - self.vehicle_enter(); - antilag_clear(other); -} - -/** vehicles_findgoodexit - Locates a valid location for the player to exit the vehicle. - Will first try prefer_spot, then up 100 random spots arround the vehicle - wich are in direct line of sight and empty enougth to hold a players bbox -**/ -vector vehicles_findgoodexit(vector prefer_spot) -{ - //vector exitspot; - float mysize; - - tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, prefer_spot, MOVE_NORMAL, self.owner); - if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) - return prefer_spot; - - mysize = 1.5 * vlen(self.maxs - self.mins); - float i; - vector v, v2; - v2 = 0.5 * (self.absmin + self.absmax); - for(i = 0; i < 100; ++i) - { - v = randomvec(); - v_z = 0; - v = v2 + normalize(v) * mysize; - tracebox(v2, PL_MIN, PL_MAX, v, MOVE_NORMAL, self.owner); - if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) - return v; - } - - /* - exitspot = (self.origin + '0 0 48') + v_forward * mysize; - tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner); - if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) - return exitspot; - - exitspot = (self.origin + '0 0 48') - v_forward * mysize; - tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner); - if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) - return exitspot; - - exitspot = (self.origin + '0 0 48') + v_right * mysize; - tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner); - if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) - return exitspot; - - exitspot = (self.origin + '0 0 48') - v_right * mysize; - tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner); - if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid) - return exitspot; - */ - - return self.origin; -} - -/** vehicles_exit - Standarrd vehicle release fucntion. - custom code goes in self.vehicle_exit -**/ -float vehicles_exit_running; -void vehicles_exit(float eject) -{ - entity _vehicle; - entity _player; - entity _oldself = self; - - if(vehicles_exit_running) - { - dprint("^1vehicles_exit allready running! this is not good..\n"); - return; - } - - vehicles_exit_running = TRUE; - if(IS_CLIENT(self)) - { - _vehicle = self.vehicle; - - if (_vehicle.vehicle_flags & VHF_PLAYERSLOT) - { - _vehicle.vehicle_exit(eject); - self = _oldself; - vehicles_exit_running = FALSE; - return; - } - } - else - _vehicle = self; - - _player = _vehicle.owner; - - self = _vehicle; - - if (_player) - { - if (IS_REAL_CLIENT(_player)) - { - msg_entity = _player; - WriteByte (MSG_ONE, SVC_SETVIEWPORT); - WriteEntity( MSG_ONE, _player); - - WriteByte (MSG_ONE, SVC_SETVIEWANGLES); - WriteAngle(MSG_ONE, 0); - WriteAngle(MSG_ONE, _vehicle.angles_y); - WriteAngle(MSG_ONE, 0); - } - - setsize(_player, PL_MIN,PL_MAX); - - _player.takedamage = DAMAGE_AIM; - _player.solid = SOLID_SLIDEBOX; - _player.movetype = MOVETYPE_WALK; - _player.effects &= ~EF_NODRAW; - _player.alpha = 1; - _player.PlayerPhysplug = func_null; - _player.vehicle = world; - _player.view_ofs = PL_VIEW_OFS; - _player.event_damage = PlayerDamage; - _player.hud = HUD_NORMAL; - _player.switchweapon = _vehicle.switchweapon; - - CSQCVehicleSetup(_player, HUD_NORMAL); - } - _vehicle.flags |= FL_NOTARGET; - - if(_vehicle.deadflag == DEAD_NO) - _vehicle.avelocity = '0 0 0'; - - _vehicle.tur_head.nodrawtoclient = world; - - if(!teamplay) - _vehicle.team = 0; - - vh_player = _player; - vh_vehicle = _vehicle; - MUTATOR_CALLHOOK(VehicleExit); - _player = vh_player; - _vehicle = vh_vehicle; - - _vehicle.team = _vehicle.tur_head.team; - - sound (_vehicle, CH_TRIGGER_SINGLE, "misc/null.wav", 1, ATTEN_NORM); - _vehicle.vehicle_hudmodel.viewmodelforclient = _vehicle; - _vehicle.phase = time + 1; - - _vehicle.vehicle_exit(eject); - - vehicles_setreturn(); - vehicles_reset_colors(); - _vehicle.owner = world; - self = _oldself; - - vehicles_exit_running = FALSE; -} - - -void vehicles_regen(float timer, .float regen_field, float field_max, float rpause, float regen, float delta_time, float _healthscale) -{ - if(self.regen_field < field_max) - if(timer + rpause < time) - { - if(_healthscale) - regen = regen * (self.vehicle_health / self.tur_health); - - self.regen_field = min(self.regen_field + regen * delta_time, field_max); - - if(self.owner) - self.owner.regen_field = (self.regen_field / field_max) * 100; - } -} - -void shieldhit_think() -{ - self.alpha -= 0.1; - if (self.alpha <= 0) - { - //setmodel(self, ""); - self.alpha = -1; - self.effects |= EF_NODRAW; - } - else - { - self.nextthink = time + 0.1; - } -} - -void vehicles_painframe() -{ - if(self.owner.vehicle_health <= 50) - if(self.pain_frame < time) - { - float _ftmp; - _ftmp = self.owner.vehicle_health / 50; - self.pain_frame = time + 0.1 + (random() * 0.5 * _ftmp); - pointparticles(particleeffectnum("smoke_small"), (self.origin + (randomvec() * 80)), '0 0 0', 1); - - if(self.vehicle_flags & VHF_DMGSHAKE) - self.velocity += randomvec() * 30; - - if(self.vehicle_flags & VHF_DMGROLL) - if(self.vehicle_flags & VHF_DMGHEADROLL) - self.tur_head.angles += randomvec(); - else - self.angles += randomvec(); - - } -} - -void vehicles_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) -{ - self.dmg_time = time; - - if(DEATH_ISWEAPON(deathtype, WEP_NEX)) - damage *= autocvar_g_vehicles_nex_damagerate; - - if(DEATH_ISWEAPON(deathtype, WEP_UZI)) - damage *= autocvar_g_vehicles_uzi_damagerate; - - if(DEATH_ISWEAPON(deathtype, WEP_RIFLE)) - damage *= autocvar_g_vehicles_rifle_damagerate; - - if(DEATH_ISWEAPON(deathtype, WEP_MINSTANEX)) - damage *= autocvar_g_vehicles_minstanex_damagerate; - - if(DEATH_ISWEAPON(deathtype, WEP_SEEKER)) - damage *= autocvar_g_vehicles_tag_damagerate; - - self.enemy = attacker; - - if((self.vehicle_flags & VHF_HASSHIELD) && (self.vehicle_shield > 0)) - { - if (wasfreed(self.vehicle_shieldent) || self.vehicle_shieldent == world) - { - self.vehicle_shieldent = spawn(); - self.vehicle_shieldent.effects = EF_LOWPRECISION; - - setmodel(self.vehicle_shieldent, "models/vhshield.md3"); - setattachment(self.vehicle_shieldent, self, ""); - setorigin(self.vehicle_shieldent, real_origin(self) - self.origin); - self.vehicle_shieldent.scale = 256 / vlen(self.maxs - self.mins); - self.vehicle_shieldent.think = shieldhit_think; - } - - self.vehicle_shieldent.colormod = '1 1 1'; - self.vehicle_shieldent.alpha = 0.45; - self.vehicle_shieldent.angles = vectoangles(normalize(hitloc - (self.origin + self.vehicle_shieldent.origin))) - self.angles; - self.vehicle_shieldent.nextthink = time; - self.vehicle_shieldent.effects &= ~EF_NODRAW; - - self.vehicle_shield -= damage; - - if(self.vehicle_shield < 0) - { - self.vehicle_health -= fabs(self.vehicle_shield); - self.vehicle_shieldent.colormod = '2 0 0'; - self.vehicle_shield = 0; - self.vehicle_shieldent.alpha = 0.75; - - if(sound_allowed(MSG_BROADCAST, attacker)) - spamsound (self, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM); // FIXME: PLACEHOLDER - } - else - if(sound_allowed(MSG_BROADCAST, attacker)) - spamsound (self, CH_PAIN, "onslaught/electricity_explode.wav", VOL_BASE, ATTEN_NORM); // FIXME: PLACEHOLDER - - } - else - { - self.vehicle_health -= damage; - - if(sound_allowed(MSG_BROADCAST, attacker)) - spamsound (self, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM); // FIXME: PLACEHOLDER - } - - if(self.damageforcescale < 1 && self.damageforcescale > 0) - self.velocity += force * self.damageforcescale; - else - self.velocity += force; - - if(self.vehicle_health <= 0) - { - if(self.owner) - if(self.vehicle_flags & VHF_DEATHEJECT) - vehicles_exit(VHEF_EJECT); - else - vehicles_exit(VHEF_RELESE); - - - antilag_clear(self); - - self.vehicle_die(); - vehicles_setreturn(); - } -} - -void vehicles_clearrturn() -{ - entity ret; - // Remove "return helper", if any. - ret = findchain(classname, "vehicle_return"); - while(ret) - { - if(ret.wp00 == self) - { - ret.classname = ""; - ret.think = SUB_Remove; - ret.nextthink = time + 0.1; - - if(ret.waypointsprite_attached) - WaypointSprite_Kill(ret.waypointsprite_attached); - - return; - } - ret = ret.chain; - } -} - -void vehicles_return() -{ - pointparticles(particleeffectnum("teleport"), self.wp00.origin + '0 0 64', '0 0 0', 1); - - self.wp00.think = vehicles_spawn; - self.wp00.nextthink = time; - - if(self.waypointsprite_attached) - WaypointSprite_Kill(self.waypointsprite_attached); - - remove(self); -} - -void vehicles_showwp_goaway() -{ - if(self.waypointsprite_attached) - WaypointSprite_Kill(self.waypointsprite_attached); - - remove(self); - -} - -void vehicles_showwp() -{ - entity oldself = world; - vector rgb; - - if(self.cnt) - { - self.think = vehicles_return; - self.nextthink = self.cnt; - } - else - { - self.think = vehicles_return; - self.nextthink = time +1; - - oldself = self; - self = spawn(); - setmodel(self, "null"); - self.team = oldself.wp00.team; - self.wp00 = oldself.wp00; - setorigin(self, oldself.wp00.pos1); - - self.nextthink = time + 5; - self.think = vehicles_showwp_goaway; - } - - if(teamplay && self.team) - rgb = Team_ColorRGB(self.team); - else - rgb = '1 1 1'; - WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, TRUE, RADARICON_POWERUP, rgb); - if(self.waypointsprite_attached) - { - WaypointSprite_UpdateRule(self.waypointsprite_attached, self.wp00.team, SPRITERULE_DEFAULT); - if(oldself == world) - WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, self.nextthink); - WaypointSprite_Ping(self.waypointsprite_attached); - } - - if(oldself != world) - self = oldself; -} - -void vehicles_setreturn() -{ - entity ret; - - vehicles_clearrturn(); - - ret = spawn(); - ret.classname = "vehicle_return"; - ret.wp00 = self; - ret.team = self.team; - ret.think = vehicles_showwp; - - if(self.deadflag != DEAD_NO) - { - ret.cnt = time + self.vehicle_respawntime; - ret.nextthink = min(time + self.vehicle_respawntime, time + self.vehicle_respawntime - 5); - } - else - { - ret.nextthink = min(time + self.vehicle_respawntime, time + self.vehicle_respawntime - 1); - } - - setmodel(ret, "null"); - setorigin(ret, self.pos1 + '0 0 96'); - -} - -void vehicles_reset_colors() -{ - entity e; - float _effects = 0, _colormap; - vector _glowmod, _colormod; - - if(autocvar_g_nodepthtestplayers) - _effects |= EF_NODEPTHTEST; - - if(autocvar_g_fullbrightplayers) - _effects |= EF_FULLBRIGHT; - - if(self.team) - _colormap = 1024 + (self.team - 1) * 17; - else - _colormap = 1024; - - _glowmod = '0 0 0'; - _colormod = '0 0 0'; - - // Find all ents attacked to main model and setup effects, colormod etc. - e = findchainentity(tag_entity, self); - while(e) - { - if(e != self.vehicle_shieldent) - { - e.effects = _effects; // | EF_LOWPRECISION; - e.colormod = _colormod; - e.colormap = _colormap; - e.alpha = 1; - } - e = e.chain; - } - - self.vehicle_hudmodel.effects = self.effects = _effects; // | EF_LOWPRECISION; - self.vehicle_hudmodel.colormod = self.colormod = _colormod; - self.vehicle_hudmodel.colormap = self.colormap = _colormap; - self.vehicle_viewport.effects = (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT); - - self.alpha = 1; - self.avelocity = '0 0 0'; - self.velocity = '0 0 0'; - self.effects = _effects; -} - -void vehicle_use() -{ - dprint("vehicle ",self.netname, " used by ", activator.classname, "\n"); - - self.tur_head.team = activator.team; - - if(self.tur_head.team == 0) - self.active = ACTIVE_NOT; - else - self.active = ACTIVE_ACTIVE; - - if(self.active == ACTIVE_ACTIVE && self.deadflag == DEAD_NO) - { - dprint("^3Eat shit yall!\n"); - vehicles_setreturn(); - vehicles_reset_colors(); - } - else if(self.active == ACTIVE_NOT && self.deadflag != DEAD_NO) - { - - } -} - -float vehicle_addplayerslot( entity _owner, - entity _slot, - float _hud, - string _hud_model, - float() _framefunc, - void(float) _exitfunc) -{ - if not (_owner.vehicle_flags & VHF_MULTISLOT) - _owner.vehicle_flags |= VHF_MULTISLOT; - - _slot.PlayerPhysplug = _framefunc; - _slot.vehicle_exit = _exitfunc; - _slot.hud = _hud; - _slot.vehicle_flags = VHF_PLAYERSLOT; - _slot.vehicle_viewport = spawn(); - _slot.vehicle_hudmodel = spawn(); - _slot.vehicle_hudmodel.viewmodelforclient = _slot; - _slot.vehicle_viewport.effects = (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NOGUNBOB | EF_NOSHADOW | EF_LOWPRECISION | EF_SELECTABLE | EF_TELEPORT_BIT); - - setmodel(_slot.vehicle_hudmodel, _hud_model); - setmodel(_slot.vehicle_viewport, "null"); - - setattachment(_slot.vehicle_hudmodel, _slot, ""); - setattachment(_slot.vehicle_viewport, _slot.vehicle_hudmodel, ""); - - return TRUE; -} - -float vehicle_initialize(string net_name, - string bodymodel, - string topmodel, - string hudmodel, - string toptag, - string hudtag, - string viewtag, - float vhud, - vector min_s, - vector max_s, - float nodrop, - void(float _spawnflag) spawnproc, - float _respawntime, - float() physproc, - void() enterproc, - void(float extflag) exitfunc, - void() dieproc, - void() thinkproc, - float use_csqc, - float _max_health, - float _max_shield) -{ - if(!autocvar_g_vehicles) - return FALSE; - - if(self.targetname) - { - self.vehicle_controller = find(world, target, self.targetname); - if(!self.vehicle_controller) - { - bprint("^1WARNING: ^7Vehicle with invalid .targetname\n"); - } - else - { - self.team = self.vehicle_controller.team; - self.use = vehicle_use; - - if(teamplay) - { - if(self.vehicle_controller.team == 0) - self.active = ACTIVE_NOT; - else - self.active = ACTIVE_ACTIVE; - } - } - } - - precache_sound("onslaught/ons_hit2.wav"); - precache_sound("onslaught/electricity_explode.wav"); - - - addstat(STAT_HUD, AS_INT, hud); - addstat(STAT_VEHICLESTAT_HEALTH, AS_INT, vehicle_health); - addstat(STAT_VEHICLESTAT_SHIELD, AS_INT, vehicle_shield); - addstat(STAT_VEHICLESTAT_ENERGY, AS_INT, vehicle_energy); - - addstat(STAT_VEHICLESTAT_AMMO1, AS_INT, vehicle_ammo1); - addstat(STAT_VEHICLESTAT_RELOAD1, AS_INT, vehicle_reload1); - - addstat(STAT_VEHICLESTAT_AMMO2, AS_INT, vehicle_ammo2); - addstat(STAT_VEHICLESTAT_RELOAD2, AS_INT, vehicle_reload2); - - if(bodymodel == "") - error("vehicles: missing bodymodel!"); - - if(hudmodel == "") - error("vehicles: missing hudmodel!"); - - if(net_name == "") - self.netname = self.classname; - else - self.netname = net_name; - - if(self.team && !teamplay) - self.team = 0; - - self.vehicle_flags |= VHF_ISVEHICLE; - - setmodel(self, bodymodel); - - self.vehicle_viewport = spawn(); - self.vehicle_hudmodel = spawn(); - self.tur_head = spawn(); - self.tur_head.owner = self; - self.takedamage = DAMAGE_AIM; - self.bot_attack = TRUE; - self.iscreature = TRUE; - self.teleportable = FALSE; // no teleporting for vehicles, too buggy - self.damagedbycontents = TRUE; - self.hud = vhud; - self.tur_health = _max_health; - self.tur_head.tur_health = _max_shield; - self.vehicle_die = dieproc; - self.vehicle_exit = exitfunc; - self.vehicle_enter = enterproc; - self.PlayerPhysplug = physproc; - self.event_damage = func_null; - self.touch = vehicles_touch; - self.think = vehicles_spawn; - self.nextthink = time; - self.vehicle_respawntime = _respawntime; - self.vehicle_spawn = spawnproc; - self.effects = EF_NODRAW; - self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID; - if(!autocvar_g_vehicles_delayspawn) - self.nextthink = time + game_starttime; - else - self.nextthink = time + _respawntime + (random() * autocvar_g_vehicles_delayspawn_jitter); - - if(autocvar_g_playerclip_collisions) - self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP; - - if(autocvar_g_nodepthtestplayers) - self.effects = self.effects | EF_NODEPTHTEST; - - if(autocvar_g_fullbrightplayers) - self.effects = self.effects | EF_FULLBRIGHT; - - setmodel(self.vehicle_hudmodel, hudmodel); - setmodel(self.vehicle_viewport, "null"); - - if(topmodel != "") - { - setmodel(self.tur_head, topmodel); - setattachment(self.tur_head, self, toptag); - setattachment(self.vehicle_hudmodel, self.tur_head, hudtag); - setattachment(self.vehicle_viewport, self.vehicle_hudmodel, viewtag); - } - else - { - setattachment(self.tur_head, self, ""); - setattachment(self.vehicle_hudmodel, self, hudtag); - setattachment(self.vehicle_viewport, self.vehicle_hudmodel, viewtag); - } - - setsize(self, min_s, max_s); - if not (nodrop) - { - setorigin(self, self.origin); - tracebox(self.origin + '0 0 100', min_s, max_s, self.origin - '0 0 10000', MOVE_WORLDONLY, self); - setorigin(self, trace_endpos); - } - - self.pos1 = self.origin; - self.pos2 = self.angles; - self.tur_head.team = self.team; - - if(MUTATOR_CALLHOOK(VehicleSpawn)) - return FALSE; - - return TRUE; -} - -vector vehicle_aimturret(entity _vehic, vector _target, entity _turrret, string _tagname, - float _pichlimit_min, float _pichlimit_max, - float _rotlimit_min, float _rotlimit_max, float _aimspeed) -{ - vector vtmp, vtag; - float ftmp; - vtag = gettaginfo(_turrret, gettagindex(_turrret, _tagname)); - vtmp = vectoangles(normalize(_target - vtag)); - vtmp = AnglesTransform_ToAngles(AnglesTransform_LeftDivide(AnglesTransform_FromAngles(_vehic.angles), AnglesTransform_FromAngles(vtmp))) - _turrret.angles; - vtmp = AnglesTransform_Normalize(vtmp, TRUE); - ftmp = _aimspeed * frametime; - vtmp_y = bound(-ftmp, vtmp_y, ftmp); - vtmp_x = bound(-ftmp, vtmp_x, ftmp); - _turrret.angles_y = bound(_rotlimit_min, _turrret.angles_y + vtmp_y, _rotlimit_max); - _turrret.angles_x = bound(_pichlimit_min, _turrret.angles_x + vtmp_x, _pichlimit_max); - return vtag; -} - -void vehicles_gib_explode() -{ - sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTEN_NORM); - pointparticles(particleeffectnum("explosion_small"), randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1); - remove(self); -} - -void vehicles_gib_think() -{ - self.alpha -= 0.1; - if(self.cnt >= time) - remove(self); - else - self.nextthink = time + 0.1; -} - -entity vehicle_tossgib(entity _template, vector _vel, string _tag, float _burn, float _explode, float _maxtime, vector _rot) -{ - entity _gib = spawn(); - setmodel(_gib, _template.model); - setorigin(_gib, gettaginfo(self, gettagindex(self, _tag))); - _gib.velocity = _vel; - _gib.movetype = MOVETYPE_TOSS; - _gib.solid = SOLID_CORPSE; - _gib.colormod = '-0.5 -0.5 -0.5'; - _gib.effects = EF_LOWPRECISION; - _gib.avelocity = _rot; - - if(_burn) - _gib.effects |= EF_FLAME; - - if(_explode) - { - _gib.think = vehicles_gib_explode; - _gib.nextthink = time + random() * _explode; - _gib.touch = vehicles_gib_explode; - } - else - { - _gib.cnt = time + _maxtime; - _gib.think = vehicles_gib_think; - _gib.nextthink = time + _maxtime - 1; - _gib.alpha = 1; - } - return _gib; -} - -/* -vector predict_target(entity _targ, vector _from, float _shot_speed) -{ - float i; // loop - float _distance; // How far to target - float _impact_time; // How long untill projectile impacts - vector _predict_pos; // Predicted enemy location - vector _original_origin;// Where target is before predicted - - _original_origin = real_origin(_targ); // Typicaly center of target BBOX - - _predict_pos = _original_origin; - for(i = 0; i < 4; ++i) // Loop a few times to increase prediction accuracy (increase loop count if accuracy is to low) - { - _distance = vlen(_predict_pos - _from); // Get distance to previos predicted location - _impact_time = _distance / _shot_speed; // Calculate impact time - _predict_pos = _original_origin + _targ.velocity * _impact_time; // Calculate new predicted location - } - - return _predict_pos; -} -*/ diff --git a/qcsrc/server/vehicles/vehicles.qh b/qcsrc/server/vehicles/vehicles.qh deleted file mode 100644 index 549dfeab7f..0000000000 --- a/qcsrc/server/vehicles/vehicles.qh +++ /dev/null @@ -1,10 +0,0 @@ -#ifdef VEHICLES_ENABLED -#include "vehicles.qc" - -#include "racer.qc" -#include "spiderbot.qc" -#include "raptor.qc" -#ifndef VEHICLES_NO_UNSTABLE -#include "bumblebee.qc" -#endif -#endif diff --git a/qcsrc/server/vehicles/vehicles_def.qh b/qcsrc/server/vehicles/vehicles_def.qh deleted file mode 100644 index 393563f18b..0000000000 --- a/qcsrc/server/vehicles/vehicles_def.qh +++ /dev/null @@ -1,75 +0,0 @@ -// #define VEHICLES_USE_ODE -#define VEHICLES_ENABLED -#ifdef VEHICLES_ENABLED - -.float vehicle_flags; -const float VHF_ISVEHICLE = 2; /// Indicates vehicle -const float VHF_HASSHIELD = 4; /// Vehicle has shileding -const float VHF_SHIELDREGEN = 8; /// Vehicles shield regenerates -const float VHF_HEALTHREGEN = 16; /// Vehicles health regenerates -const float VHF_ENERGYREGEN = 32; /// Vehicles energy regenerates -const float VHF_DEATHEJECT = 64; /// Vehicle ejects pilot upon fatal damage -const float VHF_MOVE_GROUND = 128; /// Vehicle moves on gound -const float VHF_MOVE_HOVER = 256; /// Vehicle hover close to gound -const float VHF_MOVE_FLY = 512; /// Vehicle is airborn -const float VHF_DMGSHAKE = 1024; /// Add random velocity each frame if health < 50% -const float VHF_DMGROLL = 2048; /// Add random angles each frame if health < 50% -const float VHF_DMGHEADROLL = 4096; /// Add random head angles each frame if health < 50% -const float VHF_MULTISLOT = 8192; /// Vehicle has multiple player slots -const float VHF_PLAYERSLOT = 16384; /// This ent is a player slot on a multi-person vehicle - -.entity gun1; -.entity gun2; -.entity gun3; -.entity vehicle_shieldent; /// Entity to disply the shild effect on damage -.entity vehicle; -.entity vehicle_viewport; -.entity vehicle_hudmodel; -.entity vehicle_controller; - -.entity gunner1; -.entity gunner2; - -.float vehicle_health; /// If self is player this is 0..100 indicating precentage of health left on vehicle. If self is vehile, this is the real health value. -.float vehicle_energy; /// If self is player this is 0..100 indicating precentage of energy left on vehicle. If self is vehile, this is the real energy value. -.float vehicle_shield; /// If self is player this is 0..100 indicating precentage of shield left on vehicle. If self is vehile, this is the real shield value. - -.float vehicle_ammo1; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real ammo1 value. -.float vehicle_reload1; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real reload1 value. -.float vehicle_ammo2; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real ammo2 value. -.float vehicle_reload2; /// If self is player this field's use depends on the individual vehile. If self is vehile, this is the real reload2 value. - -.float sound_nexttime; -#define VOL_VEHICLEENGINE 1 - -.float hud; -.float dmg_time; -.float vehicle_respawntime; -//.void() vehicle_spawn; - -void vehicles_exit(float eject); -.void(float exit_flags) vehicle_exit; -const float VHEF_NORMAL = 0; /// User pressed exit key -const float VHEF_EJECT = 1; /// User pressed exit key 3 times fast (not implemented) or vehile is dying -const float VHEF_RELESE = 2; /// Release ownership, client possibly allready dissconnected / went spec / changed team / used "kill" (not implemented) - -const float SVC_SETVIEWPORT = 5; // Net.Protocol 0x05 -const float SVC_SETVIEWANGLES = 10; // Net.Protocol 0x0A -const float SVC_UPDATEENTITY = 128; // Net.Protocol 0x80 - -.void() vehicle_enter; /// Vehicles custom funciton to be executed when owner exit it -.void() vehicle_die; /// Vehicles custom function to be executed when vehile die -#define VHSF_NORMAL 0 -#define VHSF_FACTORY 2 -.void(float _spawnflag) vehicle_spawn; /// Vehicles custom fucntion to be efecuted when vehicle (re)spawns -.float(float _imp) vehicles_impusle; -.float vehicle_weapon2mode = volly_counter; - -//ยง .void() vehicle_factory() - -#ifdef VEHICLES_USE_ODE -void(entity e, float physics_enabled) physics_enable = #540; // enable or disable physics on object -void(entity e, vector force, vector force_pos) physics_addforce = #541; // apply a force from certain origin, length of force vector is power of force -void(entity e, vector torque) physics_addtorque = #542; // add relative torque -#endif // VEHICLES_USE_ODE -#endif // VEHICLES_ENABLED diff --git a/vehicles.cfg b/vehicles.cfg index d28aa4cad6..70d23354d8 100644 --- a/vehicles.cfg +++ b/vehicles.cfg @@ -15,6 +15,10 @@ set g_vehicles_crush_force 50 set cl_vehicles_hudscale 0.5 +set g_vehicles_enter 0 "require pressing use key to enter a vehicle" +set g_vehicles_enter_radius 250 +set g_vehicles_steal 1 "allow stealing enemy vehicles in teamplay modes" + set g_vehicles_delayspawn 1 set g_vehicles_delayspawn_jitter 10