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