1 #include "cl_minigames_hud.qh"
3 #include <client/autocvars.qh>
4 #include <client/draw.qh>
5 #include <common/ent_cs.qh>
7 #include "minigames.qh"
11 #include <client/hud/hud_config.qh>
12 #include <client/mapvoting.qh>
14 void HUD_MinigameBoard_Export(int fh)
16 // allow saving cvars that aesthetically change the panel into hud skin files
19 void HUD_MinigameStatus_Export(int fh)
21 // allow saving cvars that aesthetically change the panel into hud skin files
24 void HUD_MinigameHelp_Export(int fh)
26 // allow saving cvars that aesthetically change the panel into hud skin files
29 void HUD_MinigameMenu_Export(int fh)
31 // allow saving cvars that aesthetically change the panel into hud skin files
34 // whether the mouse is over the given panel
35 bool HUD_mouse_over(entity somepanel)
37 vector pos = stov(cvar_string(strcat("hud_panel_", somepanel.panel_name, "_pos")));
38 vector sz = stov(cvar_string(strcat("hud_panel_", somepanel.panel_name, "_size")));
39 return mousepos_x >= pos_x*vid_conwidth && mousepos_x <= (pos_x+sz_x)*vid_conwidth &&
40 mousepos_y >= pos_y*vid_conheight && mousepos_y <= (pos_y+sz_y)*vid_conheight ;
43 // ====================================================================
45 // ====================================================================
47 // Draws the minigame game board
48 void HUD_MinigameBoard ()
50 if (!HUD_MinigameMenu_IsOpened())
53 entity hud_minigame = NULL;
55 if(!autocvar__hud_configure)
59 hud_minigame = active_minigame.descriptor;
62 hud_minigame = minigame_get_descriptor("nmm");
67 HUD_Panel_LoadCvars();
74 hud_minigame.minigame_hud_board(pos,mySize);
77 // ====================================================================
79 // ====================================================================
80 // Draws the minigame status panel
81 void HUD_MinigameStatus ()
83 if (!HUD_MinigameMenu_IsOpened())
86 entity hud_minigame = NULL;
88 if(!autocvar__hud_configure)
92 hud_minigame = active_minigame.descriptor;
95 hud_minigame = minigame_get_descriptor("nmm");
100 HUD_Panel_LoadCvars();
109 pos += '1 1 0' * panel_bg_padding;
110 mySize -= '2 2 0' * panel_bg_padding;
114 hud_minigame.minigame_hud_status(pos,mySize);
117 // ====================================================================
119 // ====================================================================
121 // Minigame menu options: list head
122 entity HUD_MinigameMenu_entries;
123 // Minigame menu options: list tail
124 entity HUD_MinigameMenu_last_entry;
126 // Minigame menu options: insert entry after the given location
127 void HUD_MinigameMenu_InsertEntry(entity newentry, entity prev)
129 if ( !HUD_MinigameMenu_entries )
131 HUD_MinigameMenu_entries = newentry;
132 HUD_MinigameMenu_last_entry = newentry;
136 newentry.list_prev = prev;
137 newentry.list_next = prev.list_next;
138 if ( prev.list_next )
139 prev.list_next.list_prev = newentry;
141 HUD_MinigameMenu_last_entry = newentry;
142 prev.list_next = newentry;
147 // minigame menu item uder the mouse
148 entity HUD_MinigameMenu_activeitem;
150 // Click the given item
151 void HUD_MinigameMenu_Click(entity menuitem)
155 menuitem.use(menuitem, NULL, NULL);
159 // Minigame menu options: Remove the given entry
160 // Precondition: the given entry is actually in the list
161 void HUD_MinigameMenu_EraseEntry ( entity e )
163 // remove child items (if any)
166 HUD_MinigameMenu_Click(e);
170 e.list_prev.list_next = e.list_next;
172 HUD_MinigameMenu_entries = e.list_next;
175 e.list_next.list_prev = e.list_prev;
177 HUD_MinigameMenu_last_entry = e.list_prev;
179 if ( HUD_MinigameMenu_activeitem == e )
180 HUD_MinigameMenu_activeitem = NULL;
185 // Minigame menu options: create entry
186 entity HUD_MinigameMenu_SpawnEntry(string s, vector offset, vector fontsize, vector color,void(entity, entity, entity) click)
188 entity entry = spawn();
190 entry.origin = offset;
191 entry.size = fontsize;
192 entry.colormod = color;
195 panel_pos_y += fontsize_y;
199 // Spawn a child entry of a collapsable entry
200 entity HUD_MinigameMenu_SpawnSubEntry(string s, void(entity, entity, entity) click, entity parent)
202 vector item_fontsize = hud_fontsize*1.25;
203 vector item_offset = '1 0 0' * item_fontsize_x;
204 entity item = HUD_MinigameMenu_SpawnEntry(
205 s,item_offset,item_fontsize,'0.8 0.8 0.8', click );
210 // Click action for Create sub-entries
211 void HUD_MinigameMenu_ClickCreate_Entry(entity this, entity actor, entity trigger)
213 minigame_cmd("create ", this.netname);
216 // Helper click action for collapsible entries
217 // returns true when you have to create the sub-entries
218 bool HUD_MinigameMenu_Click_ExpandCollapse(entity this)
221 if ( this.flags & 2 )
223 if ( HUD_MinigameMenu_activeitem &&
224 HUD_MinigameMenu_activeitem.owner == this )
225 HUD_MinigameMenu_activeitem = NULL;
227 for ( e = this.list_next; e != NULL && e.owner == this; e = this.list_next )
230 HUD_MinigameMenu_Click(e);
231 this.list_next = e.list_next;
234 if ( this.list_next )
235 this.list_next.list_prev = this;
237 HUD_MinigameMenu_last_entry = this;
241 for ( e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
243 if ( (e.flags & 2) && e.origin_x == this.origin_x)
244 HUD_MinigameMenu_Click(e);
254 // Click action for the Create menu
255 void HUD_MinigameMenu_ClickCreate(entity this, entity actor, entity trigger)
257 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
261 FOREACH(Minigames, true, {
262 curr = HUD_MinigameMenu_SpawnSubEntry(it.message, HUD_MinigameMenu_ClickCreate_Entry, this);
263 curr.netname = it.netname;
264 curr.model = strzone(minigame_texture(strcat(it.netname,"/icon")));
265 HUD_MinigameMenu_InsertEntry( curr, prev );
271 // Click action for Join sub-entries
272 void HUD_MinigameMenu_ClickJoin_Entry(entity this, entity actor, entity trigger)
274 minigame_cmd("join ",this.netname);
275 HUD_MinigameMenu_EraseEntry(this);
278 // Click action for the Join menu
279 void HUD_MinigameMenu_ClickJoin(entity this, entity actor, entity trigger)
281 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
286 while( (e = find(e,classname,"minigame")) )
288 if ( e != active_minigame )
290 curr = HUD_MinigameMenu_SpawnSubEntry(
291 e.netname, HUD_MinigameMenu_ClickJoin_Entry, this );
292 curr.netname = e.netname;
293 curr.model = strzone(minigame_texture(strcat(e.descriptor.netname,"/icon")));
294 HUD_MinigameMenu_InsertEntry( curr, prev );
301 /*// Temporary placeholder for un-implemented Click actions
302 void HUD_MinigameMenu_ClickNoop()
304 dprint("Placeholder for ",this.message,"\n");
307 // Click action for Quit
308 void HUD_MinigameMenu_ClickQuit(entity this, entity actor, entity trigger)
310 deactivate_minigame();
314 // Click action for Invite sub-entries
315 void HUD_MinigameMenu_ClickInvite_Entry(entity this, entity actor, entity trigger)
317 minigame_cmd("invite #",this.netname);
320 // Click action for the Invite menu
321 void HUD_MinigameMenu_ClickInvite(entity this, entity actor, entity trigger)
323 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
327 for(int i = 0; i < maxclients; ++i)
329 if ( player_localnum != i && playerslots[i] && entcs_GetName(i) != "" &&
330 !findfloat(NULL,minigame_playerslot,i+1) && playerslots[i].ping )
332 e = HUD_MinigameMenu_SpawnSubEntry(
333 strzone(entcs_GetName(i)), HUD_MinigameMenu_ClickInvite_Entry,
336 e.netname = strzone(ftos(i+1));
338 HUD_MinigameMenu_InsertEntry(e,prev);
345 void HUD_MinigameMenu_ClickCustomEntry(entity this, entity actor, entity trigger)
347 if ( active_minigame )
348 active_minigame.minigame_event(active_minigame,"menu_click",this.netname);
351 // Adds a game-specific entry to the menu
352 void HUD_MinigameMenu_CustomEntry(entity parent, string menumessage, string event_arg)
354 entity e = HUD_MinigameMenu_SpawnSubEntry(
355 menumessage, HUD_MinigameMenu_ClickCustomEntry, parent );
356 e.netname = event_arg;
357 HUD_MinigameMenu_InsertEntry(e, parent);
358 //dprint("CustomEntry ",ftos(num_for_edict(parent))," ",menumessage," ",event_arg,"\n");
361 // Click action for the Current Game menu
362 void HUD_MinigameMenu_ClickCurrentGame(entity this, entity actor, entity trigger)
364 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
366 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnSubEntry(
367 _("Quit"), HUD_MinigameMenu_ClickQuit, this ), this);
369 active_minigame.minigame_event(active_minigame,"menu_show",this);
371 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnSubEntry(
372 _("Invite"), HUD_MinigameMenu_ClickInvite, this), this);
375 // Whether the minigame menu panel is open
376 bool HUD_MinigameMenu_IsOpened()
378 return HUD_MinigameMenu_entries != NULL;
381 // Close the minigame menu panel
382 void HUD_MinigameMenu_Close(entity this, entity actor, entity trigger)
384 if ( HUD_MinigameMenu_IsOpened() )
387 for ( e = HUD_MinigameMenu_entries; e != NULL; e = p )
392 HUD_MinigameMenu_entries = NULL;
393 HUD_MinigameMenu_last_entry = NULL;
394 HUD_MinigameMenu_activeitem = NULL;
398 // toggle a button to manage the current game
399 void HUD_MinigameMenu_CurrentButton()
402 if ( active_minigame )
404 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = e.list_prev )
405 if ( e.classname == "hud_minigamemenu_exit" )
407 HUD_MinigameMenu_EraseEntry(e);
410 entity currb = HUD_MinigameMenu_SpawnEntry(
411 _("Current Game"), '0 0 0', hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickCurrentGame );
412 currb.classname = "hud_minigamemenu_current";
413 currb.model = strzone(minigame_texture(strcat(active_minigame.descriptor.netname,"/icon")));
414 HUD_MinigameMenu_InsertEntry(currb,HUD_MinigameMenu_last_entry);
415 HUD_MinigameMenu_Click(currb);
420 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = p.list_prev )
423 if ( e.classname == "hud_minigamemenu_current" )
427 p = HUD_MinigameMenu_last_entry;
428 HUD_MinigameMenu_EraseEntry(e);
432 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = e.list_prev )
433 if ( e.classname == "hud_minigamemenu_exit" )
435 entity exit = HUD_MinigameMenu_SpawnEntry(
436 _("Exit Menu"),'0 0 0',hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_Close);
437 exit.classname = "hud_minigamemenu_exit";
438 HUD_MinigameMenu_InsertEntry ( exit, HUD_MinigameMenu_last_entry );
442 // Open the minigame menu panel
443 void HUD_MinigameMenu_Open()
445 if ( !mv_active && !HUD_MinigameMenu_IsOpened() )
447 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnEntry(
448 _("Create"), '0 0 0', hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickCreate),
449 HUD_MinigameMenu_last_entry );
450 HUD_MinigameMenu_InsertEntry ( HUD_MinigameMenu_SpawnEntry(
451 _("Join"),'0 0 0',hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickJoin),
452 HUD_MinigameMenu_last_entry );
453 HUD_MinigameMenu_CurrentButton();
454 HUD_MinigameMenu_activeitem = NULL;
458 // Handles mouse input on to minigame menu panel
459 void HUD_MinigameMenu_MouseInput()
461 panel = HUD_PANEL(MINIGAMEMENU);
463 HUD_Panel_LoadCvars();
467 panel_pos += '1 1 0' * panel_bg_padding;
468 panel_size -= '2 2 0' * panel_bg_padding;
473 panel_pos_y += hud_fontsize_y*2;
475 HUD_MinigameMenu_activeitem = NULL;
477 for ( e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
479 sz = eX*panel_size_x + eY*e.size_y;
482 if ( !HUD_MinigameMenu_activeitem && mousepos_y >= panel_pos_y && mousepos_y <= panel_pos_y + sz_y )
484 HUD_MinigameMenu_activeitem = e;
491 void HUD_MinigameMenu_DrawEntry(vector pos, string s, vector fontsize, vector color)
493 minigame_drawstring_trunc(panel_size_x-pos_x+panel_pos_x, pos, s,
494 fontsize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
496 // Draw a color-coded menu
497 void HUD_MinigameMenu_DrawColoredEntry(vector pos, string s, vector fontsize)
499 minigame_drawcolorcodedstring_trunc(panel_size_x-pos_x+panel_pos_x, pos, s,
500 fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
503 // Minigame menu panel UI
504 void HUD_MinigameMenu ()
508 if (HUD_MinigameMenu_IsOpened())
509 HUD_MinigameMenu_Close(NULL, NULL, NULL);
513 if ( !HUD_MinigameMenu_IsOpened() )
516 HUD_Panel_LoadCvars();
523 panel_pos += '1 1 0' * panel_bg_padding;
524 panel_size -= '2 2 0' * panel_bg_padding;
527 HUD_MinigameMenu_DrawEntry(panel_pos,_("Minigames"),hud_fontsize*2,'0.25 0.47 0.72');
528 panel_pos_y += hud_fontsize_y*2;
533 vector imgsz = '22 22 0'; // NOTE: if changed, edit where HUD_MinigameMenu_activeitem is selected
534 for ( entity e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
546 drawfill(panel_pos, eX*panel_size_x + eY*itemh, e.colormod,
547 panel_fg_alpha, DRAWFLAG_NORMAL);
553 drawpic( panel_pos+offset, e.model, imgsz, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
555 offset_y = (imgsz_y-e.size_y) / 2;
559 HUD_MinigameMenu_DrawColoredEntry(panel_pos+offset,e.message,e.size);
561 HUD_MinigameMenu_DrawEntry(panel_pos+offset,e.message,e.size,color);
563 if ( e == HUD_MinigameMenu_activeitem )
564 drawfill(panel_pos, eX*panel_size_x + eY*itemh,'1 1 1', 0.25, DRAWFLAG_ADDITIVE);
566 panel_pos_y += itemh;
570 // ====================================================================
571 // Minigame Help Panel
572 // ====================================================================
574 void HUD_MinigameHelp()
576 if (!HUD_MinigameMenu_IsOpened())
581 if(!autocvar__hud_configure)
583 if (!active_minigame)
585 help_message = active_minigame.message;
588 help_message = _("Minigame message");
593 HUD_Panel_LoadCvars();
602 pos += '1 1 0' * panel_bg_padding;
603 mySize -= '2 2 0' * panel_bg_padding;
606 minigame_drawcolorcodedstring_wrapped( mySize_x, pos, help_message,
607 hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL, 0.5 );
610 // ====================================================================
611 // Minigame Panel Input
612 // ====================================================================
613 float HUD_Minigame_InputEvent(float bInputType, float nPrimary, float nSecondary)
616 if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure )
621 mousepos_x = nPrimary;
622 mousepos_y = nSecondary;
623 if ( active_minigame && HUD_mouse_over(HUD_PANEL(MINIGAMEBOARD)) )
624 active_minigame.minigame_event(active_minigame,"mouse_moved",mousepos);
630 if(bInputType == 0) {
631 if(nPrimary == K_ALT) hudShiftState |= S_ALT;
632 if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
633 if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
634 if(nPrimary == K_MOUSE1) mouseClicked |= S_MOUSE1;
635 if(nPrimary == K_MOUSE2) mouseClicked |= S_MOUSE2;
637 else if(bInputType == 1) {
638 if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
639 if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
640 if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
641 if(nPrimary == K_MOUSE1) mouseClicked -= (mouseClicked & S_MOUSE1);
642 if(nPrimary == K_MOUSE2) mouseClicked -= (mouseClicked & S_MOUSE2);
646 string con_keys = findkeysforcommand("toggleconsole", 0);
647 int keys = tokenize(con_keys); // findkeysforcommand returns data for this
649 for (i = 0; i < keys; ++i)
651 if(nPrimary == stof(argv(i)))
655 if ( active_minigame && ( bInputType == 0 || bInputType == 1 ) )
658 string action = bInputType == 0 ? "pressed" : "released";
659 if ( nPrimary >= K_MOUSE1 && nPrimary <= K_MOUSE16 )
661 if ( HUD_mouse_over(HUD_PANEL(MINIGAMEBOARD)) )
667 if ( device && active_minigame.minigame_event(
668 active_minigame,strcat(device,"_",action),nPrimary) )
671 /// TODO: bInputType == 2?
674 if ( bInputType == 0 )
676 if ( nPrimary == K_MOUSE1 && HUD_MinigameMenu_activeitem &&
677 HUD_mouse_over(HUD_PANEL(MINIGAMEMENU)) )
679 HUD_MinigameMenu_Click(HUD_MinigameMenu_activeitem);
682 if ( nPrimary == K_UPARROW || nPrimary == K_KP_UPARROW )
684 if ( HUD_MinigameMenu_activeitem && HUD_MinigameMenu_activeitem.list_prev )
685 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_activeitem.list_prev;
687 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_last_entry;
690 else if ( nPrimary == K_DOWNARROW || nPrimary == K_KP_DOWNARROW )
692 if ( HUD_MinigameMenu_activeitem && HUD_MinigameMenu_activeitem.list_next )
693 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_activeitem.list_next;
695 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
698 else if ( nPrimary == K_HOME || nPrimary == K_KP_HOME )
700 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
703 else if ( nPrimary == K_END || nPrimary == K_KP_END )
705 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
708 else if ( nPrimary == K_KP_ENTER || nPrimary == K_ENTER || nPrimary == K_SPACE )
710 HUD_MinigameMenu_Click(HUD_MinigameMenu_activeitem);
713 else if ( nPrimary == K_ESCAPE )
715 HUD_MinigameMenu_Close(NULL, NULL, NULL);
725 void HUD_Minigame_Mouse()
727 if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure || mv_active )
730 if ( HUD_MinigameMenu_IsOpened() && HUD_mouse_over(HUD_PANEL(MINIGAMEMENU)) )
731 HUD_MinigameMenu_MouseInput();