1 #include "cl_minigames_hud.qh"
3 #include <client/autocvars.qh>
4 #include <common/ent_cs.qh>
6 #include "minigames.qh"
10 #include <client/hud/hud_config.qh>
11 #include <client/mapvoting.qh>
13 // whether the mouse is over the given panel
14 bool HUD_mouse_over(entity somepanel)
16 vector pos = stov(cvar_string(strcat("hud_panel_", somepanel.panel_name, "_pos")));
17 vector sz = stov(cvar_string(strcat("hud_panel_", somepanel.panel_name, "_size")));
18 return mousepos_x >= pos_x*vid_conwidth && mousepos_x <= (pos_x+sz_x)*vid_conwidth &&
19 mousepos_y >= pos_y*vid_conheight && mousepos_y <= (pos_y+sz_y)*vid_conheight ;
22 // ====================================================================
24 // ====================================================================
26 // Draws the minigame game board
27 void HUD_MinigameBoard ()
29 if (!HUD_MinigameMenu_IsOpened())
32 entity hud_minigame = NULL;
34 if(!autocvar__hud_configure)
38 hud_minigame = active_minigame.descriptor;
41 hud_minigame = minigame_get_descriptor("nmm");
46 HUD_Panel_LoadCvars();
53 hud_minigame.minigame_hud_board(pos,mySize);
56 // ====================================================================
58 // ====================================================================
59 // Draws the minigame status panel
60 void HUD_MinigameStatus ()
62 if (!HUD_MinigameMenu_IsOpened())
65 entity hud_minigame = NULL;
67 if(!autocvar__hud_configure)
71 hud_minigame = active_minigame.descriptor;
74 hud_minigame = minigame_get_descriptor("nmm");
79 HUD_Panel_LoadCvars();
88 pos += '1 1 0' * panel_bg_padding;
89 mySize -= '2 2 0' * panel_bg_padding;
93 hud_minigame.minigame_hud_status(pos,mySize);
96 // ====================================================================
98 // ====================================================================
100 // Minigame menu options: list head
101 entity HUD_MinigameMenu_entries;
102 // Minigame menu options: list tail
103 entity HUD_MinigameMenu_last_entry;
105 // Minigame menu options: insert entry after the given location
106 void HUD_MinigameMenu_InsertEntry(entity newentry, entity prev)
108 if ( !HUD_MinigameMenu_entries )
110 HUD_MinigameMenu_entries = newentry;
111 HUD_MinigameMenu_last_entry = newentry;
115 newentry.list_prev = prev;
116 newentry.list_next = prev.list_next;
117 if ( prev.list_next )
118 prev.list_next.list_prev = newentry;
120 HUD_MinigameMenu_last_entry = newentry;
121 prev.list_next = newentry;
126 // minigame menu item uder the mouse
127 entity HUD_MinigameMenu_activeitem;
129 // Click the given item
130 void HUD_MinigameMenu_Click(entity menuitem)
134 menuitem.use(menuitem, NULL, NULL);
138 // Minigame menu options: Remove the given entry
139 // Precondition: the given entry is actually in the list
140 void HUD_MinigameMenu_EraseEntry ( entity e )
142 // remove child items (if any)
145 HUD_MinigameMenu_Click(e);
149 e.list_prev.list_next = e.list_next;
151 HUD_MinigameMenu_entries = e.list_next;
154 e.list_next.list_prev = e.list_prev;
156 HUD_MinigameMenu_last_entry = e.list_prev;
158 if ( HUD_MinigameMenu_activeitem == e )
159 HUD_MinigameMenu_activeitem = NULL;
164 // Minigame menu options: create entry
165 entity HUD_MinigameMenu_SpawnEntry(string s, vector offset, vector fontsize, vector color,void(entity, entity, entity) click)
167 entity entry = spawn();
169 entry.origin = offset;
170 entry.size = fontsize;
171 entry.colormod = color;
174 panel_pos_y += fontsize_y;
178 // Spawn a child entry of a collapsable entry
179 entity HUD_MinigameMenu_SpawnSubEntry(string s, void(entity, entity, entity) click, entity parent)
181 vector item_fontsize = hud_fontsize*1.25;
182 vector item_offset = '1 0 0' * item_fontsize_x;
183 entity item = HUD_MinigameMenu_SpawnEntry(
184 s,item_offset,item_fontsize,'0.8 0.8 0.8', click );
189 // Click action for Create sub-entries
190 void HUD_MinigameMenu_ClickCreate_Entry(entity this, entity actor, entity trigger)
192 minigame_cmd("create ", this.netname);
195 // Helper click action for collapsible entries
196 // returns true when you have to create the sub-entries
197 bool HUD_MinigameMenu_Click_ExpandCollapse(entity this)
200 if ( this.flags & 2 )
202 if ( HUD_MinigameMenu_activeitem &&
203 HUD_MinigameMenu_activeitem.owner == this )
204 HUD_MinigameMenu_activeitem = NULL;
206 for ( e = this.list_next; e != NULL && e.owner == this; e = this.list_next )
209 HUD_MinigameMenu_Click(e);
210 this.list_next = e.list_next;
213 if ( this.list_next )
214 this.list_next.list_prev = this;
216 HUD_MinigameMenu_last_entry = this;
220 for ( e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
222 if ( (e.flags & 2) && e.origin_x == this.origin_x)
223 HUD_MinigameMenu_Click(e);
233 // Click action for the Create menu
234 void HUD_MinigameMenu_ClickCreate(entity this, entity actor, entity trigger)
236 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
240 FOREACH(Minigames, true, {
241 curr = HUD_MinigameMenu_SpawnSubEntry(it.message, HUD_MinigameMenu_ClickCreate_Entry, this);
242 curr.netname = it.netname;
243 curr.model = strzone(minigame_texture(strcat(it.netname,"/icon")));
244 HUD_MinigameMenu_InsertEntry( curr, prev );
250 // Click action for Join sub-entries
251 void HUD_MinigameMenu_ClickJoin_Entry(entity this, entity actor, entity trigger)
253 minigame_cmd("join ",this.netname);
254 HUD_MinigameMenu_EraseEntry(this);
257 // Click action for the Join menu
258 void HUD_MinigameMenu_ClickJoin(entity this, entity actor, entity trigger)
260 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
265 while( (e = find(e,classname,"minigame")) )
267 if ( e != active_minigame )
269 curr = HUD_MinigameMenu_SpawnSubEntry(
270 e.netname, HUD_MinigameMenu_ClickJoin_Entry, this );
271 curr.netname = e.netname;
272 curr.model = strzone(minigame_texture(strcat(e.descriptor.netname,"/icon")));
273 HUD_MinigameMenu_InsertEntry( curr, prev );
280 /*// Temporary placeholder for un-implemented Click actions
281 void HUD_MinigameMenu_ClickNoop()
283 dprint("Placeholder for ",this.message,"\n");
286 // Click action for Quit
287 void HUD_MinigameMenu_ClickQuit(entity this, entity actor, entity trigger)
289 deactivate_minigame();
293 // Click action for Invite sub-entries
294 void HUD_MinigameMenu_ClickInvite_Entry(entity this, entity actor, entity trigger)
296 minigame_cmd("invite #",this.netname);
299 // Click action for the Invite menu
300 void HUD_MinigameMenu_ClickInvite(entity this, entity actor, entity trigger)
302 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
306 for(int i = 0; i < maxclients; ++i)
308 if ( player_localnum != i && playerslots[i] && entcs_GetName(i) != "" &&
309 !findfloat(NULL,minigame_playerslot,i+1) && playerslots[i].ping )
311 e = HUD_MinigameMenu_SpawnSubEntry(
312 strzone(entcs_GetName(i)), HUD_MinigameMenu_ClickInvite_Entry,
315 e.netname = strzone(ftos(i+1));
317 HUD_MinigameMenu_InsertEntry(e,prev);
324 void HUD_MinigameMenu_ClickCustomEntry(entity this, entity actor, entity trigger)
326 if ( active_minigame )
327 active_minigame.minigame_event(active_minigame,"menu_click",this.netname);
330 // Adds a game-specific entry to the menu
331 void HUD_MinigameMenu_CustomEntry(entity parent, string menumessage, string event_arg)
333 entity e = HUD_MinigameMenu_SpawnSubEntry(
334 menumessage, HUD_MinigameMenu_ClickCustomEntry, parent );
335 e.netname = event_arg;
336 HUD_MinigameMenu_InsertEntry(e, parent);
337 //dprint("CustomEntry ",ftos(num_for_edict(parent))," ",menumessage," ",event_arg,"\n");
340 // Click action for the Current Game menu
341 void HUD_MinigameMenu_ClickCurrentGame(entity this, entity actor, entity trigger)
343 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
345 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnSubEntry(
346 _("Quit"), HUD_MinigameMenu_ClickQuit, this ), this);
348 active_minigame.minigame_event(active_minigame,"menu_show",this);
350 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnSubEntry(
351 _("Invite"), HUD_MinigameMenu_ClickInvite, this), this);
354 // Whether the minigame menu panel is open
355 bool HUD_MinigameMenu_IsOpened()
357 return HUD_MinigameMenu_entries != NULL;
360 // Close the minigame menu panel
361 void HUD_MinigameMenu_Close(entity this, entity actor, entity trigger)
363 if ( HUD_MinigameMenu_IsOpened() )
366 for ( e = HUD_MinigameMenu_entries; e != NULL; e = p )
371 HUD_MinigameMenu_entries = NULL;
372 HUD_MinigameMenu_last_entry = NULL;
373 HUD_MinigameMenu_activeitem = NULL;
377 // toggle a button to manage the current game
378 void HUD_MinigameMenu_CurrentButton()
381 if ( active_minigame )
383 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = e.list_prev )
384 if ( e.classname == "hud_minigamemenu_exit" )
386 HUD_MinigameMenu_EraseEntry(e);
389 entity currb = HUD_MinigameMenu_SpawnEntry(
390 _("Current Game"), '0 0 0', hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickCurrentGame );
391 currb.classname = "hud_minigamemenu_current";
392 currb.model = strzone(minigame_texture(strcat(active_minigame.descriptor.netname,"/icon")));
393 HUD_MinigameMenu_InsertEntry(currb,HUD_MinigameMenu_last_entry);
394 HUD_MinigameMenu_Click(currb);
399 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = p.list_prev )
402 if ( e.classname == "hud_minigamemenu_current" )
406 p = HUD_MinigameMenu_last_entry;
407 HUD_MinigameMenu_EraseEntry(e);
411 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = e.list_prev )
412 if ( e.classname == "hud_minigamemenu_exit" )
414 entity exit = HUD_MinigameMenu_SpawnEntry(
415 _("Exit Menu"),'0 0 0',hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_Close);
416 exit.classname = "hud_minigamemenu_exit";
417 HUD_MinigameMenu_InsertEntry ( exit, HUD_MinigameMenu_last_entry );
421 // Open the minigame menu panel
422 void HUD_MinigameMenu_Open()
424 if ( !mv_active && !HUD_MinigameMenu_IsOpened() )
426 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnEntry(
427 _("Create"), '0 0 0', hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickCreate),
428 HUD_MinigameMenu_last_entry );
429 HUD_MinigameMenu_InsertEntry ( HUD_MinigameMenu_SpawnEntry(
430 _("Join"),'0 0 0',hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickJoin),
431 HUD_MinigameMenu_last_entry );
432 HUD_MinigameMenu_CurrentButton();
433 HUD_MinigameMenu_activeitem = NULL;
437 // Handles mouse input on to minigame menu panel
438 void HUD_MinigameMenu_MouseInput()
440 panel = HUD_PANEL(MINIGAMEMENU);
442 HUD_Panel_LoadCvars();
446 panel_pos += '1 1 0' * panel_bg_padding;
447 panel_size -= '2 2 0' * panel_bg_padding;
452 panel_pos_y += hud_fontsize_y*2;
454 HUD_MinigameMenu_activeitem = NULL;
456 for ( e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
458 sz = eX*panel_size_x + eY*e.size_y;
461 if ( !HUD_MinigameMenu_activeitem && mousepos_y >= panel_pos_y && mousepos_y <= panel_pos_y + sz_y )
463 HUD_MinigameMenu_activeitem = e;
470 void HUD_MinigameMenu_DrawEntry(vector pos, string s, vector fontsize, vector color)
472 minigame_drawstring_trunc(panel_size_x-pos_x+panel_pos_x, pos, s,
473 fontsize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
475 // Draw a color-coded menu
476 void HUD_MinigameMenu_DrawColoredEntry(vector pos, string s, vector fontsize)
478 minigame_drawcolorcodedstring_trunc(panel_size_x-pos_x+panel_pos_x, pos, s,
479 fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
482 // Minigame menu panel UI
483 void HUD_MinigameMenu ()
487 if (HUD_MinigameMenu_IsOpened())
488 HUD_MinigameMenu_Close(NULL, NULL, NULL);
492 if ( !HUD_MinigameMenu_IsOpened() )
495 HUD_Panel_LoadCvars();
502 panel_pos += '1 1 0' * panel_bg_padding;
503 panel_size -= '2 2 0' * panel_bg_padding;
506 HUD_MinigameMenu_DrawEntry(panel_pos,_("Minigames"),hud_fontsize*2,'0.25 0.47 0.72');
507 panel_pos_y += hud_fontsize_y*2;
512 vector imgsz = '22 22 0'; // NOTE: if changed, edit where HUD_MinigameMenu_activeitem is selected
513 for ( entity e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
525 drawfill(panel_pos, eX*panel_size_x + eY*itemh, e.colormod,
526 panel_fg_alpha, DRAWFLAG_NORMAL);
532 drawpic( panel_pos+offset, e.model, imgsz, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
534 offset_y = (imgsz_y-e.size_y) / 2;
538 HUD_MinigameMenu_DrawColoredEntry(panel_pos+offset,e.message,e.size);
540 HUD_MinigameMenu_DrawEntry(panel_pos+offset,e.message,e.size,color);
542 if ( e == HUD_MinigameMenu_activeitem )
543 drawfill(panel_pos, eX*panel_size_x + eY*itemh,'1 1 1', 0.25, DRAWFLAG_ADDITIVE);
545 panel_pos_y += itemh;
549 // ====================================================================
550 // Minigame Help Panel
551 // ====================================================================
553 void HUD_MinigameHelp()
555 if (!HUD_MinigameMenu_IsOpened())
560 if(!autocvar__hud_configure)
562 if (!active_minigame)
564 help_message = active_minigame.message;
567 help_message = _("Minigame message");
572 HUD_Panel_LoadCvars();
581 pos += '1 1 0' * panel_bg_padding;
582 mySize -= '2 2 0' * panel_bg_padding;
585 minigame_drawcolorcodedstring_wrapped( mySize_x, pos, help_message,
586 hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL, 0.5 );
589 // ====================================================================
590 // Minigame Panel Input
591 // ====================================================================
592 float HUD_Minigame_InputEvent(float bInputType, float nPrimary, float nSecondary)
595 if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure )
600 mousepos_x = nPrimary;
601 mousepos_y = nSecondary;
602 if ( active_minigame && HUD_mouse_over(HUD_PANEL(MINIGAMEBOARD)) )
603 active_minigame.minigame_event(active_minigame,"mouse_moved",mousepos);
609 if(bInputType == 0) {
610 if(nPrimary == K_ALT) hudShiftState |= S_ALT;
611 if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
612 if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
613 if(nPrimary == K_MOUSE1) mouseClicked |= S_MOUSE1;
614 if(nPrimary == K_MOUSE2) mouseClicked |= S_MOUSE2;
616 else if(bInputType == 1) {
617 if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
618 if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
619 if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
620 if(nPrimary == K_MOUSE1) mouseClicked -= (mouseClicked & S_MOUSE1);
621 if(nPrimary == K_MOUSE2) mouseClicked -= (mouseClicked & S_MOUSE2);
625 string con_keys = findkeysforcommand("toggleconsole", 0);
626 int keys = tokenize(con_keys); // findkeysforcommand returns data for this
628 for (i = 0; i < keys; ++i)
630 if(nPrimary == stof(argv(i)))
634 if ( active_minigame && ( bInputType == 0 || bInputType == 1 ) )
637 string action = bInputType == 0 ? "pressed" : "released";
638 if ( nPrimary >= K_MOUSE1 && nPrimary <= K_MOUSE16 )
640 if ( HUD_mouse_over(HUD_PANEL(MINIGAMEBOARD)) )
646 if ( device && active_minigame.minigame_event(
647 active_minigame,strcat(device,"_",action),nPrimary) )
650 /// TODO: bInputType == 2?
653 if ( bInputType == 0 )
655 if ( nPrimary == K_MOUSE1 && HUD_MinigameMenu_activeitem &&
656 HUD_mouse_over(HUD_PANEL(MINIGAMEMENU)) )
658 HUD_MinigameMenu_Click(HUD_MinigameMenu_activeitem);
661 if ( nPrimary == K_UPARROW || nPrimary == K_KP_UPARROW )
663 if ( HUD_MinigameMenu_activeitem && HUD_MinigameMenu_activeitem.list_prev )
664 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_activeitem.list_prev;
666 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_last_entry;
669 else if ( nPrimary == K_DOWNARROW || nPrimary == K_KP_DOWNARROW )
671 if ( HUD_MinigameMenu_activeitem && HUD_MinigameMenu_activeitem.list_next )
672 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_activeitem.list_next;
674 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
677 else if ( nPrimary == K_HOME || nPrimary == K_KP_HOME )
679 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
682 else if ( nPrimary == K_END || nPrimary == K_KP_END )
684 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
687 else if ( nPrimary == K_KP_ENTER || nPrimary == K_ENTER || nPrimary == K_SPACE )
689 HUD_MinigameMenu_Click(HUD_MinigameMenu_activeitem);
692 else if ( nPrimary == K_ESCAPE )
694 HUD_MinigameMenu_Close(NULL, NULL, NULL);
704 void HUD_Minigame_Mouse()
706 if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure || mv_active )
709 if ( HUD_MinigameMenu_IsOpened() && HUD_mouse_over(HUD_PANEL(MINIGAMEMENU)) )
710 HUD_MinigameMenu_MouseInput();