1 #include "cl_minigames_hud.qh"
3 #include <client/draw.qh>
4 #include <client/hud/_mod.qh>
5 #include <client/hud/hud_config.qh>
6 #include <client/mapvoting.qh>
7 #include <common/ent_cs.qh>
8 #include <common/minigames/minigames.qh>
12 void HUD_MinigameBoard_Export(int fh)
14 // allow saving cvars that aesthetically change the panel into hud skin files
17 void HUD_MinigameStatus_Export(int fh)
19 // allow saving cvars that aesthetically change the panel into hud skin files
22 void HUD_MinigameHelp_Export(int fh)
24 // allow saving cvars that aesthetically change the panel into hud skin files
27 void HUD_MinigameMenu_Export(int fh)
29 // allow saving cvars that aesthetically change the panel into hud skin files
32 // whether the mouse is over the given panel
33 bool HUD_mouse_over(entity somepanel)
35 vector pos = stov(cvar_string(strcat("hud_panel_", somepanel.panel_name, "_pos")));
36 vector sz = stov(cvar_string(strcat("hud_panel_", somepanel.panel_name, "_size")));
37 return mousepos_x >= pos_x*vid_conwidth && mousepos_x <= (pos_x+sz_x)*vid_conwidth &&
38 mousepos_y >= pos_y*vid_conheight && mousepos_y <= (pos_y+sz_y)*vid_conheight ;
41 // ====================================================================
43 // ====================================================================
45 // Draws the minigame game board
46 void HUD_MinigameBoard ()
48 if (!HUD_MinigameMenu_IsOpened())
51 entity hud_minigame = NULL;
53 if(!autocvar__hud_configure)
57 hud_minigame = active_minigame.descriptor;
60 hud_minigame = minigame_get_descriptor("nmm");
65 HUD_Panel_LoadCvars();
72 hud_minigame.minigame_hud_board(pos,mySize);
75 // ====================================================================
77 // ====================================================================
78 // Draws the minigame status panel
79 void HUD_MinigameStatus ()
81 if (!HUD_MinigameMenu_IsOpened())
84 entity hud_minigame = NULL;
86 if(!autocvar__hud_configure)
90 hud_minigame = active_minigame.descriptor;
93 hud_minigame = minigame_get_descriptor("nmm");
98 HUD_Panel_LoadCvars();
107 pos += '1 1 0' * panel_bg_padding;
108 mySize -= '2 2 0' * panel_bg_padding;
112 hud_minigame.minigame_hud_status(pos,mySize);
115 // ====================================================================
117 // ====================================================================
119 // Minigame menu options: list head
120 entity HUD_MinigameMenu_entries;
121 // Minigame menu options: list tail
122 entity HUD_MinigameMenu_last_entry;
124 // Minigame menu options: insert entry after the given location
125 void HUD_MinigameMenu_InsertEntry(entity newentry, entity prev)
127 if ( !HUD_MinigameMenu_entries )
129 HUD_MinigameMenu_entries = newentry;
130 HUD_MinigameMenu_last_entry = newentry;
134 newentry.list_prev = prev;
135 newentry.list_next = prev.list_next;
136 if ( prev.list_next )
137 prev.list_next.list_prev = newentry;
139 HUD_MinigameMenu_last_entry = newentry;
140 prev.list_next = newentry;
144 // minigame menu item uder the mouse
145 entity HUD_MinigameMenu_activeitem;
147 // Click the given item
148 void HUD_MinigameMenu_Click(entity menuitem)
152 menuitem.use(menuitem, NULL, NULL);
156 // Minigame menu options: Remove the given entry
157 // Precondition: the given entry is actually in the list
158 void HUD_MinigameMenu_EraseEntry ( entity e )
160 // remove child items (if any)
163 HUD_MinigameMenu_Click(e);
167 e.list_prev.list_next = e.list_next;
169 HUD_MinigameMenu_entries = e.list_next;
172 e.list_next.list_prev = e.list_prev;
174 HUD_MinigameMenu_last_entry = e.list_prev;
176 if ( HUD_MinigameMenu_activeitem == e )
177 HUD_MinigameMenu_activeitem = NULL;
182 // Minigame menu options: create entry
183 entity HUD_MinigameMenu_SpawnEntry(entity entry, string s, vector offset, vector fontsize, vector color,void(entity, entity, entity) click)
186 entry.origin = offset;
187 entry.size = fontsize;
188 entry.colormod = color;
191 panel_pos_y += fontsize_y;
195 // Spawn a child entry of a collapsable entry
196 entity HUD_MinigameMenu_SpawnSubEntry(string s, void(entity, entity, entity) click, entity parent)
198 vector item_fontsize = hud_fontsize*1.25;
199 vector item_offset = '1 0 0' * item_fontsize_x;
200 entity item = HUD_MinigameMenu_SpawnEntry(new(hud_minigamemenu_subentry),
201 s,item_offset,item_fontsize,'0.8 0.8 0.8', click );
206 // Click action for Create sub-entries
207 void HUD_MinigameMenu_ClickCreate_Entry(entity this, entity actor, entity trigger)
209 minigame_cmd("create ", this.netname);
212 // Helper click action for collapsible entries
213 // returns true when you have to create the sub-entries
214 bool HUD_MinigameMenu_Click_ExpandCollapse(entity this)
217 if ( this.flags & 2 )
219 if ( HUD_MinigameMenu_activeitem &&
220 HUD_MinigameMenu_activeitem.owner == this )
221 HUD_MinigameMenu_activeitem = NULL;
223 for ( e = this.list_next; e != NULL && e.owner == this; e = this.list_next )
226 HUD_MinigameMenu_Click(e);
227 this.list_next = e.list_next;
230 if ( this.list_next )
231 this.list_next.list_prev = this;
233 HUD_MinigameMenu_last_entry = this;
237 for ( e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
239 if ( (e.flags & 2) && e.origin_x == this.origin_x)
240 HUD_MinigameMenu_Click(e);
250 // Click action for the Create menu
251 void HUD_MinigameMenu_ClickCreate(entity this, entity actor, entity trigger)
253 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
257 FOREACH(Minigames, true, {
258 curr = HUD_MinigameMenu_SpawnSubEntry(it.message, HUD_MinigameMenu_ClickCreate_Entry, this);
259 curr.netname = it.netname;
260 curr.model = strzone(minigame_texture(strcat(it.netname,"/icon")));
261 HUD_MinigameMenu_InsertEntry( curr, prev );
267 // Click action for Join sub-entries
268 void HUD_MinigameMenu_ClickJoin_Entry(entity this, entity actor, entity trigger)
270 minigame_cmd("join ",this.netname);
271 HUD_MinigameMenu_EraseEntry(this);
274 // Click action for the Join menu
275 void HUD_MinigameMenu_ClickJoin(entity this, entity actor, entity trigger)
277 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
282 while( (e = find(e,classname,"minigame")) )
284 if ( e != active_minigame )
286 curr = HUD_MinigameMenu_SpawnSubEntry(
287 e.netname, HUD_MinigameMenu_ClickJoin_Entry, this );
288 curr.netname = e.netname;
289 curr.model = strzone(minigame_texture(strcat(e.descriptor.netname,"/icon")));
290 HUD_MinigameMenu_InsertEntry( curr, prev );
297 /*// Temporary placeholder for un-implemented Click actions
298 void HUD_MinigameMenu_ClickNoop()
300 dprint("Placeholder for ",this.message,"\n");
303 // Click action for Quit
304 void HUD_MinigameMenu_ClickQuit(entity this, entity actor, entity trigger)
306 deactivate_minigame();
310 // Click action for Invite sub-entries
311 void HUD_MinigameMenu_ClickInvite_Entry(entity this, entity actor, entity trigger)
313 minigame_cmd("invite #",this.netname);
316 // Click action for the Invite menu
317 void HUD_MinigameMenu_ClickInvite(entity this, entity actor, entity trigger)
319 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
323 for(int i = 0; i < maxclients; ++i)
325 if ( player_localnum != i && playerslots[i] && entcs_GetName(i) != "" &&
326 !findfloat(NULL,minigame_playerslot,i+1) && playerslots[i].ping )
328 e = HUD_MinigameMenu_SpawnSubEntry(
329 strzone(entcs_GetName(i)), HUD_MinigameMenu_ClickInvite_Entry,
332 e.netname = strzone(ftos(i+1));
334 HUD_MinigameMenu_InsertEntry(e,prev);
341 void HUD_MinigameMenu_ClickCustomEntry(entity this, entity actor, entity trigger)
343 if ( active_minigame )
344 active_minigame.minigame_event(active_minigame,"menu_click",this.netname);
347 // Adds a game-specific entry to the menu
348 void HUD_MinigameMenu_CustomEntry(entity parent, string menumessage, string event_arg)
350 entity e = HUD_MinigameMenu_SpawnSubEntry(
351 menumessage, HUD_MinigameMenu_ClickCustomEntry, parent );
352 e.netname = event_arg;
353 HUD_MinigameMenu_InsertEntry(e, parent);
354 //dprint("CustomEntry ",ftos(num_for_edict(parent))," ",menumessage," ",event_arg,"\n");
357 // Click action for the Current Game menu
358 void HUD_MinigameMenu_ClickCurrentGame(entity this, entity actor, entity trigger)
360 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
362 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnSubEntry(
363 _("Quit"), HUD_MinigameMenu_ClickQuit, this ), this);
365 active_minigame.minigame_event(active_minigame,"menu_show",this);
367 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnSubEntry(
368 _("Invite"), HUD_MinigameMenu_ClickInvite, this), this);
371 // Whether the minigame menu panel is open
372 bool HUD_MinigameMenu_IsOpened()
374 return HUD_MinigameMenu_entries != NULL;
377 // Close the minigame menu panel
378 void HUD_MinigameMenu_Close(entity this, entity actor, entity trigger)
380 if ( HUD_MinigameMenu_IsOpened() )
383 for ( e = HUD_MinigameMenu_entries; e != NULL; e = p )
388 HUD_MinigameMenu_entries = NULL;
389 HUD_MinigameMenu_last_entry = NULL;
390 HUD_MinigameMenu_activeitem = NULL;
394 // toggle a button to manage the current game
395 void HUD_MinigameMenu_CurrentButton()
398 if ( active_minigame )
400 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = e.list_prev )
401 if ( e.classname == "hud_minigamemenu_exit" )
403 HUD_MinigameMenu_EraseEntry(e);
406 entity currb = HUD_MinigameMenu_SpawnEntry(new(hud_minigamemenu_current),
407 _("Current Game"), '0 0 0', hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickCurrentGame );
408 currb.model = strzone(minigame_texture(strcat(active_minigame.descriptor.netname,"/icon")));
409 HUD_MinigameMenu_InsertEntry(currb,HUD_MinigameMenu_last_entry);
410 HUD_MinigameMenu_Click(currb);
415 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = p.list_prev )
418 if ( e.classname == "hud_minigamemenu_current" )
422 p = HUD_MinigameMenu_last_entry;
423 HUD_MinigameMenu_EraseEntry(e);
427 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = e.list_prev )
428 if ( e.classname == "hud_minigamemenu_exit" )
430 entity exit = HUD_MinigameMenu_SpawnEntry(new(hud_minigamemenu_exit),
431 _("Exit Menu"),'0 0 0',hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_Close);
432 HUD_MinigameMenu_InsertEntry ( exit, HUD_MinigameMenu_last_entry );
436 // Open the minigame menu panel
437 void HUD_MinigameMenu_Open()
439 if ( !mv_active && !HUD_MinigameMenu_IsOpened() )
441 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnEntry(new(hud_minigamemenu_entry),
442 _("Create"), '0 0 0', hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickCreate),
443 HUD_MinigameMenu_last_entry );
444 HUD_MinigameMenu_InsertEntry ( HUD_MinigameMenu_SpawnEntry(new(hud_minigamemenu_entry),
445 _("Join"),'0 0 0',hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickJoin),
446 HUD_MinigameMenu_last_entry );
447 HUD_MinigameMenu_CurrentButton();
448 HUD_MinigameMenu_activeitem = NULL;
452 // Handles mouse input on to minigame menu panel
453 void HUD_MinigameMenu_MouseInput()
455 panel = HUD_PANEL(MINIGAMEMENU);
457 HUD_Panel_LoadCvars();
461 panel_pos += '1 1 0' * panel_bg_padding;
462 panel_size -= '2 2 0' * panel_bg_padding;
467 panel_pos_y += hud_fontsize_y*2;
469 HUD_MinigameMenu_activeitem = NULL;
471 for ( e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
473 sz = eX*panel_size_x + eY*e.size_y;
476 if ( !HUD_MinigameMenu_activeitem && mousepos_y >= panel_pos_y && mousepos_y <= panel_pos_y + sz_y )
478 HUD_MinigameMenu_activeitem = e;
485 void HUD_MinigameMenu_DrawEntry(vector pos, string s, vector fontsize, vector color)
487 minigame_drawstring_trunc(panel_size_x-pos_x+panel_pos_x, pos, s,
488 fontsize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
490 // Draw a color-coded menu
491 void HUD_MinigameMenu_DrawColoredEntry(vector pos, string s, vector fontsize)
493 minigame_drawcolorcodedstring_trunc(panel_size_x-pos_x+panel_pos_x, pos, s,
494 fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
497 // Minigame menu panel UI
498 void HUD_MinigameMenu ()
502 if (HUD_MinigameMenu_IsOpened())
503 HUD_MinigameMenu_Close(NULL, NULL, NULL);
507 if ( !HUD_MinigameMenu_IsOpened() )
510 HUD_Panel_LoadCvars();
517 panel_pos += '1 1 0' * panel_bg_padding;
518 panel_size -= '2 2 0' * panel_bg_padding;
521 HUD_MinigameMenu_DrawEntry(panel_pos,_("Minigames"),hud_fontsize*2,'0.25 0.47 0.72');
522 panel_pos_y += hud_fontsize_y*2;
527 vector imgsz = '22 22 0'; // NOTE: if changed, edit where HUD_MinigameMenu_activeitem is selected
528 for ( entity e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
540 drawfill(panel_pos, eX*panel_size_x + eY*itemh, e.colormod,
541 panel_fg_alpha, DRAWFLAG_NORMAL);
547 drawpic( panel_pos+offset, e.model, imgsz, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
549 offset_y = (imgsz_y-e.size_y) / 2;
553 HUD_MinigameMenu_DrawColoredEntry(panel_pos+offset,e.message,e.size);
555 HUD_MinigameMenu_DrawEntry(panel_pos+offset,e.message,e.size,color);
557 if ( e == HUD_MinigameMenu_activeitem )
558 drawfill(panel_pos, eX*panel_size_x + eY*itemh,'1 1 1', 0.25, DRAWFLAG_ADDITIVE);
560 panel_pos_y += itemh;
564 // ====================================================================
565 // Minigame Help Panel
566 // ====================================================================
568 void HUD_MinigameHelp()
570 if (!HUD_MinigameMenu_IsOpened())
575 if(!autocvar__hud_configure)
577 if (!active_minigame)
579 help_message = active_minigame.message;
582 help_message = _("Minigame message");
587 HUD_Panel_LoadCvars();
596 pos += '1 1 0' * panel_bg_padding;
597 mySize -= '2 2 0' * panel_bg_padding;
600 minigame_drawcolorcodedstring_wrapped( mySize_x, pos, help_message,
601 hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL, 0.5 );
604 // ====================================================================
605 // Minigame Panel Input
606 // ====================================================================
607 float HUD_Minigame_InputEvent(float bInputType, float nPrimary, float nSecondary)
610 if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure )
615 mousepos_x = nPrimary;
616 mousepos_y = nSecondary;
617 if ( active_minigame && HUD_mouse_over(HUD_PANEL(MINIGAMEBOARD)) )
618 active_minigame.minigame_event(active_minigame,"mouse_moved",mousepos);
624 if ( active_minigame && HUD_mouse_over(HUD_PANEL(MINIGAMEBOARD)) )
625 active_minigame.minigame_event(active_minigame,"mouse_moved",mousepos);
629 // at this point bInputType can only be 0 or 1 (key pressed or released)
630 bool key_pressed = (bInputType == 0);
633 if(nPrimary == K_ALT) hudShiftState |= S_ALT;
634 if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
635 if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
636 if(nPrimary == K_MOUSE1) mouseClicked |= S_MOUSE1;
637 if(nPrimary == K_MOUSE2) mouseClicked |= S_MOUSE2;
640 if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
641 if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
642 if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
643 if(nPrimary == K_MOUSE1) mouseClicked -= (mouseClicked & S_MOUSE1);
644 if(nPrimary == K_MOUSE2) mouseClicked -= (mouseClicked & S_MOUSE2);
648 string con_keys = findkeysforcommand("toggleconsole", 0);
649 int keys = tokenize(con_keys); // findkeysforcommand returns data for this
651 for (i = 0; i < keys; ++i)
653 if(nPrimary == stof(argv(i)))
657 if ( active_minigame )
660 string action = key_pressed ? "pressed" : "released";
661 if ( nPrimary >= K_MOUSE1 && nPrimary <= K_MOUSE16 )
663 if ( HUD_mouse_over(HUD_PANEL(MINIGAMEBOARD)) )
669 if ( device && active_minigame.minigame_event(
670 active_minigame,strcat(device,"_",action),nPrimary) )
674 if ( nPrimary == K_MOUSE2 )
678 if ( nPrimary == K_MOUSE1 )
682 if (HUD_MinigameMenu_activeitem && HUD_mouse_over(HUD_PANEL(MINIGAMEMENU)))
683 HUD_MinigameMenu_Click(HUD_MinigameMenu_activeitem);
686 if ( nPrimary == K_UPARROW || nPrimary == K_KP_UPARROW )
690 if ( HUD_MinigameMenu_activeitem && HUD_MinigameMenu_activeitem.list_prev )
691 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_activeitem.list_prev;
693 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_last_entry;
696 else if ( nPrimary == K_DOWNARROW || nPrimary == K_KP_DOWNARROW )
700 if ( HUD_MinigameMenu_activeitem && HUD_MinigameMenu_activeitem.list_next )
701 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_activeitem.list_next;
703 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
706 else if ( nPrimary == K_HOME || nPrimary == K_KP_HOME )
710 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
713 else if ( nPrimary == K_END || nPrimary == K_KP_END )
717 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
720 else if ( nPrimary == K_KP_ENTER || nPrimary == K_ENTER || nPrimary == K_SPACE )
724 HUD_MinigameMenu_Click(HUD_MinigameMenu_activeitem);
727 else if ( nPrimary == K_ESCAPE )
731 HUD_MinigameMenu_Close(NULL, NULL, NULL);
738 void HUD_Minigame_Mouse()
740 if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure || mv_active )
743 if ( HUD_MinigameMenu_IsOpened() && HUD_mouse_over(HUD_PANEL(MINIGAMEMENU)) )
744 HUD_MinigameMenu_MouseInput();