+#include "mapvoting.qh"
#include "scoreboard.qh"
#include "teamradar.qh"
#include "../common/buffs.qh"
return bound(1, floor((sqrt(4 * item_aspect * aspect * item_count + aspect * aspect) + aspect + 0.5) / 2), item_count);
}
+ vector HUD_GetTableSize(float item_count, vector psize, float item_aspect)
+ {
+ float columns, rows;
+ float ratio, best_ratio = 0;
+ float best_columns = 1, best_rows = 1;
+ bool vertical = (psize.x / psize.y >= item_aspect);
+ if(vertical)
+ {
+ psize = eX * psize.y + eY * psize.x;
+ item_aspect = 1 / item_aspect;
+ }
+
+ rows = ceil(sqrt(item_count));
+ columns = ceil(item_count/rows);
+ while(columns >= 1)
+ {
+ ratio = (psize.x/columns) / (psize.y/rows);
+ if(ratio > item_aspect)
+ ratio = item_aspect * item_aspect / ratio;
+
+ if(ratio <= best_ratio)
+ break; // ratio starts decreasing by now, skip next configurations
+
+ best_columns = columns;
+ best_rows = rows;
+ best_ratio = ratio;
+
+ if(columns == 1)
+ break;
+
+ --columns;
+ rows = ceil(item_count/columns);
+ }
+
+ if(vertical)
+ return eX * best_rows + eY * best_columns;
+ else
+ return eX * best_columns + eY * best_rows;
+ }
+
float stringwidth_colors(string s, vector theSize)
{
return stringwidth(s, true, theSize);
float screen_ar;
vector center = '0 0 0';
float weapon_count, weapon_id;
- float row, column, rows = 0, columns;
+ float row, column, rows = 0, columns = 0;
+ bool vertical_order = true;
float aspect = autocvar_hud_panel_weapons_aspect;
float timeout = autocvar_hud_panel_weapons_timeout;
if(!weapons_stat)
for(i = WEP_FIRST; i <= WEP_LAST; i += floor((WEP_LAST-WEP_FIRST)/5))
weapons_stat |= WepSet_FromWeapon(i);
+
+ #if 0
+ /// debug code
+ if(cvar("wep_add"))
+ {
+ weapons_stat = '0 0 0';
+ float countw = 1 + floor((floor(time * cvar("wep_add"))) % WEP_COUNT);
+ for(i = WEP_FIRST; i <= countw; ++i)
+ weapons_stat |= WepSet_FromWeapon(i);
+ }
+ #endif
}
// determine which weapons are going to be shown
if((weapons_stat & WepSet_FromWeapon(weaponorder[i].weapon)) || (weaponorder[i].weapon == complain_weapon))
++weapon_count;
+
// might as well commit suicide now, no reason to live ;)
if (weapon_count == 0)
{
vector padded_panel_size = panel_size - '2 2 0' * panel_bg_padding;
// get the all-weapons layout
- rows = HUD_GetRowCount(WEP_COUNT, padded_panel_size, aspect);
- columns = ceil(WEP_COUNT / rows);
+ vector table_size = HUD_GetTableSize(WEP_COUNT, padded_panel_size, aspect);
+ columns = table_size.x;
+ rows = table_size.y;
weapon_size.x = padded_panel_size.x / columns;
weapon_size.y = padded_panel_size.y / rows;
- // reduce rows and columns as needed
// NOTE: although weapons should aways look the same even if onlyowned is enabled,
// we enlarge them a bit when possible to better match the desired aspect ratio
- if(padded_panel_size.y > padded_panel_size.x)
+ if(padded_panel_size.x / padded_panel_size.y < aspect)
{
- columns = ceil(weapon_count / rows);
+ // maximum number of rows that allows to display items with the desired aspect ratio
+ float max_rows = floor(padded_panel_size.y / (weapon_size.x / aspect));
+ columns = min(columns, ceil(weapon_count / max_rows));
rows = ceil(weapon_count / columns);
weapon_size.y = min(padded_panel_size.y / rows, weapon_size.x / aspect);
weapon_size.x = min(padded_panel_size.x / columns, aspect * weapon_size.y);
+ vertical_order = false;
}
else
{
- rows = ceil(weapon_count / columns);
+ float max_columns = floor(padded_panel_size.x / (weapon_size.y * aspect));
+ rows = min(rows, ceil(weapon_count / max_columns));
columns = ceil(weapon_count / rows);
weapon_size.x = min(padded_panel_size.x / columns, aspect * weapon_size.y);
weapon_size.y = min(padded_panel_size.y / rows, weapon_size.x / aspect);
+ vertical_order = true;
}
// reduce size of the panel
if(!rows) // if rows is > 0 onlyowned code has already updated these vars
{
- rows = HUD_GetRowCount(weapon_count, panel_size, aspect);
- columns = ceil(weapon_count/rows);
- weapon_size = eX * panel_size.x*(1/columns) + eY * panel_size.y*(1/rows);
+ vector table_size = HUD_GetTableSize(WEP_COUNT, panel_size, aspect);
+ columns = table_size.x;
+ rows = table_size.y;
+ weapon_size.x = panel_size.x / columns;
+ weapon_size.y = panel_size.y / rows;
+ vertical_order = (panel_size.x / panel_size.y >= aspect);
}
// calculate position/size for visual bar displaying ammount of ammo status
drawstring_aspect(weapon_pos + '1 1 0' * padding, s, weapon_size - '2 2 0' * padding, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
}
+ #if 0
+ /// debug code
+ if(!autocvar_hud_panel_weapons_onlyowned)
+ {
+ drawfill(weapon_pos + '1 1 0', weapon_size - '2 2 0', '1 1 1', panel_fg_alpha * 0.2, DRAWFLAG_NORMAL);
+ drawstring(weapon_pos, ftos(i + 1), label_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
+ #endif
+
// continue with new position for the next weapon
- ++row;
- if(row >= rows)
+ if(vertical_order)
{
- row = 0;
++column;
+ if(column >= columns)
+ {
+ column = 0;
+ ++row;
+ }
+ }
+ else
+ {
+ ++row;
+ if(row >= rows)
+ {
+ row = 0;
+ ++column;
+ }
}
}
// Radar (#6)
//
+
+float HUD_Radar_Clickable()
+{
+ return hud_panel_radar_mouse && !hud_panel_radar_temp_hidden;
+}
+
+void HUD_Radar_Show_Maximized(float show,float clickable)
+{
+ hud_panel_radar_maximized = show;
+ hud_panel_radar_temp_hidden = 0;
+
+ if ( show )
+ {
+ if (clickable)
+ {
+ if(autocvar_hud_cursormode)
+ setcursormode(1);
+ hud_panel_radar_mouse = 1;
+ }
+ }
+ else if ( hud_panel_radar_mouse )
+ {
+ hud_panel_radar_mouse = 0;
+ mouseClicked = 0;
+ if(autocvar_hud_cursormode)
+ if(!mv_active)
+ setcursormode(0);
+ }
+}
+void HUD_Radar_Hide_Maximized()
+{
+ HUD_Radar_Show_Maximized(false,false);
+}
+
+
+float HUD_Radar_InputEvent(float bInputType, float nPrimary, float nSecondary)
+{
+ if(!hud_panel_radar_maximized || !hud_panel_radar_mouse ||
+ autocvar__hud_configure || mv_active)
+ return false;
+
+ if(bInputType == 3)
+ {
+ mousepos_x = nPrimary;
+ mousepos_y = nSecondary;
+ return true;
+ }
+
+ if(nPrimary == K_MOUSE1)
+ {
+ if(bInputType == 0) // key pressed
+ mouseClicked |= S_MOUSE1;
+ else if(bInputType == 1) // key released
+ mouseClicked -= (mouseClicked & S_MOUSE1);
+ }
+ else if(nPrimary == K_MOUSE2)
+ {
+ if(bInputType == 0) // key pressed
+ mouseClicked |= S_MOUSE2;
+ else if(bInputType == 1) // key released
+ mouseClicked -= (mouseClicked & S_MOUSE2);
+ }
+ else if ( nPrimary == K_ESCAPE && bInputType == 0 )
+ {
+ HUD_Radar_Hide_Maximized();
+ }
+ else
+ {
+ // allow console/use binds to work without hiding the map
+ string con_keys;
+ float keys;
+ float i;
+ con_keys = strcat(findkeysforcommand("toggleconsole", 0)," ",findkeysforcommand("+use", 0)) ;
+ keys = tokenize(con_keys); // findkeysforcommand returns data for this
+ for (i = 0; i < keys; ++i)
+ {
+ if(nPrimary == stof(argv(i)))
+ return false;
+ }
+
+ if ( getstati(STAT_HEALTH) <= 0 )
+ {
+ // Show scoreboard
+ if ( bInputType < 2 )
+ {
+ con_keys = findkeysforcommand("+showscores", 0);
+ keys = tokenize(con_keys);
+ for (i = 0; i < keys; ++i)
+ {
+ if ( nPrimary == stof(argv(i)) )
+ {
+ hud_panel_radar_temp_hidden = bInputType == 0;
+ return false;
+ }
+ }
+ }
+ }
+ else if ( bInputType == 0 )
+ HUD_Radar_Hide_Maximized();
+
+ return false;
+ }
+
+ return true;
+}
+
+void HUD_Radar_Mouse()
+{
+ if ( !hud_panel_radar_mouse ) return;
+ if(mv_active) return;
+
+ if ( intermission )
+ {
+ HUD_Radar_Hide_Maximized();
+ return;
+ }
+
+ if(mouseClicked & S_MOUSE2)
+ {
+ HUD_Radar_Hide_Maximized();
+ return;
+ }
+
+ if(!autocvar_hud_cursormode)
+ {
+ mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
+
+ mousepos_x = bound(0, mousepos_x, vid_conwidth);
+ mousepos_y = bound(0, mousepos_y, vid_conheight);
+ }
+
+ HUD_Panel_UpdateCvars();
+
+
+ panel_size = autocvar_hud_panel_radar_maximized_size;
+ panel_size_x = bound(0.2, panel_size_x, 1) * vid_conwidth;
+ panel_size_y = bound(0.2, panel_size_y, 1) * vid_conheight;
+ panel_pos_x = (vid_conwidth - panel_size_x) / 2;
+ panel_pos_y = (vid_conheight - panel_size_y) / 2;
+
+ if(mouseClicked & S_MOUSE1)
+ {
+ // click outside
+ if ( mousepos_x < panel_pos_x || mousepos_x > panel_pos_x + panel_size_x ||
+ mousepos_y < panel_pos_y || mousepos_y > panel_pos_y + panel_size_y )
+ {
+ HUD_Radar_Hide_Maximized();
+ return;
+ }
+ vector pos = teamradar_texcoord_to_3dcoord(teamradar_2dcoord_to_texcoord(mousepos),view_origin_z);
+ localcmd(sprintf("cmd ons_spawn %f %f %f",pos_x,pos_y,pos_z));
+
+ HUD_Radar_Hide_Maximized();
+ return;
+ }
+
+
+ const vector cursor_size = '32 32 0';
+ drawpic(mousepos-'8 4 0', strcat("gfx/menu/", autocvar_menu_skin, "/cursor.tga"), cursor_size, '1 1 1', 0.8, DRAWFLAG_NORMAL);
+}
+
void HUD_Radar(void)
{
if (!autocvar__hud_configure)
}
}
}
+
+ if ( hud_panel_radar_temp_hidden )
+ return;
HUD_Panel_UpdateCvars();
for(tm = world; (tm = find(tm, classname, "radarlink")); )
draw_teamradar_link(tm.origin, tm.velocity, tm.team);
+
+ vector coord;
+ vector brightcolor;
for(tm = world; (tm = findflags(tm, teamradar_icon, 0xFFFFFF)); )
+ {
+ if ( hud_panel_radar_mouse )
+ if ( tm.health > 0 )
+ if ( tm.team == myteam+1 )
+ {
+ coord = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(tm.origin));
+ if ( vlen(mousepos-coord) < 8 )
+ {
+ brightcolor_x = min(1,tm.teamradar_color_x*1.5);
+ brightcolor_y = min(1,tm.teamradar_color_y*1.5);
+ brightcolor_z = min(1,tm.teamradar_color_z*1.5);
+ drawpic(coord - '8 8 0', "gfx/teamradar_icon_glow", '16 16 0', brightcolor, panel_fg_alpha, 0);
+ }
+ }
+
draw_teamradar_icon(tm.origin, tm.teamradar_icon, tm, tm.teamradar_color, panel_fg_alpha);
+ }
for(tm = world; (tm = find(tm, classname, "entcs_receiver")); )
{
color2 = GetPlayerColor(tm.sv_entnum);
draw_teamradar_player(view_origin, view_angles, '1 1 1');
drawresetcliparea();
+
+ if ( hud_panel_radar_mouse )
+ {
+ string message = "Click to select teleport destination";
+
+ if ( getstati(STAT_HEALTH) <= 0 )
+ {
+ message = "Click to select spawn location";
+ }
+
+ drawcolorcodedstring(pos + '0.5 0 0' * (mySize_x - stringwidth(message, true, hud_fontsize)) - '0 1 0' * hud_fontsize_y * 2,
+ message, hud_fontsize, hud_panel_radar_foreground_alpha, DRAWFLAG_NORMAL);
+
+ hud_panel_radar_bottom = pos_y + mySize_y + hud_fontsize_y;
+ }
}
// Score (#7)
{
if(!autocvar_hud_panel_centerprint) return;
- if (hud_configure_prev && hud_configure_prev != -1)
+ if(hud_configure_prev)
reset_centerprint_messages();
}
else
{
- if (!hud_configure_prev)
+ if(!hud_configure_prev)
reset_centerprint_messages();
if (time > hud_configure_cp_generation_time)
{
hud_fade_alpha = 1 - autocvar__menu_alpha;
}
HUD_Panel_UpdateCvars();
-
- if(scoreboard_fade_alpha)
+
+ if ( HUD_Radar_Clickable() )
+ {
+ if (hud_panel_radar_bottom >= 0.96 * vid_conheight)
+ return;
+
+ panel_pos = eY * hud_panel_radar_bottom + eX * 0.5 * (vid_conwidth - panel_size_x);
+ panel_size_y = min(panel_size_y, vid_conheight - hud_panel_radar_bottom);
+ }
+ else if(scoreboard_fade_alpha)
{
hud_fade_alpha = hud_fade_alpha_save;
wcross_alpha_goal_prev = wcross_alpha;
wcross_color_goal_prev = wcross_color;
- if(shottype == SHOTTYPE_HITTEAM || (shottype == SHOTTYPE_HITOBSTRUCTION && autocvar_crosshair_hittest_blur && !autocvar_chase_active))
+ if(spectatee_status == -1 && shottype == SHOTTYPE_HITTEAM || (shottype == SHOTTYPE_HITOBSTRUCTION && autocvar_crosshair_hittest_blur && !autocvar_chase_active))
{
wcross_blur = 1;
wcross_alpha *= 0.75;
// event chase camera
if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped
{
- if(WantEventchase())
+ float ons_roundlost = (gametype == MAPINFO_TYPE_ONSLAUGHT && getstati(STAT_ROUNDLOST));
+ entity gen = world;
+
+ if(ons_roundlost)
+ {
+ entity e;
+ for(e = world; (e = find(e, classname, "onslaught_generator")); )
+ {
+ if(e.health <= 0)
+ {
+ gen = e;
+ break;
+ }
+ }
+ if(!gen)
+ ons_roundlost = FALSE; // don't enforce the 3rd person camera if there is no dead generator to show
+ }
+ if(WantEventchase() || (!autocvar_cl_orthoview && ons_roundlost))
{
eventchase_running = true;
// make special vector since we can't use view_origin (It is one frame old as of this code, it gets set later with the results this code makes.)
vector current_view_origin = (csqcplayer ? csqcplayer.origin : pmove_org);
+ if(ons_roundlost) { current_view_origin = gen.origin; }
// detect maximum viewoffset and use it
- if(autocvar_cl_eventchase_viewoffset)
+ vector view_offset = autocvar_cl_eventchase_viewoffset;
+ if(ons_roundlost) { view_offset = autocvar_cl_eventchase_generator_viewoffset; }
+
+ if(view_offset)
{
- WarpZone_TraceLine(current_view_origin, current_view_origin + autocvar_cl_eventchase_viewoffset + ('0 0 1' * autocvar_cl_eventchase_maxs.z), MOVE_WORLDONLY, self);
- if(trace_fraction == 1) { current_view_origin += autocvar_cl_eventchase_viewoffset; }
+ WarpZone_TraceLine(current_view_origin, current_view_origin + view_offset + ('0 0 1' * autocvar_cl_eventchase_maxs.z), MOVE_WORLDONLY, self);
+ if(trace_fraction == 1) { current_view_origin += view_offset; }
else { current_view_origin.z += max(0, (trace_endpos.z - current_view_origin.z) - autocvar_cl_eventchase_maxs.z); }
}
if(!autocvar_chase_active) { cvar_set("chase_active", "-1"); }
// make the camera smooth back
- if(autocvar_cl_eventchase_speed && eventchase_current_distance < autocvar_cl_eventchase_distance)
- eventchase_current_distance += autocvar_cl_eventchase_speed * (autocvar_cl_eventchase_distance - eventchase_current_distance) * frametime; // slow down the further we get
- else if(eventchase_current_distance != autocvar_cl_eventchase_distance)
- eventchase_current_distance = autocvar_cl_eventchase_distance;
+ float chase_distance = autocvar_cl_eventchase_distance;
+ if(ons_roundlost) { chase_distance = autocvar_cl_eventchase_generator_distance; }
+
+ if(autocvar_cl_eventchase_speed && eventchase_current_distance < chase_distance)
+ eventchase_current_distance += autocvar_cl_eventchase_speed * (chase_distance - eventchase_current_distance) * frametime; // slow down the further we get
+ else if(eventchase_current_distance != chase_distance)
+ eventchase_current_distance = chase_distance;
makevectors(view_angles);
if(autocvar__hud_configure)
HUD_Panel_Mouse();
+ else
+ HUD_Radar_Mouse();
if(hud && !intermission)
{
float autocvar_g_nodepthtestitems;
float autocvar_g_nodepthtestplayers;
float autocvar_g_norecoil;
-float autocvar_g_onslaught_cp_buildhealth;
-float autocvar_g_onslaught_cp_buildtime;
-float autocvar_g_onslaught_cp_health;
-float autocvar_g_onslaught_cp_regen;
-float autocvar_g_onslaught_gen_health;
float autocvar_g_pickup_cells_max;
float autocvar_g_pickup_plasma_max;
float autocvar_g_pickup_fuel_max;
float autocvar_g_random_gravity_negative;
float autocvar_g_random_gravity_delay;
float autocvar_g_nades;
+ vector autocvar_g_nades_throw_offset;
float autocvar_g_nades_spawn;
float autocvar_g_nades_spawn_count;
float autocvar_g_nades_client_select;
float autocvar_g_spawn_near_teammate_ignore_spawnpoint_delay_death;
float autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health;
float autocvar_g_spawn_near_teammate_ignore_spawnpoint_closetodeath;
+float autocvar_g_onslaught_debug;
+float autocvar_g_onslaught_teleport_wait;
+float autocvar_g_onslaught_spawn_at_controlpoints;
+var float autocvar_g_onslaught_spawn_at_controlpoints_chance = 0.5;
+float autocvar_g_onslaught_spawn_at_controlpoints_random;
+float autocvar_g_onslaught_spawn_at_generator;
+float autocvar_g_onslaught_spawn_at_generator_chance;
+float autocvar_g_onslaught_spawn_at_generator_random;
+float autocvar_g_onslaught_cp_proxydecap;
+var float autocvar_g_onslaught_cp_proxydecap_distance = 512;
+var float autocvar_g_onslaught_cp_proxydecap_dps = 100;
+float autocvar_g_onslaught_cp_buildhealth;
+float autocvar_g_onslaught_cp_buildtime;
+float autocvar_g_onslaught_cp_health;
+float autocvar_g_onslaught_cp_regen;
+float autocvar_g_onslaught_gen_health;
+var float autocvar_g_onslaught_shield_force = 100;
+float autocvar_g_onslaught_allow_vehicle_touch;
+float autocvar_g_onslaught_round_timelimit;
+float autocvar_g_onslaught_point_limit;
+float autocvar_g_onslaught_warmup;
+float autocvar_g_onslaught_teleport_radius;
+float autocvar_g_onslaught_spawn_choose;
+float autocvar_g_onslaught_click_radius;
float autocvar_g_buffs_waypoint_distance;
float autocvar_g_buffs_randomize;
float autocvar_g_buffs_random_lifetime;
float autocvar_g_buffs_invisible_alpha;
float autocvar_g_buffs_flight_gravity;
float autocvar_g_buffs_jump_height;
+
#endif
// does nothing visible
BADCVAR("captureleadlimit_override");
BADCVAR("g_balance_kill_delay");
+ BADCVAR("g_ca_point_limit");
BADCVAR("g_ca_point_leadlimit");
BADCVAR("g_ctf_captimerecord_always");
BADCVAR("g_ctf_flag_glowtrails");
BADCVAR("g_ctf_flag_pickup_verbosename");
BADCVAR("g_domination_point_leadlimit");
BADCVAR("g_forced_respawn");
+ BADCVAR("g_freezetag_point_limit");
+ BADCVAR("g_freezetag_point_leadlimit");
BADCVAR("g_keyhunt_point_leadlimit");
BADPREFIX("g_mod_");
+ BADCVAR("g_invasion_point_limit");
BADCVAR("g_nexball_goalleadlimit");
+ BADCVAR("g_tdm_point_limit");
+ BADCVAR("g_tdm_point_leadlimit");
BADCVAR("leadlimit_and_fraglimit");
BADCVAR("leadlimit_override");
BADCVAR("pausable");
head.winning = 0;
}
-// Onslaught winning condition:
-// game terminates if only one team has a working generator (or none)
-float WinningCondition_Onslaught()
-{
- entity head;
- float t1, t2, t3, t4;
-
- WinningConditionHelper(); // set worldstatus
-
- if(warmup_stage)
- return WINNING_NO;
-
- // first check if the game has ended
- t1 = t2 = t3 = t4 = 0;
- head = find(world, classname, "onslaught_generator");
- while (head)
- {
- if (head.health > 0)
- {
- if (head.team == NUM_TEAM_1) t1 = 1;
- if (head.team == NUM_TEAM_2) t2 = 1;
- if (head.team == NUM_TEAM_3) t3 = 1;
- if (head.team == NUM_TEAM_4) t4 = 1;
- }
- head = find(head, classname, "onslaught_generator");
- }
- if (t1 + t2 + t3 + t4 < 2)
- {
- // game over, only one team remains (or none)
- ClearWinners();
- if (t1) SetWinners(team, NUM_TEAM_1);
- if (t2) SetWinners(team, NUM_TEAM_2);
- if (t3) SetWinners(team, NUM_TEAM_3);
- if (t4) SetWinners(team, NUM_TEAM_4);
- dprint("Have a winner, ending game.\n");
- return WINNING_YES;
- }
-
- // Two or more teams remain
- return WINNING_NO;
-}
-
// Assault winning condition: If the attackers triggered a round end (by fulfilling all objectives)
// they win. Otherwise the defending team wins once the timelimit passes.
void assault_new_round();
return;
}
- if(g_onslaught)
- timelimit = 0; // ONS has its own overtime rule
-
float wantovertime;
wantovertime = 0;
{
checkrules_status = WinningCondition_LMS();
}
- else if (g_onslaught)
- {
- checkrules_status = WinningCondition_Onslaught(); // TODO remove this?
- }
else
{
checkrules_status = WinningCondition_Scores(fraglimit, leadlimit);