#include "mapvoting.qh"
-#include <client/autocvars.qh>
#include <client/draw.qh>
#include <client/hud/_mod.qh>
#include <client/hud/panel/scoreboard.qh>
float mv_timeout;
float mv_top2_time;
float mv_top2_alpha;
+float mv_winner_time;
+float mv_winner_alpha;
int mv_selection;
int mv_columns;
int mv_mouse_selection;
int mv_selection_keyboard;
-float gametypevote;
+bool gametypevote;
string mapvote_chosenmap;
vector gtv_text_size;
vector gtv_text_size_small;
delete(title);
}
+void MapVote_DrawMapPicture(string pic, vector pos, vector img_size, float theAlpha)
+{
+ if(pic == "")
+ drawfill(pos, img_size, '.5 .5 .5', .7 * theAlpha, DRAWFLAG_NORMAL);
+ else
+ {
+ if(drawgetimagesize(pic) == '0 0 0')
+ drawpic(pos, draw_UseSkinFor("nopreview_map"), img_size, '1 1 1', theAlpha, DRAWFLAG_NORMAL);
+ else
+ drawpic(pos, pic, img_size, '1 1 1', theAlpha, DRAWFLAG_NORMAL);
+ }
+}
+
void MapVote_DrawMapItem(vector pos, float isize, float tsize, string map, string pic, float _count, int id)
{
TC(int, id);
float theAlpha;
if (!(mv_flags[id] & GTV_AVAILABLE) && mv_top2_alpha)
theAlpha = mv_top2_alpha;
+ else if (mv_winner && mv_winner_alpha)
+ theAlpha = mv_winner_alpha;
else
theAlpha = 1;
theAlpha *= panel_fg_alpha;
- // Highlight selected item
- if(id == mv_selection && (mv_flags[id] & GTV_AVAILABLE))
- drawfill(rect_pos, rect_size, '1 1 1', 0.1 * panel_fg_alpha, DRAWFLAG_NORMAL);
-
- // Highlight current vote
vector rgb = MapVote_RGB(id);
- if(id == mv_ownvote)
+
+ // Highlight selected item
+ if (!mv_winner)
{
- drawfill(rect_pos, rect_size, rgb, 0.1 * theAlpha, DRAWFLAG_NORMAL);
- drawborderlines(autocvar_hud_panel_mapvote_highlight_border, rect_pos, rect_size, rgb, theAlpha, DRAWFLAG_NORMAL);
+ if(id == mv_selection && (mv_flags[id] & GTV_AVAILABLE))
+ drawfill(rect_pos, rect_size, '1 1 1', 0.1 * panel_fg_alpha, DRAWFLAG_NORMAL);
+
+ // Highlight current vote
+ if(id == mv_ownvote)
+ {
+ drawfill(rect_pos, rect_size, rgb, 0.1 * theAlpha, DRAWFLAG_NORMAL);
+ drawborderlines(autocvar_hud_panel_mapvote_highlight_border, rect_pos, rect_size, rgb, theAlpha, DRAWFLAG_NORMAL);
+ }
}
drawstring(text_pos, label, hud_fontsize, rgb, theAlpha, DRAWFLAG_NORMAL);
- if(pic == "")
- {
- drawfill(pos, img_size, '.5 .5 .5', .7 * theAlpha, DRAWFLAG_NORMAL);
- }
- else
- {
- if(drawgetimagesize(pic) == '0 0 0')
- drawpic(pos, draw_UseSkinFor("nopreview_map"), img_size, '1 1 1', theAlpha, DRAWFLAG_NORMAL);
- else
- drawpic(pos, pic, img_size, '1 1 1', theAlpha, DRAWFLAG_NORMAL);
- }
+ MapVote_DrawMapPicture(pic, pos, img_size, theAlpha);
}
void MapVote_DrawAbstain(vector pos, float isize, float tsize, float _count, int id)
float MapVote_Selection(vector topleft, vector cellsize, float rows, float columns)
{
-
float c, r;
+ if (mv_winner)
+ return -1;
mv_mouse_selection = -1;
return mv_mouse_selection;
}
-vector prev_mousepos;
// draws map vote or gametype vote
void MapVote_Draw()
{
HUD_Panel_LoadCvars();
- if (!autocvar_hud_cursormode)
- {
- if (mousepos.x != prev_mousepos.x || mousepos.y != prev_mousepos.y)
- {
- mv_selection_keyboard = 0;
- prev_mousepos = mousepos;
- }
- }
-
center = (vid_conwidth - 1)/2;
xmin = vid_conwidth * 0.08;
xmax = vid_conwidth - xmin;
draw_beginBoldFont();
map = ((gametypevote) ? _("Decide the gametype") : _("Vote for a map"));
- pos.x = center - stringwidth(map, false, hud_fontsize * 2) * 0.5;
- drawstring(pos, map, hud_fontsize * 2, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ if (!mv_winner)
+ {
+ pos.x = center - stringwidth(map, false, hud_fontsize * 2) * 0.5;
+ drawstring(pos, map, hud_fontsize * 2, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
pos.y += hud_fontsize.y * 2;
if( mapvote_chosenmap != "" )
draw_endBoldFont();
- i = ceil(max(0, mv_timeout - time));
- map = sprintf(_("%d seconds left"), i);
+ i = ceil(max(1, mv_timeout - time)); // make sure 0 seconds left never shows up, not even for a frame
+ if (mv_winner)
+ map = mv_maps[mv_winner - 1];
+ else
+ map = sprintf(_("%d seconds left"), i);
pos.x = center - stringwidth(map, false, hud_fontsize * 1.5) * 0.5;
drawstring(pos, map, hud_fontsize * 1.5, '0 1 0', panel_fg_alpha, DRAWFLAG_NORMAL);
pos.y += hud_fontsize.y * 1.5;
if (mv_top2_time)
mv_top2_alpha = max(0.2, 1 - (time - mv_top2_time) ** 2);
+ if (mv_winner_time)
+ mv_winner_alpha = max(0.2, 1 - sqrt(max(0, time - mv_winner_time)));
+
void (vector, float, float, string, string, float, float) DrawItem;
if(gametypevote)
else
DrawItem(pos + MapVote_GridVec(dist, i, mv_columns), dist.y, dist.x, map, "", tmp, i);
}
+ if (mv_winner)
+ {
+ // expand winner map image
+ vector startsize = '0 0 0';
+ startsize.y = vid_conheight * 0.1;
+ startsize.x = startsize.y * 4/3;
+ vector startpos = panel_pos + (panel_size - startsize) / 2;
+
+ vector endsize = '0 0 0';
+ endsize.y = vid_conheight * 0.5;
+ endsize.x = endsize.y * 4/3;
+ vector endpos = '0 0 0';
+ endpos.y = panel_pos.y;
+ endpos.x = (vid_conwidth - endsize.x) * 0.5;
+
+ float f = bound(0, (time - mv_winner_time) * 2, 1);
+ f = sqrt(f);
+ float theAlpha = f;
+ f = min(0.1 + f, 1);
+ vector img_pos = endpos * f + startpos * (1 - f);
+ vector img_size = endsize * f + startsize * (1 - f);
+
+ MapVote_DrawMapPicture(mv_pics[mv_winner - 1], img_pos, img_size, theAlpha);
+ }
if(mv_abstain)
++mv_num_maps;
}
else
{
- Gametype type = MapInfo_Type_FromString(gt, false);
+ Gametype type = MapInfo_Type_FromString(gt, false, false);
mv_pk3[i] = strzone(MapInfo_Type_ToText(type));
mv_desc[i] = MapInfo_Type_Description(type);
}
mv_ownvote = -1;
mv_timeout = ReadCoord();
- gametypevote = ReadByte();
-
- if(gametypevote)
- {
+ int gametypevote_flags = ReadByte();
+ gametypevote = boolean(gametypevote_flags & BIT(0));
+ if(gametypevote_flags)
mapvote_chosenmap = strzone(ReadString());
- if ( gametypevote == 2 )
- gametypevote = 0;
- }
MapVote_ReadMask();
int i;
imp = pos - mv_columns;
if ( imp < 0 )
{
- imp = floor(mv_num_maps/mv_columns)*mv_columns + pos % mv_columns;
- if ( imp >= mv_num_maps )
- imp -= mv_columns;
+ int mv_rows = ceil(mv_num_maps / mv_columns);
+ if (imp == -mv_columns) // pos == 0
+ imp = mv_columns * mv_rows - 1;
+ else
+ imp = imp + mv_columns * mv_rows - 1;
}
}
if ( !(mv_flags[imp] & GTV_AVAILABLE) && imp != mv_ownvote )
{
imp = pos + mv_columns;
if ( imp >= mv_num_maps )
- imp = imp % mv_columns;
+ {
+ if ((imp % mv_columns) == mv_columns - 1)
+ imp = 0;
+ else
+ imp = imp % mv_columns + 1;
+ }
}
if ( !(mv_flags[imp] & GTV_AVAILABLE) && imp != mv_ownvote )
imp = MapVote_MoveDown(imp);
TC(int, bInputType);
static int first_digit = 0;
- if (!mv_active)
+ if (!mv_active || isdemo())
return false;
if(bInputType == 3)
return true;
}
- if (bInputType == 0)
+ if (bInputType == 2)
+ {
+ mv_selection_keyboard = 0;
+ return false;
+ }
+
+ // at this point bInputType can only be 0 or 1 (key pressed or released)
+ bool key_pressed = (bInputType == 0);
+
+ if (key_pressed)
{
if (nPrimary == K_ALT) hudShiftState |= S_ALT;
if (nPrimary == K_CTRL) hudShiftState |= S_CTRL;
if (nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
}
- else if (bInputType == 1)
+ else
{
if (nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
if (nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
first_digit = 0;
}
- if (bInputType != 0)
- return false;
+ // Key release events must be handled by the engine otherwise the on-press command such as +jump
+ // executed by pressing SPACE before entering the map voting screen won't be followed by the
+ // on-release command (-jump) on key release once entered the map voting screen, causing +jump
+ // to stay active even on the next map and automatically forcing the player to join
+ if (!key_pressed) return false;
int imp = 0;
switch(nPrimary)
{
case K_RIGHTARROW:
+ if (mv_winner)
+ return true;
mv_selection_keyboard = 1;
mv_selection = MapVote_MoveRight(mv_selection);
return true;
case K_LEFTARROW:
+ if (mv_winner)
+ return true;
mv_selection_keyboard = 1;
mv_selection = MapVote_MoveLeft(mv_selection);
return true;
case K_DOWNARROW:
+ if (mv_winner)
+ return true;
mv_selection_keyboard = 1;
mv_selection = MapVote_MoveDown(mv_selection);
return true;
case K_UPARROW:
+ if (mv_winner)
+ return true;
mv_selection_keyboard = 1;
mv_selection = MapVote_MoveUp(mv_selection);
return true;
case K_KP_ENTER:
case K_ENTER:
case K_SPACE:
+ if (mv_winner)
+ return true;
if ( mv_selection_keyboard )
MapVote_SendChoice(mv_selection);
return true;
imp = min(mv_selection + 1, mv_num_maps);
}
+ if (nPrimary == K_MOUSE2)
+ return true; // do nothing
+
if (imp)
{
- if (imp <= mv_num_maps)
+ if (!mv_winner && imp <= mv_num_maps)
localcmd(strcat("\nimpulse ", ftos(imp), "\n"));
return true;
}
if(sf & 4)
MapVote_UpdateVotes();
+
+ if(sf & 8)
+ {
+ mv_winner = ReadByte();
+ mv_winner_time = time;
+ }
}
NET_HANDLE(TE_CSQC_PICTURE, bool isNew)