4 #include "../movetypes.qh"
5 #include "../movetypes.qh"
6 #include "../prandom.qh"
7 #include "../scoreboard.qh"
8 #include "../t_items.qh"
10 #include "../../common/buffs.qh"
11 #include "../../common/constants.qh"
12 #include "../../common/stats.qh"
13 #include "../../common/util.qh"
15 #include "../../csqcmodellib/cl_model.qh"
19 const string vNULL = "gfx/vehicles/null.tga";
20 const string vFRAME = "gfx/vehicles/frame.tga";
22 const string vMODEL_SHIELD = "gfx/vehicles/vh-shield.tga";
23 const string vMODEL_BUMBLE = "gfx/vehicles/bumb.tga";
24 const string vMODEL_BUMBLE_WEAPON1 = "gfx/vehicles/bumb_lgun.tga";
25 const string vMODEL_BUMBLE_WEAPON2 = "gfx/vehicles/bumb_rgun.tga";
26 const string vMODEL_GUNNER = "gfx/vehicles/bumb_side.tga";
27 const string vMODEL_GUNNER_WEAPON1 = "gfx/vehicles/bumb_side_gun.tga";
28 const string vMODEL_RAPTOR = "gfx/vehicles/raptor.tga";
29 const string vMODEL_RAPTOR_WEAPON1 = "gfx/vehicles/raptor_guns.tga";
30 const string vMODEL_RAPTOR_WEAPON2 = "gfx/vehicles/raptor_bombs.tga";
31 const string vMODEL_SPIDER = "gfx/vehicles/sbot.tga";
32 const string vMODEL_SPIDER_WEAPON1 = "gfx/vehicles/sbot_mguns.tga";
33 const string vMODEL_SPIDER_WEAPON2 = "gfx/vehicles/sbot_rpods.tga";
34 const string vMODEL_RACER = "gfx/vehicles/waki.tga";
35 const string vMODEL_RACER_WEAPON1 = "gfx/vehicles/waki_guns.tga";
36 const string vMODEL_RACER_WEAPON2 = "gfx/vehicles/waki_rockets.tga";
38 const string vBAR_HEALTH = "gfx/vehicles/bar_up_left.tga";
39 const string vBAR_SHIELD = "gfx/vehicles/bar_dwn_left.tga";
40 const string vBAR_AMMO1 = "gfx/vehicles/bar_up_right.tga";
41 const string vBAR_AMMO2 = "gfx/vehicles/bar_dwn_right.tga";
43 const string vICON_HEALTH = "gfx/vehicles/health.tga";
44 const string vICON_SHIELD = "gfx/vehicles/shield.tga";
45 const string vICON_AMMO1 = "gfx/vehicles/bullets.tga";
46 const string vICON_AMMO2 = "gfx/vehicles/rocket.tga";
48 const string vCROSS_AIM = "gfx/vehicles/crosshair_aim.tga";
49 const string vCROSS_DROP = "gfx/vehicles/crosshair_drop.tga";
50 const string vCROSS_HEAL = "gfx/vehicles/crosshair_heal.tga";
51 const string vCROSS_HINT = "gfx/vehicles/crosshair_hint.tga";
52 const string vCROSS_LOCK = "gfx/vehicles/crosshair_lock.tga";
53 const string vCROSS_TAG = "gfx/vehicles/crosshair_tag.tga.tga";
55 const int SBRM_FIRST = 1;
56 const int SBRM_VOLLY = 1;
57 const int SBRM_GUIDE = 2;
58 const int SBRM_ARTILLERY = 3;
59 const int SBRM_LAST = 3;
61 const int RSM_FIRST = 1;
62 const int RSM_BOMB = 1;
63 const int RSM_FLARE = 2;
64 const int RSM_LAST = 2;
66 const int MAX_AXH = 4;
67 entity AuxiliaryXhairs[MAX_AXH];
68 entityclass(AuxiliaryXhair);
69 class(AuxiliaryXhair) .string axh_image;
70 class(AuxiliaryXhair) .float axh_fadetime;
71 class(AuxiliaryXhair) .float axh_drawflag;
80 void AuxiliaryXhair_Draw2D()
82 if (scoreboard_showscores)
85 vector size = draw_getimagesize(self.axh_image) * autocvar_cl_vehicles_crosshair_size;
86 vector pos = project_3d_to_2d(self.move_origin) - 0.5 * size;
88 if (!(pos.z < 0 || pos.x < 0 || pos.y < 0 || pos.x > vid_conwidth || pos.y > vid_conheight))
92 drawpic(pos, self.axh_image, size, self.colormod, autocvar_crosshair_alpha * self.alpha, self.axh_drawflag);
95 if(time - self.cnt > self.axh_fadetime)
96 self.draw2d = func_null;
99 void Net_AuXair2(bool bIsNew)
101 int axh_id = bound(0, ReadByte(), MAX_AXH);
102 entity axh = AuxiliaryXhairs[axh_id];
104 if(axh == world || wasfreed(axh)) // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
107 axh.draw2d = func_null;
108 axh.drawmask = MASK_NORMAL;
109 axh.axh_drawflag = DRAWFLAG_ADDITIVE;
110 axh.axh_fadetime = 0.1;
111 axh.axh_image = vCROSS_HINT;
114 AuxiliaryXhairs[axh_id] = axh;
117 axh.move_origin_x = ReadCoord();
118 axh.move_origin_y = ReadCoord();
119 axh.move_origin_z = ReadCoord();
120 axh.colormod_x = ReadByte() / 255;
121 axh.colormod_y = ReadByte() / 255;
122 axh.colormod_z = ReadByte() / 255;
124 axh.draw2d = AuxiliaryXhair_Draw2D;
127 void Net_VehicleSetup()
129 int hud_id = ReadByte();
132 if(hud_id > HUD_VEHICLE_LAST)
134 weapon2mode = hud_id - HUD_VEHICLE_LAST;
138 // hud_id == 0 means we exited a vehicle, so stop alarm sound/s
141 sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
142 sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
146 hud_id = bound(HUD_VEHICLE_FIRST, hud_id, HUD_VEHICLE_LAST);
148 // Init auxiliary crosshairs
150 for(i = 0; i < MAX_AXH; ++i)
152 entity axh = AuxiliaryXhairs[i];
154 if(axh != world && !wasfreed(axh)) // MADNESS? THIS IS QQQQCCCCCCCCC (wasfreed, why do you exsist?)
158 axh.draw2d = func_null;
159 axh.drawmask = MASK_NORMAL;
160 axh.axh_drawflag = DRAWFLAG_NORMAL;
161 axh.axh_fadetime = 0.1;
162 axh.axh_image = vCROSS_HINT;
164 AuxiliaryXhairs[i] = axh;
170 AuxiliaryXhairs[0].axh_image = vCROSS_HINT; // Minigun1
171 AuxiliaryXhairs[1].axh_image = vCROSS_HINT; // Minigun2
175 AuxiliaryXhairs[0].axh_image = vCROSS_LOCK; // Rocket
179 AuxiliaryXhairs[1].axh_image = vCROSS_LOCK;
183 AuxiliaryXhairs[0].axh_image = vCROSS_LOCK; // Raygun-locked
184 AuxiliaryXhairs[1].axh_image = vCROSS_TAG; // Gunner1
185 AuxiliaryXhairs[2].axh_image = vCROSS_TAG; // Gunner2
188 case HUD_BUMBLEBEE_GUN:
189 AuxiliaryXhairs[0].axh_image = vCROSS_TAG; // Plasma cannons
190 AuxiliaryXhairs[1].axh_image = vCROSS_TAG; // Raygun
195 void Vehicles_drawHUD(
205 if(autocvar_r_letterbox)
208 if(scoreboard_showscores)
212 vector hudSize = '0 0 0';
213 vector hudPos = '0 0 0';
214 vector tmpSize = '0 0 0';
215 vector tmpPos = '0 0 0';
217 float hudAlpha = autocvar_hud_panel_fg_alpha;
218 float barAlpha = autocvar_hud_progressbar_alpha * hudAlpha;
219 float blinkValue = 0.55 + sin(time * 7) * 0.45;
221 float health = getstati(STAT_VEHICLESTAT_HEALTH) * 0.01;
222 float shield = getstati(STAT_VEHICLESTAT_SHIELD) * 0.01;
223 float energy = getstati(STAT_VEHICLESTAT_ENERGY) * 0.01;
224 float ammo1 = getstati(STAT_VEHICLESTAT_AMMO1) * 0.01;
225 float reload1 = getstati(STAT_VEHICLESTAT_RELOAD1) * 0.01;
226 float ammo2 = getstati(STAT_VEHICLESTAT_AMMO2) * 0.01;
227 float reload2 = getstati(STAT_VEHICLESTAT_RELOAD2) * 0.01;
229 // HACK to deal with the inconcistent use of the vehicle stats
230 ammo1 = (ammo1) ? ammo1 : energy;
233 hudSize = draw_getimagesize(vFRAME) * autocvar_cl_vehicles_hudscale;
234 hudPos.x = (vid_conwidth - hudSize.x) / 2;
235 hudPos.y = vid_conheight - hudSize.y;
237 if(teamplay && autocvar_hud_panel_bg_color_team)
238 drawpic(hudPos, vFRAME, hudSize, myteamcolors * autocvar_hud_panel_bg_color_team, autocvar_hud_panel_bg_alpha, DRAWFLAG_NORMAL);
240 drawpic(hudPos, vFRAME, hudSize, autocvar_hud_panel_bg_color, autocvar_hud_panel_bg_alpha, DRAWFLAG_NORMAL);
243 tmpSize.x = hudSize.x / 3;
244 tmpSize.y = hudSize.y;
245 tmpPos.x = hudPos.x + hudSize.x / 3;
249 drawpic(tmpPos, modelBase, tmpSize, '1 0 0' + '0 1 1' * blinkValue, hudAlpha, DRAWFLAG_NORMAL);
251 drawpic(tmpPos, modelBase, tmpSize, '1 1 1' * health + '1 0 0' * (1 - health), hudAlpha, DRAWFLAG_NORMAL);
253 drawpic(tmpPos, modelWeapon1, tmpSize, '1 1 1' * ammo1 + '1 0 0' * (1 - ammo1), hudAlpha, DRAWFLAG_NORMAL);
254 drawpic(tmpPos, modelWeapon2, tmpSize, '1 1 1' * ammo2 + '1 0 0' * (1 - ammo2), hudAlpha, DRAWFLAG_NORMAL);
255 drawpic(tmpPos, vMODEL_SHIELD, tmpSize, '1 1 1' * shield + '1 0 0' * (1 - shield), hudAlpha * shield, DRAWFLAG_NORMAL);
258 tmpSize.y = hudSize.y / 2;
259 tmpPos.x = hudPos.x + hudSize.x * (32/768);
262 drawsetcliparea(tmpPos.x + (tmpSize.x * (1 - health)), tmpPos.y, tmpSize.x, tmpSize.y);
263 drawpic(tmpPos, vBAR_HEALTH, tmpSize, autocvar_hud_progressbar_health_color, barAlpha, DRAWFLAG_NORMAL);
266 tmpPos.y = hudPos.y + hudSize.y / 2;
268 drawsetcliparea(tmpPos.x + (tmpSize.x * (1 - shield)), tmpPos.y, tmpSize.x, tmpSize.y);
269 drawpic(tmpPos, vBAR_SHIELD, tmpSize, autocvar_hud_progressbar_armor_color, barAlpha, DRAWFLAG_NORMAL);
272 tmpPos.x = hudPos.x + hudSize.x * (480/768);
276 drawsetcliparea(tmpPos.x, tmpPos.y, tmpSize.x * ammo1, tmpSize.y);
278 drawsetcliparea(tmpPos.x, tmpPos.y, tmpSize.x * reload1, tmpSize.y);
280 drawpic(tmpPos, vBAR_AMMO1, tmpSize, colorAmmo1, barAlpha, DRAWFLAG_NORMAL);
283 tmpPos.y = hudPos.y + hudSize.y / 2;
286 drawsetcliparea(tmpPos.x, tmpPos.y, tmpSize.x * ammo2, tmpSize.y);
288 drawsetcliparea(tmpPos.x, tmpPos.y, tmpSize.x * reload2, tmpSize.y);
290 drawpic(tmpPos, vBAR_AMMO2, tmpSize, colorAmmo2, barAlpha, DRAWFLAG_NORMAL);
294 tmpSize.x = hudSize.x * (80/768);
295 tmpSize.y = hudSize.y * (80/256);
296 tmpPos.x = hudPos.x + hudSize.x * (56/768);
297 tmpPos.y = hudPos.y + hudSize.y * (48/256);
301 if(alarm1time < time)
303 alarm1time = time + 2;
304 sound(self, CH_PAIN_SINGLE, "vehicles/alarm.wav", VOL_BASEVOICE, ATTEN_NONE);
306 drawpic(tmpPos, vICON_HEALTH, tmpSize, '1 1 1', hudAlpha * blinkValue, DRAWFLAG_NORMAL);
312 sound(self, CH_PAIN_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
315 drawpic(tmpPos, vICON_HEALTH, tmpSize, '1 1 1', hudAlpha, DRAWFLAG_NORMAL);
319 tmpPos.y = hudPos.y + hudSize.y / 2;
323 if(alarm2time < time)
325 alarm2time = time + 1;
326 sound(self, CH_TRIGGER_SINGLE, "vehicles/alarm_shield.wav", VOL_BASEVOICE, ATTEN_NONE);
328 drawpic(tmpPos, vICON_SHIELD, tmpSize, '1 1 1', hudAlpha * blinkValue, DRAWFLAG_NORMAL);
334 sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASEVOICE, ATTEN_NONE);
337 drawpic(tmpPos, vICON_SHIELD, tmpSize, '1 1 1', hudAlpha, DRAWFLAG_NORMAL);
341 tmpPos.x = hudPos.x + hudSize.x * (632/768);
342 tmpPos.y = hudPos.y + hudSize.y * (48/256);
345 drawpic(tmpPos, iconAmmo1, tmpSize, '1 1 1', hudAlpha, DRAWFLAG_NORMAL);
347 drawpic(tmpPos, iconAmmo1, tmpSize, '1 1 1', hudAlpha * 0.2, DRAWFLAG_NORMAL);
350 tmpPos.y = hudPos.y + hudSize.y / 2;
353 drawpic(tmpPos, iconAmmo2, tmpSize, '1 1 1', hudAlpha, DRAWFLAG_NORMAL);
355 drawpic(tmpPos, iconAmmo2, tmpSize, '1 1 1', hudAlpha * 0.2, DRAWFLAG_NORMAL);
357 // Bumblebee gunner crosshairs
358 if(hud == HUD_BUMBLEBEE)
360 tmpSize = '1 1 1' * hud_fontsize;
361 tmpPos.x = hudPos.x + hudSize.x * (520/768);
363 if(!AuxiliaryXhairs[1].draw2d)
365 tmpPos.y = hudPos.y + hudSize.y * (96/256) - tmpSize.y;
366 drawstring(tmpPos, _("No right gunner!"), tmpSize, '1 1 1', hudAlpha * blinkValue, DRAWFLAG_NORMAL);
369 if(!AuxiliaryXhairs[2].draw2d)
371 tmpPos.y = hudPos.y + hudSize.y * (160/256);
372 drawstring(tmpPos, _("No left gunner!"), tmpSize, '1 1 1', hudAlpha * blinkValue, DRAWFLAG_NORMAL);
376 // Raptor bomb crosshair
377 if(hud == HUD_RAPTOR && weapon2mode != RSM_FLARE)
384 dropmark.owner = self;
385 dropmark.gravity = 1;
390 setorigin(dropmark, pmove_org);
391 dropmark.velocity = pmove_vel;
392 tracetoss(dropmark, self);
394 where = project_3d_to_2d(trace_endpos);
396 setorigin(dropmark, trace_endpos);
397 tmpSize = draw_getimagesize(vCROSS_DROP) * autocvar_cl_vehicles_crosshair_size;
399 if (!(where.z < 0 || where.x < 0 || where.y < 0 || where.x > vid_conwidth || where.y > vid_conheight))
401 where.x -= tmpSize.x * 0.5;
402 where.y -= tmpSize.y * 0.5;
404 drawpic(where, vCROSS_DROP, tmpSize, '0 1 0', autocvar_crosshair_alpha * 0.9, DRAWFLAG_ADDITIVE);
405 drawpic(where, vCROSS_DROP, tmpSize, '0 1 0', autocvar_crosshair_alpha * 0.6, DRAWFLAG_NORMAL); // Ensure visibility against bright bg
407 dropmark.cnt = time + 5;
411 if(dropmark.cnt > time)
413 where = project_3d_to_2d(dropmark.origin);
414 tmpSize = draw_getimagesize(vCROSS_DROP) * autocvar_cl_vehicles_crosshair_size * 1.25;
416 if (!(where.z < 0 || where.x < 0 || where.y < 0 || where.x > vid_conwidth || where.y > vid_conheight))
418 where.x -= tmpSize.x * 0.5;
419 where.y -= tmpSize.y * 0.5;
421 drawpic(where, vCROSS_DROP, tmpSize, '1 0 0', autocvar_crosshair_alpha * 0.9, DRAWFLAG_ADDITIVE);
422 drawpic(where, vCROSS_DROP, tmpSize, '1 0 0', autocvar_crosshair_alpha * 0.6, DRAWFLAG_NORMAL); // Ensure visibility against bright bg
429 tmpSize = draw_getimagesize(crosshair) * autocvar_cl_vehicles_crosshair_size;
430 tmpPos.x = (vid_conwidth - tmpSize.x) / 2;
431 tmpPos.y = (vid_conheight - tmpSize.y) / 2;
433 drawpic(tmpPos, crosshair, tmpSize, '1 1 1', autocvar_crosshair_alpha, DRAWFLAG_NORMAL);
436 void CSQC_BUMBLE_HUD()
438 Vehicles_drawHUD(vMODEL_BUMBLE, vMODEL_BUMBLE_WEAPON1, vMODEL_BUMBLE_WEAPON2,
439 vICON_AMMO1, autocvar_hud_progressbar_vehicles_ammo1_color,
440 vICON_AMMO1, autocvar_hud_progressbar_vehicles_ammo1_color,
444 void CSQC_BUMBLE_GUN_HUD()
446 Vehicles_drawHUD(vMODEL_GUNNER, vMODEL_GUNNER_WEAPON1, vNULL,
447 vICON_AMMO1, autocvar_hud_progressbar_vehicles_ammo1_color,
452 void CSQC_SPIDER_HUD()
458 case SBRM_VOLLY: crosshair = vCROSS_LOCK; break;
459 case SBRM_GUIDE: crosshair = vCROSS_AIM; break;
460 default: crosshair = vCROSS_TAG;
463 Vehicles_drawHUD(vMODEL_SPIDER, vMODEL_SPIDER_WEAPON1, vMODEL_SPIDER_WEAPON2,
464 vICON_AMMO1, autocvar_hud_progressbar_vehicles_ammo1_color,
465 vICON_AMMO2, autocvar_hud_progressbar_vehicles_ammo2_color,
469 void CSQC_RAPTOR_HUD()
475 case RSM_FLARE: crosshair = vCROSS_LOCK; break;
476 default: crosshair = vCROSS_AIM;
479 Vehicles_drawHUD(vMODEL_RAPTOR, vMODEL_RAPTOR_WEAPON1, vMODEL_RAPTOR_WEAPON2,
480 vICON_AMMO1, autocvar_hud_progressbar_vehicles_ammo1_color,
481 vICON_AMMO2, autocvar_hud_progressbar_vehicles_ammo2_color,
485 void CSQC_WAKIZASHI_HUD()
487 Vehicles_drawHUD(vMODEL_RACER, vMODEL_RACER_WEAPON1, vMODEL_RACER_WEAPON2,
488 vICON_AMMO1, autocvar_hud_progressbar_vehicles_ammo1_color,
489 vICON_AMMO2, autocvar_hud_progressbar_vehicles_ammo2_color,
493 void Vehicles_Precache()
495 precache_model("models/vehicles/bomblet.md3");
496 precache_model("models/vehicles/clusterbomb.md3");
497 precache_model("models/vehicles/clusterbomb_fragment.md3");
498 precache_model("models/vehicles/rocket01.md3");
499 precache_model("models/vehicles/rocket02.md3");
501 precache_sound("vehicles/alarm.wav");
502 precache_sound("vehicles/alarm_shield.wav");
505 void RaptorCBShellfragDraw()
510 Movetype_Physics_MatchTicrate(autocvar_cl_gibs_ticrate, autocvar_cl_gibs_sloppy);
511 self.move_avelocity += randomvec() * 15;
512 self.renderflags = 0;
515 self.alpha = bound(0, self.nextthink - time, 1);
517 if(self.alpha < ALPHA_MIN_VISIBLE)
521 void RaptorCBShellfragToss(vector _org, vector _vel, vector _ang)
526 setmodel(sfrag, "models/vehicles/clusterbomb_fragment.md3");
527 setorigin(sfrag, _org);
529 sfrag.move_movetype = MOVETYPE_BOUNCE;
530 sfrag.gravity = 0.15;
531 sfrag.solid = SOLID_CORPSE;
533 sfrag.draw = RaptorCBShellfragDraw;
535 sfrag.move_origin = sfrag.origin = _org;
536 sfrag.move_velocity = _vel;
537 sfrag.move_avelocity = prandomvec() * vlen(sfrag.move_velocity);
538 sfrag.angles = self.move_angles = _ang;
540 sfrag.move_time = time;
541 sfrag.damageforcescale = 4;
543 sfrag.nextthink = time + 3;
544 sfrag.cnt = time + 2;
546 sfrag.drawmask = MASK_NORMAL;