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 void HUD_MinigameBoard_Export(int fh)
15 // allow saving cvars that aesthetically change the panel into hud skin files
18 void HUD_MinigameStatus_Export(int fh)
20 // allow saving cvars that aesthetically change the panel into hud skin files
23 void HUD_MinigameHelp_Export(int fh)
25 // allow saving cvars that aesthetically change the panel into hud skin files
28 void HUD_MinigameMenu_Export(int fh)
30 // allow saving cvars that aesthetically change the panel into hud skin files
33 // whether the mouse is over the given panel
34 bool HUD_mouse_over(entity somepanel)
36 vector pos = stov(cvar_string(strcat("hud_panel_", somepanel.panel_name, "_pos")));
37 vector sz = stov(cvar_string(strcat("hud_panel_", somepanel.panel_name, "_size")));
38 return mousepos_x >= pos_x*vid_conwidth && mousepos_x <= (pos_x+sz_x)*vid_conwidth &&
39 mousepos_y >= pos_y*vid_conheight && mousepos_y <= (pos_y+sz_y)*vid_conheight ;
42 // ====================================================================
44 // ====================================================================
46 // Draws the minigame game board
47 void HUD_MinigameBoard ()
49 if (!HUD_MinigameMenu_IsOpened())
52 entity hud_minigame = NULL;
54 if(!autocvar__hud_configure)
58 hud_minigame = active_minigame.descriptor;
61 hud_minigame = minigame_get_descriptor("nmm");
66 HUD_Panel_LoadCvars();
73 hud_minigame.minigame_hud_board(pos,mySize);
76 // ====================================================================
78 // ====================================================================
79 // Draws the minigame status panel
80 void HUD_MinigameStatus ()
82 if (!HUD_MinigameMenu_IsOpened())
85 entity hud_minigame = NULL;
87 if(!autocvar__hud_configure)
91 hud_minigame = active_minigame.descriptor;
94 hud_minigame = minigame_get_descriptor("nmm");
99 HUD_Panel_LoadCvars();
108 pos += '1 1 0' * panel_bg_padding;
109 mySize -= '2 2 0' * panel_bg_padding;
113 hud_minigame.minigame_hud_status(pos,mySize);
116 // ====================================================================
118 // ====================================================================
120 // Minigame menu options: list head
121 entity HUD_MinigameMenu_entries;
122 // Minigame menu options: list tail
123 entity HUD_MinigameMenu_last_entry;
125 // Minigame menu options: insert entry after the given location
126 void HUD_MinigameMenu_InsertEntry(entity newentry, entity prev)
128 if ( !HUD_MinigameMenu_entries )
130 HUD_MinigameMenu_entries = newentry;
131 HUD_MinigameMenu_last_entry = newentry;
135 newentry.list_prev = prev;
136 newentry.list_next = prev.list_next;
137 if ( prev.list_next )
138 prev.list_next.list_prev = newentry;
140 HUD_MinigameMenu_last_entry = newentry;
141 prev.list_next = newentry;
146 // minigame menu item uder the mouse
147 entity HUD_MinigameMenu_activeitem;
149 // Click the given item
150 void HUD_MinigameMenu_Click(entity menuitem)
154 menuitem.use(menuitem, NULL, NULL);
158 // Minigame menu options: Remove the given entry
159 // Precondition: the given entry is actually in the list
160 void HUD_MinigameMenu_EraseEntry ( entity e )
162 // remove child items (if any)
165 HUD_MinigameMenu_Click(e);
169 e.list_prev.list_next = e.list_next;
171 HUD_MinigameMenu_entries = e.list_next;
174 e.list_next.list_prev = e.list_prev;
176 HUD_MinigameMenu_last_entry = e.list_prev;
178 if ( HUD_MinigameMenu_activeitem == e )
179 HUD_MinigameMenu_activeitem = NULL;
184 // Minigame menu options: create entry
185 entity HUD_MinigameMenu_SpawnEntry(string s, vector offset, vector fontsize, vector color,void(entity, entity, entity) click)
187 entity entry = spawn();
189 entry.origin = offset;
190 entry.size = fontsize;
191 entry.colormod = color;
194 panel_pos_y += fontsize_y;
198 // Spawn a child entry of a collapsable entry
199 entity HUD_MinigameMenu_SpawnSubEntry(string s, void(entity, entity, entity) click, entity parent)
201 vector item_fontsize = hud_fontsize*1.25;
202 vector item_offset = '1 0 0' * item_fontsize_x;
203 entity item = HUD_MinigameMenu_SpawnEntry(
204 s,item_offset,item_fontsize,'0.8 0.8 0.8', click );
209 // Click action for Create sub-entries
210 void HUD_MinigameMenu_ClickCreate_Entry(entity this, entity actor, entity trigger)
212 minigame_cmd("create ", this.netname);
215 // Helper click action for collapsible entries
216 // returns true when you have to create the sub-entries
217 bool HUD_MinigameMenu_Click_ExpandCollapse(entity this)
220 if ( this.flags & 2 )
222 if ( HUD_MinigameMenu_activeitem &&
223 HUD_MinigameMenu_activeitem.owner == this )
224 HUD_MinigameMenu_activeitem = NULL;
226 for ( e = this.list_next; e != NULL && e.owner == this; e = this.list_next )
229 HUD_MinigameMenu_Click(e);
230 this.list_next = e.list_next;
233 if ( this.list_next )
234 this.list_next.list_prev = this;
236 HUD_MinigameMenu_last_entry = this;
240 for ( e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
242 if ( (e.flags & 2) && e.origin_x == this.origin_x)
243 HUD_MinigameMenu_Click(e);
253 // Click action for the Create menu
254 void HUD_MinigameMenu_ClickCreate(entity this, entity actor, entity trigger)
256 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
260 FOREACH(Minigames, true, {
261 curr = HUD_MinigameMenu_SpawnSubEntry(it.message, HUD_MinigameMenu_ClickCreate_Entry, this);
262 curr.netname = it.netname;
263 curr.model = strzone(minigame_texture(strcat(it.netname,"/icon")));
264 HUD_MinigameMenu_InsertEntry( curr, prev );
270 // Click action for Join sub-entries
271 void HUD_MinigameMenu_ClickJoin_Entry(entity this, entity actor, entity trigger)
273 minigame_cmd("join ",this.netname);
274 HUD_MinigameMenu_EraseEntry(this);
277 // Click action for the Join menu
278 void HUD_MinigameMenu_ClickJoin(entity this, entity actor, entity trigger)
280 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
285 while( (e = find(e,classname,"minigame")) )
287 if ( e != active_minigame )
289 curr = HUD_MinigameMenu_SpawnSubEntry(
290 e.netname, HUD_MinigameMenu_ClickJoin_Entry, this );
291 curr.netname = e.netname;
292 curr.model = strzone(minigame_texture(strcat(e.descriptor.netname,"/icon")));
293 HUD_MinigameMenu_InsertEntry( curr, prev );
300 /*// Temporary placeholder for un-implemented Click actions
301 void HUD_MinigameMenu_ClickNoop()
303 dprint("Placeholder for ",this.message,"\n");
306 // Click action for Quit
307 void HUD_MinigameMenu_ClickQuit(entity this, entity actor, entity trigger)
309 deactivate_minigame();
313 // Click action for Invite sub-entries
314 void HUD_MinigameMenu_ClickInvite_Entry(entity this, entity actor, entity trigger)
316 minigame_cmd("invite #",this.netname);
319 // Click action for the Invite menu
320 void HUD_MinigameMenu_ClickInvite(entity this, entity actor, entity trigger)
322 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
326 for(int i = 0; i < maxclients; ++i)
328 if ( player_localnum != i && playerslots[i] && entcs_GetName(i) != "" &&
329 !findfloat(NULL,minigame_playerslot,i+1) && playerslots[i].ping )
331 e = HUD_MinigameMenu_SpawnSubEntry(
332 strzone(entcs_GetName(i)), HUD_MinigameMenu_ClickInvite_Entry,
335 e.netname = strzone(ftos(i+1));
337 HUD_MinigameMenu_InsertEntry(e,prev);
344 void HUD_MinigameMenu_ClickCustomEntry(entity this, entity actor, entity trigger)
346 if ( active_minigame )
347 active_minigame.minigame_event(active_minigame,"menu_click",this.netname);
350 // Adds a game-specific entry to the menu
351 void HUD_MinigameMenu_CustomEntry(entity parent, string menumessage, string event_arg)
353 entity e = HUD_MinigameMenu_SpawnSubEntry(
354 menumessage, HUD_MinigameMenu_ClickCustomEntry, parent );
355 e.netname = event_arg;
356 HUD_MinigameMenu_InsertEntry(e, parent);
357 //dprint("CustomEntry ",ftos(num_for_edict(parent))," ",menumessage," ",event_arg,"\n");
360 // Click action for the Current Game menu
361 void HUD_MinigameMenu_ClickCurrentGame(entity this, entity actor, entity trigger)
363 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
365 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnSubEntry(
366 _("Quit"), HUD_MinigameMenu_ClickQuit, this ), this);
368 active_minigame.minigame_event(active_minigame,"menu_show",this);
370 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnSubEntry(
371 _("Invite"), HUD_MinigameMenu_ClickInvite, this), this);
374 // Whether the minigame menu panel is open
375 bool HUD_MinigameMenu_IsOpened()
377 return HUD_MinigameMenu_entries != NULL;
380 // Close the minigame menu panel
381 void HUD_MinigameMenu_Close(entity this, entity actor, entity trigger)
383 if ( HUD_MinigameMenu_IsOpened() )
386 for ( e = HUD_MinigameMenu_entries; e != NULL; e = p )
391 HUD_MinigameMenu_entries = NULL;
392 HUD_MinigameMenu_last_entry = NULL;
393 HUD_MinigameMenu_activeitem = NULL;
397 // toggle a button to manage the current game
398 void HUD_MinigameMenu_CurrentButton()
401 if ( active_minigame )
403 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = e.list_prev )
404 if ( e.classname == "hud_minigamemenu_exit" )
406 HUD_MinigameMenu_EraseEntry(e);
409 entity currb = HUD_MinigameMenu_SpawnEntry(
410 _("Current Game"), '0 0 0', hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickCurrentGame );
411 currb.classname = "hud_minigamemenu_current";
412 currb.model = strzone(minigame_texture(strcat(active_minigame.descriptor.netname,"/icon")));
413 HUD_MinigameMenu_InsertEntry(currb,HUD_MinigameMenu_last_entry);
414 HUD_MinigameMenu_Click(currb);
419 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = p.list_prev )
422 if ( e.classname == "hud_minigamemenu_current" )
426 p = HUD_MinigameMenu_last_entry;
427 HUD_MinigameMenu_EraseEntry(e);
431 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = e.list_prev )
432 if ( e.classname == "hud_minigamemenu_exit" )
434 entity exit = HUD_MinigameMenu_SpawnEntry(
435 _("Exit Menu"),'0 0 0',hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_Close);
436 exit.classname = "hud_minigamemenu_exit";
437 HUD_MinigameMenu_InsertEntry ( exit, HUD_MinigameMenu_last_entry );
441 // Open the minigame menu panel
442 void HUD_MinigameMenu_Open()
444 if ( !mv_active && !HUD_MinigameMenu_IsOpened() )
446 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnEntry(
447 _("Create"), '0 0 0', hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickCreate),
448 HUD_MinigameMenu_last_entry );
449 HUD_MinigameMenu_InsertEntry ( HUD_MinigameMenu_SpawnEntry(
450 _("Join"),'0 0 0',hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickJoin),
451 HUD_MinigameMenu_last_entry );
452 HUD_MinigameMenu_CurrentButton();
453 HUD_MinigameMenu_activeitem = NULL;
457 // Handles mouse input on to minigame menu panel
458 void HUD_MinigameMenu_MouseInput()
460 panel = HUD_PANEL(MINIGAMEMENU);
462 HUD_Panel_LoadCvars();
466 panel_pos += '1 1 0' * panel_bg_padding;
467 panel_size -= '2 2 0' * panel_bg_padding;
472 panel_pos_y += hud_fontsize_y*2;
474 HUD_MinigameMenu_activeitem = NULL;
476 for ( e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
478 sz = eX*panel_size_x + eY*e.size_y;
481 if ( !HUD_MinigameMenu_activeitem && mousepos_y >= panel_pos_y && mousepos_y <= panel_pos_y + sz_y )
483 HUD_MinigameMenu_activeitem = e;
490 void HUD_MinigameMenu_DrawEntry(vector pos, string s, vector fontsize, vector color)
492 minigame_drawstring_trunc(panel_size_x-pos_x+panel_pos_x, pos, s,
493 fontsize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
495 // Draw a color-coded menu
496 void HUD_MinigameMenu_DrawColoredEntry(vector pos, string s, vector fontsize)
498 minigame_drawcolorcodedstring_trunc(panel_size_x-pos_x+panel_pos_x, pos, s,
499 fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
502 // Minigame menu panel UI
503 void HUD_MinigameMenu ()
507 if (HUD_MinigameMenu_IsOpened())
508 HUD_MinigameMenu_Close(NULL, NULL, NULL);
512 if ( !HUD_MinigameMenu_IsOpened() )
515 HUD_Panel_LoadCvars();
522 panel_pos += '1 1 0' * panel_bg_padding;
523 panel_size -= '2 2 0' * panel_bg_padding;
526 HUD_MinigameMenu_DrawEntry(panel_pos,_("Minigames"),hud_fontsize*2,'0.25 0.47 0.72');
527 panel_pos_y += hud_fontsize_y*2;
532 vector imgsz = '22 22 0'; // NOTE: if changed, edit where HUD_MinigameMenu_activeitem is selected
533 for ( entity e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
545 drawfill(panel_pos, eX*panel_size_x + eY*itemh, e.colormod,
546 panel_fg_alpha, DRAWFLAG_NORMAL);
552 drawpic( panel_pos+offset, e.model, imgsz, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
554 offset_y = (imgsz_y-e.size_y) / 2;
558 HUD_MinigameMenu_DrawColoredEntry(panel_pos+offset,e.message,e.size);
560 HUD_MinigameMenu_DrawEntry(panel_pos+offset,e.message,e.size,color);
562 if ( e == HUD_MinigameMenu_activeitem )
563 drawfill(panel_pos, eX*panel_size_x + eY*itemh,'1 1 1', 0.25, DRAWFLAG_ADDITIVE);
565 panel_pos_y += itemh;
569 // ====================================================================
570 // Minigame Help Panel
571 // ====================================================================
573 void HUD_MinigameHelp()
575 if (!HUD_MinigameMenu_IsOpened())
580 if(!autocvar__hud_configure)
582 if (!active_minigame)
584 help_message = active_minigame.message;
587 help_message = _("Minigame message");
592 HUD_Panel_LoadCvars();
601 pos += '1 1 0' * panel_bg_padding;
602 mySize -= '2 2 0' * panel_bg_padding;
605 minigame_drawcolorcodedstring_wrapped( mySize_x, pos, help_message,
606 hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL, 0.5 );
609 // ====================================================================
610 // Minigame Panel Input
611 // ====================================================================
612 float HUD_Minigame_InputEvent(float bInputType, float nPrimary, float nSecondary)
615 if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure )
620 mousepos_x = nPrimary;
621 mousepos_y = nSecondary;
622 if ( active_minigame && HUD_mouse_over(HUD_PANEL(MINIGAMEBOARD)) )
623 active_minigame.minigame_event(active_minigame,"mouse_moved",mousepos);
629 if(bInputType == 0) {
630 if(nPrimary == K_ALT) hudShiftState |= S_ALT;
631 if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
632 if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
633 if(nPrimary == K_MOUSE1) mouseClicked |= S_MOUSE1;
634 if(nPrimary == K_MOUSE2) mouseClicked |= S_MOUSE2;
636 else if(bInputType == 1) {
637 if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
638 if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
639 if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
640 if(nPrimary == K_MOUSE1) mouseClicked -= (mouseClicked & S_MOUSE1);
641 if(nPrimary == K_MOUSE2) mouseClicked -= (mouseClicked & S_MOUSE2);
645 string con_keys = findkeysforcommand("toggleconsole", 0);
646 int keys = tokenize(con_keys); // findkeysforcommand returns data for this
648 for (i = 0; i < keys; ++i)
650 if(nPrimary == stof(argv(i)))
654 if ( active_minigame && ( bInputType == 0 || bInputType == 1 ) )
657 string action = bInputType == 0 ? "pressed" : "released";
658 if ( nPrimary >= K_MOUSE1 && nPrimary <= K_MOUSE16 )
660 if ( HUD_mouse_over(HUD_PANEL(MINIGAMEBOARD)) )
666 if ( device && active_minigame.minigame_event(
667 active_minigame,strcat(device,"_",action),nPrimary) )
670 /// TODO: bInputType == 2?
673 if ( bInputType == 0 )
675 if ( nPrimary == K_MOUSE1 && HUD_MinigameMenu_activeitem &&
676 HUD_mouse_over(HUD_PANEL(MINIGAMEMENU)) )
678 HUD_MinigameMenu_Click(HUD_MinigameMenu_activeitem);
681 if ( nPrimary == K_UPARROW || nPrimary == K_KP_UPARROW )
683 if ( HUD_MinigameMenu_activeitem && HUD_MinigameMenu_activeitem.list_prev )
684 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_activeitem.list_prev;
686 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_last_entry;
689 else if ( nPrimary == K_DOWNARROW || nPrimary == K_KP_DOWNARROW )
691 if ( HUD_MinigameMenu_activeitem && HUD_MinigameMenu_activeitem.list_next )
692 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_activeitem.list_next;
694 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
697 else if ( nPrimary == K_HOME || nPrimary == K_KP_HOME )
699 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
702 else if ( nPrimary == K_END || nPrimary == K_KP_END )
704 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
707 else if ( nPrimary == K_KP_ENTER || nPrimary == K_ENTER || nPrimary == K_SPACE )
709 HUD_MinigameMenu_Click(HUD_MinigameMenu_activeitem);
712 else if ( nPrimary == K_ESCAPE )
714 HUD_MinigameMenu_Close(NULL, NULL, NULL);
724 void HUD_Minigame_Mouse()
726 if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure || mv_active )
729 if ( HUD_MinigameMenu_IsOpened() && HUD_mouse_over(HUD_PANEL(MINIGAMEMENU)) )
730 HUD_MinigameMenu_MouseInput();