Line data Source code
1 : /*
2 : * menus.cpp
3 : *
4 : * automatic triggers for certain UIs in game
5 : * does not implement menus, just some low level bindings for main menu functionality
6 : */
7 :
8 : #include "../libprimis-headers/cube.h"
9 :
10 : #include "control.h"
11 : #include "menus.h"
12 : #include "ui.h"
13 :
14 : #include "world/octaedit.h"
15 :
16 : //internally relevant functionality
17 : namespace
18 : {
19 : struct Change final
20 : {
21 : int type;
22 : const char *desc;
23 :
24 : Change() {}
25 1 : Change(int type, const char *desc) : type(type), desc(desc) {}
26 :
27 0 : bool operator==(const Change & c) const
28 : {
29 0 : return type == c.type && std::strcmp(desc, c.desc) == 0;
30 : }
31 : };
32 : std::vector<Change> needsapply;
33 :
34 : VARP(applydialog, 0, 1, 1);
35 :
36 : //when 1: change UI shows up whenever a pending change is added
37 : //when 0: change UI does not appear and applychanges must be used manually
38 : VAR(showchanges, 0, 1, 1);
39 :
40 : //goes through and applies changes that are enqueued
41 1 : void applychanges()
42 : {
43 1 : int changetypes = 0;
44 2 : for(const Change &i : needsapply)
45 : {
46 1 : changetypes |= i.type;
47 : }
48 1 : if(changetypes&Change_Graphics)
49 : {
50 1 : execident("resetgl");
51 : }
52 0 : else if(changetypes&Change_Shaders)
53 : {
54 0 : execident("resetshaders");
55 : }
56 1 : if(changetypes&Change_Sound)
57 : {
58 0 : execident("resetsound");
59 : }
60 1 : }
61 :
62 : //returns if there are pending changes or not enqueued
63 1 : void pendingchanges(const int *idx)
64 : {
65 1 : if(idx)
66 : {
67 1 : if((needsapply.size()) > static_cast<uint>(*idx))
68 : {
69 0 : result(needsapply.at(*idx).desc);
70 : }
71 1 : else if(*idx < 0)
72 : {
73 1 : intret(needsapply.size());
74 : }
75 : }
76 1 : }
77 : }
78 :
79 : //externally relevant functionality
80 :
81 : //toggles if the main menu is shown
82 : VAR(mainmenu, 1, 1, 0);
83 :
84 1 : void addchange(const char *desc, int type)
85 : {
86 1 : if(!applydialog)
87 : {
88 0 : return;
89 : }
90 1 : for(const Change &i : needsapply)
91 : {
92 0 : if(!std::strcmp(i.desc, desc))
93 : {
94 0 : return;
95 : }
96 : }
97 1 : needsapply.emplace_back(type, desc);
98 1 : if(showchanges)
99 : {
100 1 : UI::showui("changes");
101 : }
102 : }
103 :
104 0 : void notifywelcome()
105 : {
106 0 : UI::hideui("servers");
107 0 : }
108 :
109 0 : void clearchanges(int type)
110 : {
111 0 : for(int i = needsapply.size(); --i >=0;) //note reverse iteration
112 : {
113 0 : Change &c = needsapply[i];
114 0 : if(c.type&type)
115 : {
116 0 : c.type &= ~type;
117 0 : if(!c.type)
118 : {
119 0 : auto it = std::find(needsapply.begin(), needsapply.end(), needsapply[i]);
120 0 : needsapply.erase(it);
121 : }
122 : }
123 : }
124 0 : if(needsapply.empty())
125 : {
126 0 : UI::hideui("changes");
127 : }
128 0 : }
129 :
130 0 : void clearmainmenu()
131 : {
132 0 : showchanges = 1;
133 0 : if(mainmenu && multiplayer)
134 : {
135 0 : mainmenu = 0;
136 0 : UI::hideui(nullptr);
137 : }
138 0 : }
139 :
140 1 : void initmenuscmds()
141 : {
142 1 : addcommand("applychanges", reinterpret_cast<identfun>(applychanges), "", Id_Command);
143 1 : addcommand("pendingchanges", reinterpret_cast<identfun>(pendingchanges), "b", Id_Command);
144 1 : }
|