1 #include "cl_minigames_hud.qh"
3 #include <common/ent_cs.qh>
5 #include "minigames.qh"
9 #include <client/hud/hud_config.qh>
10 #include <client/mapvoting.qh>
12 // whether the mouse is over the given panel
13 bool HUD_mouse_over(entity somepanel)
15 vector pos = stov(cvar_string(strcat("hud_panel_", somepanel.panel_name, "_pos")));
16 vector sz = stov(cvar_string(strcat("hud_panel_", somepanel.panel_name, "_size")));
17 return mousepos_x >= pos_x*vid_conwidth && mousepos_x <= (pos_x+sz_x)*vid_conwidth &&
18 mousepos_y >= pos_y*vid_conheight && mousepos_y <= (pos_y+sz_y)*vid_conheight ;
21 // ====================================================================
23 // ====================================================================
25 // Draws the minigame game board
26 void HUD_MinigameBoard ()
28 entity hud_minigame = NULL;
30 if(!autocvar__hud_configure)
31 hud_minigame = active_minigame.descriptor;
33 hud_minigame = minigame_get_descriptor("nmm");
38 HUD_Panel_LoadCvars();
45 hud_minigame.minigame_hud_board(pos,mySize);
48 // ====================================================================
50 // ====================================================================
51 // Draws the minigame status panel
52 void HUD_MinigameStatus ()
54 entity hud_minigame = NULL;
56 if(!autocvar__hud_configure)
57 hud_minigame = active_minigame.descriptor;
59 hud_minigame = minigame_get_descriptor("nmm");
64 HUD_Panel_LoadCvars();
73 pos += '1 1 0' * panel_bg_padding;
74 mySize -= '2 2 0' * panel_bg_padding;
78 hud_minigame.minigame_hud_status(pos,mySize);
81 // ====================================================================
83 // ====================================================================
85 // Minigame menu options: list head
86 entity HUD_MinigameMenu_entries;
87 // Minigame menu options: list tail
88 entity HUD_MinigameMenu_last_entry;
90 // Minigame menu options: insert entry after the given location
91 void HUD_MinigameMenu_InsertEntry(entity newentry, entity prev)
93 if ( !HUD_MinigameMenu_entries )
95 HUD_MinigameMenu_entries = newentry;
96 HUD_MinigameMenu_last_entry = newentry;
100 newentry.list_prev = prev;
101 newentry.list_next = prev.list_next;
102 if ( prev.list_next )
103 prev.list_next.list_prev = newentry;
105 HUD_MinigameMenu_last_entry = newentry;
106 prev.list_next = newentry;
111 // minigame menu item uder the mouse
112 entity HUD_MinigameMenu_activeitem;
114 // Click the given item
115 void HUD_MinigameMenu_Click(entity menuitem)
119 menuitem.use(menuitem, NULL, NULL);
123 // Minigame menu options: Remove the given entry
124 // Precondition: the given entry is actually in the list
125 void HUD_MinigameMenu_EraseEntry ( entity e )
127 // remove child items (if any)
130 HUD_MinigameMenu_Click(e);
134 e.list_prev.list_next = e.list_next;
136 HUD_MinigameMenu_entries = e.list_next;
139 e.list_next.list_prev = e.list_prev;
141 HUD_MinigameMenu_last_entry = e.list_prev;
143 if ( HUD_MinigameMenu_activeitem == e )
144 HUD_MinigameMenu_activeitem = NULL;
149 // Minigame menu options: create entry
150 entity HUD_MinigameMenu_SpawnEntry(string s, vector offset, vector fontsize, vector color,void(entity, entity, entity) click)
152 entity entry = spawn();
154 entry.origin = offset;
155 entry.size = fontsize;
156 entry.colormod = color;
159 panel_pos_y += fontsize_y;
163 // Spawn a child entry of a collapsable entry
164 entity HUD_MinigameMenu_SpawnSubEntry(string s, void(entity, entity, entity) click, entity parent)
166 vector item_fontsize = hud_fontsize*1.25;
167 vector item_offset = '1 0 0' * item_fontsize_x;
168 entity item = HUD_MinigameMenu_SpawnEntry(
169 s,item_offset,item_fontsize,'0.8 0.8 0.8', click );
174 // Click action for Create sub-entries
175 void HUD_MinigameMenu_ClickCreate_Entry(entity this, entity actor, entity trigger)
177 minigame_cmd("create ", this.netname);
180 // Helper click action for collapsible entries
181 // returns true when you have to create the sub-entries
182 bool HUD_MinigameMenu_Click_ExpandCollapse(entity this)
185 if ( this.flags & 2 )
187 if ( HUD_MinigameMenu_activeitem &&
188 HUD_MinigameMenu_activeitem.owner == this )
189 HUD_MinigameMenu_activeitem = NULL;
191 for ( e = this.list_next; e != NULL && e.owner == this; e = this.list_next )
194 HUD_MinigameMenu_Click(e);
195 this.list_next = e.list_next;
198 if ( this.list_next )
199 this.list_next.list_prev = this;
201 HUD_MinigameMenu_last_entry = this;
205 for ( e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
207 if ( e.flags & 2 && e.origin_x == this.origin_x)
208 HUD_MinigameMenu_Click(e);
218 // Click action for the Create menu
219 void HUD_MinigameMenu_ClickCreate(entity this, entity actor, entity trigger)
221 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
225 FOREACH(Minigames, true, {
226 curr = HUD_MinigameMenu_SpawnSubEntry(it.message, HUD_MinigameMenu_ClickCreate_Entry, this);
227 curr.netname = it.netname;
228 curr.model = strzone(minigame_texture(strcat(it.netname,"/icon")));
229 HUD_MinigameMenu_InsertEntry( curr, prev );
235 // Click action for Join sub-entries
236 void HUD_MinigameMenu_ClickJoin_Entry(entity this, entity actor, entity trigger)
238 minigame_cmd("join ",this.netname);
239 HUD_MinigameMenu_EraseEntry(this);
242 // Click action for the Join menu
243 void HUD_MinigameMenu_ClickJoin(entity this, entity actor, entity trigger)
245 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
250 while( (e = find(e,classname,"minigame")) )
252 if ( e != active_minigame )
254 curr = HUD_MinigameMenu_SpawnSubEntry(
255 e.netname, HUD_MinigameMenu_ClickJoin_Entry, this );
256 curr.netname = e.netname;
257 curr.model = strzone(minigame_texture(strcat(e.descriptor.netname,"/icon")));
258 HUD_MinigameMenu_InsertEntry( curr, prev );
265 /*// Temporary placeholder for un-implemented Click actions
266 void HUD_MinigameMenu_ClickNoop()
268 dprint("Placeholder for ",this.message,"\n");
271 // Click action for Quit
272 void HUD_MinigameMenu_ClickQuit(entity this, entity actor, entity trigger)
274 deactivate_minigame();
278 // Click action for Invite sub-entries
279 void HUD_MinigameMenu_ClickInvite_Entry(entity this, entity actor, entity trigger)
281 minigame_cmd("invite #",this.netname);
284 // Click action for the Invite menu
285 void HUD_MinigameMenu_ClickInvite(entity this, entity actor, entity trigger)
287 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
291 for(int i = 0; i < maxclients; ++i)
293 if ( player_localnum != i && playerslots[i] && entcs_GetName(i) != "" &&
294 !findfloat(NULL,minigame_playerslot,i+1) && playerslots[i].ping )
296 e = HUD_MinigameMenu_SpawnSubEntry(
297 strzone(entcs_GetName(i)), HUD_MinigameMenu_ClickInvite_Entry,
300 e.netname = strzone(ftos(i+1));
302 HUD_MinigameMenu_InsertEntry(e,prev);
309 void HUD_MinigameMenu_ClickCustomEntry(entity this, entity actor, entity trigger)
311 if ( active_minigame )
312 active_minigame.minigame_event(active_minigame,"menu_click",this.netname);
315 // Adds a game-specific entry to the menu
316 void HUD_MinigameMenu_CustomEntry(entity parent, string menumessage, string event_arg)
318 entity e = HUD_MinigameMenu_SpawnSubEntry(
319 menumessage, HUD_MinigameMenu_ClickCustomEntry, parent );
320 e.netname = event_arg;
321 HUD_MinigameMenu_InsertEntry(e, parent);
322 //dprint("CustomEntry ",ftos(num_for_edict(parent))," ",menumessage," ",event_arg,"\n");
325 // Click action for the Current Game menu
326 void HUD_MinigameMenu_ClickCurrentGame(entity this, entity actor, entity trigger)
328 if ( HUD_MinigameMenu_Click_ExpandCollapse(this) )
330 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnSubEntry(
331 _("Quit"), HUD_MinigameMenu_ClickQuit, this ), this);
333 active_minigame.minigame_event(active_minigame,"menu_show",this);
335 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnSubEntry(
336 _("Invite"), HUD_MinigameMenu_ClickInvite, this), this);
339 // Whether the minigame menu panel is open
340 bool HUD_MinigameMenu_IsOpened()
342 return HUD_MinigameMenu_entries != NULL;
345 // Close the minigame menu panel
346 void HUD_MinigameMenu_Close(entity this, entity actor, entity trigger)
348 if ( HUD_MinigameMenu_IsOpened() )
351 for ( e = HUD_MinigameMenu_entries; e != NULL; e = p )
356 HUD_MinigameMenu_entries = NULL;
357 HUD_MinigameMenu_last_entry = NULL;
358 HUD_MinigameMenu_activeitem = NULL;
359 if(autocvar_hud_cursormode)
360 if ( !autocvar__hud_configure )
365 // toggle a button to manage the current game
366 void HUD_MinigameMenu_CurrentButton()
369 if ( active_minigame )
371 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = e.list_prev )
372 if ( e.classname == "hud_minigamemenu_exit" )
374 HUD_MinigameMenu_EraseEntry(e);
377 entity currb = HUD_MinigameMenu_SpawnEntry(
378 _("Current Game"), '0 0 0', hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickCurrentGame );
379 currb.classname = "hud_minigamemenu_current";
380 currb.model = strzone(minigame_texture(strcat(active_minigame.descriptor.netname,"/icon")));
381 HUD_MinigameMenu_InsertEntry(currb,HUD_MinigameMenu_last_entry);
382 HUD_MinigameMenu_Click(currb);
387 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = p.list_prev )
390 if ( e.classname == "hud_minigamemenu_current" )
394 p = HUD_MinigameMenu_last_entry;
395 HUD_MinigameMenu_EraseEntry(e);
399 for ( e = HUD_MinigameMenu_last_entry; e != NULL; e = e.list_prev )
400 if ( e.classname == "hud_minigamemenu_exit" )
402 entity exit = HUD_MinigameMenu_SpawnEntry(
403 _("Exit Menu"),'0 0 0',hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_Close);
404 exit.classname = "hud_minigamemenu_exit";
405 HUD_MinigameMenu_InsertEntry ( exit, HUD_MinigameMenu_last_entry );
409 // Open the minigame menu panel
410 void HUD_MinigameMenu_Open()
412 if ( !HUD_MinigameMenu_IsOpened() )
414 HUD_MinigameMenu_InsertEntry( HUD_MinigameMenu_SpawnEntry(
415 _("Create"), '0 0 0', hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickCreate),
416 HUD_MinigameMenu_last_entry );
417 HUD_MinigameMenu_InsertEntry ( HUD_MinigameMenu_SpawnEntry(
418 _("Join"),'0 0 0',hud_fontsize*1.5,'0.7 0.84 1', HUD_MinigameMenu_ClickJoin),
419 HUD_MinigameMenu_last_entry );
420 HUD_MinigameMenu_CurrentButton();
421 HUD_MinigameMenu_activeitem = NULL;
422 if(autocvar_hud_cursormode)
427 // Handles mouse input on to minigame menu panel
428 void HUD_MinigameMenu_MouseInput()
430 panel = HUD_PANEL(MINIGAME_MENU);
432 HUD_Panel_LoadCvars();
436 panel_pos += '1 1 0' * panel_bg_padding;
437 panel_size -= '2 2 0' * panel_bg_padding;
442 panel_pos_y += hud_fontsize_y*2;
444 HUD_MinigameMenu_activeitem = NULL;
446 for ( e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
448 sz = eX*panel_size_x + eY*e.size_y;
451 if ( !HUD_MinigameMenu_activeitem && mousepos_y >= panel_pos_y && mousepos_y <= panel_pos_y + sz_y )
453 HUD_MinigameMenu_activeitem = e;
460 void HUD_MinigameMenu_DrawEntry(vector pos, string s, vector fontsize, vector color)
462 minigame_drawstring_trunc(panel_size_x-pos_x+panel_pos_x, pos, s,
463 fontsize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
465 // Draw a color-coded menu
466 void HUD_MinigameMenu_DrawColoredEntry(vector pos, string s, vector fontsize)
468 minigame_drawcolorcodedstring_trunc(panel_size_x-pos_x+panel_pos_x, pos, s,
469 fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
472 // Minigame menu panel UI
473 void HUD_MinigameMenu ()
475 if ( !HUD_MinigameMenu_IsOpened() )
478 HUD_Panel_LoadCvars();
485 panel_pos += '1 1 0' * panel_bg_padding;
486 panel_size -= '2 2 0' * panel_bg_padding;
489 HUD_MinigameMenu_DrawEntry(panel_pos,_("Minigames"),hud_fontsize*2,'0.25 0.47 0.72');
490 panel_pos_y += hud_fontsize_y*2;
495 vector imgsz = '22 22 0'; // NOTE: if changed, edit where HUD_MinigameMenu_activeitem is selected
496 for ( entity e = HUD_MinigameMenu_entries; e != NULL; e = e.list_next )
508 drawfill(panel_pos, eX*panel_size_x + eY*itemh, e.colormod,
509 panel_fg_alpha, DRAWFLAG_NORMAL);
515 drawpic( panel_pos+offset, e.model, imgsz, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL );
517 offset_y = (imgsz_y-e.size_y) / 2;
521 HUD_MinigameMenu_DrawColoredEntry(panel_pos+offset,e.message,e.size);
523 HUD_MinigameMenu_DrawEntry(panel_pos+offset,e.message,e.size,color);
525 if ( e == HUD_MinigameMenu_activeitem )
526 drawfill(panel_pos, eX*panel_size_x + eY*itemh,'1 1 1', 0.25, DRAWFLAG_ADDITIVE);
528 panel_pos_y += itemh;
532 // ====================================================================
533 // Minigame Help Panel
534 // ====================================================================
536 void HUD_MinigameHelp()
540 if(!autocvar__hud_configure)
541 help_message = active_minigame.message;
543 help_message = "Minigame message";
548 HUD_Panel_LoadCvars();
557 pos += '1 1 0' * panel_bg_padding;
558 mySize -= '2 2 0' * panel_bg_padding;
561 minigame_drawcolorcodedstring_wrapped( mySize_x, pos, help_message,
562 hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL, 0.5 );
565 // ====================================================================
566 // Minigame Panel Input
567 // ====================================================================
568 float HUD_Minigame_InputEvent(float bInputType, float nPrimary, float nSecondary)
571 if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure )
576 mousepos_x = nPrimary;
577 mousepos_y = nSecondary;
578 if ( minigame_isactive() && HUD_mouse_over(HUD_PANEL(MINIGAME_BOARD)) )
579 active_minigame.minigame_event(active_minigame,"mouse_moved",mousepos);
585 if(bInputType == 0) {
586 if(nPrimary == K_ALT) hudShiftState |= S_ALT;
587 if(nPrimary == K_CTRL) hudShiftState |= S_CTRL;
588 if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT;
589 if(nPrimary == K_MOUSE1) mouseClicked |= S_MOUSE1;
590 if(nPrimary == K_MOUSE2) mouseClicked |= S_MOUSE2;
592 else if(bInputType == 1) {
593 if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT);
594 if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL);
595 if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT);
596 if(nPrimary == K_MOUSE1) mouseClicked -= (mouseClicked & S_MOUSE1);
597 if(nPrimary == K_MOUSE2) mouseClicked -= (mouseClicked & S_MOUSE2);
601 string con_keys = findkeysforcommand("toggleconsole", 0);
602 int keys = tokenize(con_keys); // findkeysforcommand returns data for this
604 for (i = 0; i < keys; ++i)
606 if(nPrimary == stof(argv(i)))
610 if ( minigame_isactive() && ( bInputType == 0 || bInputType == 1 ) )
613 string action = bInputType == 0 ? "pressed" : "released";
614 if ( nPrimary >= K_MOUSE1 && nPrimary <= K_MOUSE16 )
616 if ( HUD_mouse_over(HUD_PANEL(MINIGAME_BOARD)) )
622 if ( device && active_minigame.minigame_event(
623 active_minigame,strcat(device,"_",action),nPrimary) )
626 /// TODO: bInputType == 2?
629 if ( bInputType == 0 )
631 if ( nPrimary == K_MOUSE1 && HUD_MinigameMenu_activeitem &&
632 HUD_mouse_over(HUD_PANEL(MINIGAME_MENU)) )
634 HUD_MinigameMenu_Click(HUD_MinigameMenu_activeitem);
637 if ( nPrimary == K_UPARROW || nPrimary == K_KP_UPARROW )
639 if ( HUD_MinigameMenu_activeitem && HUD_MinigameMenu_activeitem.list_prev )
640 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_activeitem.list_prev;
642 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_last_entry;
645 else if ( nPrimary == K_DOWNARROW || nPrimary == K_KP_DOWNARROW )
647 if ( HUD_MinigameMenu_activeitem && HUD_MinigameMenu_activeitem.list_next )
648 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_activeitem.list_next;
650 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
653 else if ( nPrimary == K_HOME || nPrimary == K_KP_HOME )
655 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
658 else if ( nPrimary == K_END || nPrimary == K_KP_END )
660 HUD_MinigameMenu_activeitem = HUD_MinigameMenu_entries;
663 else if ( nPrimary == K_KP_ENTER || nPrimary == K_ENTER || nPrimary == K_SPACE )
665 HUD_MinigameMenu_Click(HUD_MinigameMenu_activeitem);
668 else if ( nPrimary == K_ESCAPE )
670 HUD_MinigameMenu_Close(NULL, NULL, NULL);
680 void HUD_Minigame_Mouse()
682 if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure || mv_active )
685 if(!autocvar_hud_cursormode)
687 mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
689 mousepos_x = bound(0, mousepos_x, vid_conwidth);
690 mousepos_y = bound(0, mousepos_y, vid_conheight);
693 if ( HUD_MinigameMenu_IsOpened() && HUD_mouse_over(HUD_PANEL(MINIGAME_MENU)) )
694 HUD_MinigameMenu_MouseInput();
696 draw_cursor_normal(mousepos, '1 1 1', panel_fg_alpha);
699 bool HUD_Minigame_Showpanels()
701 return (HUD_MinigameMenu_IsOpened() && minigame_isactive());