]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/menu-div0test/nexuiz/campaign.c
-scmenu; make mapinfo default
[divverent/nexuiz.git] / data / qcsrc / menu-div0test / nexuiz / campaign.c
1 #ifdef INTERFACE
2 CLASS(NexuizCampaignList) EXTENDS(NexuizListBox)
3         METHOD(NexuizCampaignList, configureNexuizCampaignList, void(entity))
4         ATTRIB(NexuizCampaignList, rowsPerItem, float, 10)
5         METHOD(NexuizCampaignList, draw, void(entity))
6         METHOD(NexuizCampaignList, drawListBoxItem, void(entity, float, vector, float))
7         METHOD(NexuizCampaignList, clickListBoxItem, void(entity, float, vector))
8         METHOD(NexuizCampaignList, resizeNotify, void(entity, vector, vector, vector, vector))
9         METHOD(NexuizCampaignList, setSelected, void(entity, float))
10         METHOD(NexuizCampaignList, keyDown, float(entity, float, float, float))
11
12         ATTRIB(NexuizCampaignList, realFontSize, vector, '0 0 0')
13         ATTRIB(NexuizCampaignList, columnPreviewOrigin, float, 0)
14         ATTRIB(NexuizCampaignList, columnPreviewSize, float, 0)
15         ATTRIB(NexuizCampaignList, columnNameOrigin, float, 0)
16         ATTRIB(NexuizCampaignList, columnNameSize, float, 0)
17         ATTRIB(NexuizCampaignList, columnCheckMarkOrigin, float, 0)
18         ATTRIB(NexuizCampaignList, columnCheckMarkSize, float, 0)
19         ATTRIB(NexuizCampaignList, checkMarkOrigin, vector, '0 0 0')
20         ATTRIB(NexuizCampaignList, checkMarkSize, vector, '0 0 0')
21         ATTRIB(NexuizCampaignList, realUpperMargin1, float, 0)
22         ATTRIB(NexuizCampaignList, realUpperMargin2, float, 0)
23
24         ATTRIB(NexuizCampaignList, lastClickedMap, float, -1)
25         ATTRIB(NexuizCampaignList, lastClickedTime, float, 0)
26
27         ATTRIB(NexuizCampaignList, origin, vector, '0 0 0')
28         ATTRIB(NexuizCampaignList, itemAbsSize, vector, '0 0 0')
29         ATTRIB(NexuizCampaignList, emptyLineHeight, float, 0.5)
30
31         ATTRIB(NexuizCampaignList, campaignIndex, float, 0)
32         ATTRIB(NexuizCampaignList, cvarName, string, string_null)
33         METHOD(NexuizCampaignList, loadCvars, void(entity))
34         METHOD(NexuizCampaignList, saveCvars, void(entity))
35 ENDCLASS(NexuizCampaignList)
36 entity makeNexuizCampaignList();
37 void CampaignList_LoadMap(entity btn, entity me);
38 #endif
39
40 #ifdef IMPLEMENTATION
41 string campaign_longdesc_wrapped[CAMPAIGN_MAX_ENTRIES];
42
43 void rewrapCampaign(float w, float l0, float emptyheight)
44 {
45         float i, j;
46         float n, take, cantake, l;
47         string r, s;
48         for(i = 0; i < campaign_entries; ++i)
49         {
50                 l = l0;
51                 if(campaign_longdesc_wrapped[i])
52                         strunzone(campaign_longdesc_wrapped[i]);
53                 n = tokenizebyseparator(campaign_longdesc[i], "\n");
54                 r = "";
55                 for(j = 0; j < n; ++j)
56                 {
57                         s = argv(j);
58                         if(s == "")
59                         {
60                                 l -= emptyheight;
61                                 r = strcat(r, "\n");
62                                 continue;
63                         }
64                         for(;;)
65                         {
66                                 cantake = draw_TextLengthUpToWidth(s, w, 0);
67                                 if(cantake > 0 && cantake < strlen(s))
68                                 {
69                                         take = cantake - 1;
70                                         while(take > 0 && substring(s, take, 1) != " ")
71                                                 --take;
72                                         if(take == 0)
73                                         {
74                                                 if(--l < 0) goto toolong;
75                                                 r = strcat(r, substring(s, 0, cantake), "\n");
76                                                 s = substring(s, cantake, strlen(s) - cantake);
77                                         }
78                                         else
79                                         {
80                                                 if(--l < 0) goto toolong;
81                                                 r = strcat(r, substring(s, 0, take), "\n");
82                                                 s = substring(s, take + 1, strlen(s) - take);
83                                         }
84                                 }
85                                 else
86                                 {
87                                         if(--l < 0) goto toolong;
88                                         r = strcat(r, s, "\n");
89                                         break;
90                                 }
91                         }
92                 }
93                 goto nottoolong;
94 :toolong
95                 while(substring(r, strlen(r) - 1, 1) == "\n")
96                         r = substring(r, 0, strlen(r) - 1);
97                 r = strcat(r, "...\n");
98 :nottoolong
99                 campaign_longdesc_wrapped[i] = strzone(substring(r, 0, strlen(r) - 1));
100         }
101 }
102
103 entity makeNexuizCampaignList()
104 {
105         entity me;
106         me = spawnNexuizCampaignList();
107         me.configureNexuizCampaignList(me);
108         return me;
109 }
110 void configureNexuizCampaignListNexuizCampaignList(entity me)
111 {
112         me.configureNexuizListBox(me);
113         me.loadCvars(me);
114 }
115
116 void loadCvarsNexuizCampaignList(entity me)
117 {
118         // read campaign cvars
119         if(campaign_name)
120                 strunzone(campaign_name);
121         if(me.cvarName)
122                 strunzone(me.cvarName);
123         campaign_name = strzone(cvar_string("g_campaign_name"));
124         me.cvarName = strzone(strcat("g_campaign", campaign_name, "_index"));
125         CampaignFile_Load(0, CAMPAIGN_MAX_ENTRIES);
126         me.campaignIndex = bound(0, cvar(me.cvarName), campaign_entries);
127         cvar_set(me.cvarName, ftos(me.campaignIndex));
128         if(me.columnNameSize)
129                 rewrapCampaign(me.columnNameSize / me.realFontSize_x, me.rowsPerItem - 3, me.emptyLineHeight);
130         me.nItems = min(me.campaignIndex + 2, campaign_entries);
131         me.selectedItem = min(me.campaignIndex, me.nItems - 1);
132         me.scrollPos = me.nItems * me.itemHeight - 1;
133 }
134
135 void saveCvarsNexuizCampaignList(entity me)
136 {
137         // write campaign cvars
138         cvar_set("g_campaign_name", campaign_name);
139         // cvar_set(me.cvarName, ftos(me.campaignIndex)); // NOTE: only server QC does that!
140 }
141
142 void drawNexuizCampaignList(entity me)
143 {
144         if(cvar(me.cvarName) != me.campaignIndex || cvar_string("g_campaign_name") != campaign_name)
145                 me.loadCvars(me);
146         drawListBox(me);
147 }
148
149 void resizeNotifyNexuizCampaignList(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
150 {
151         me.origin = absOrigin;
152         me.itemAbsSize = '0 0 0';
153         resizeNotifyNexuizListBox(me, relOrigin, relSize, absOrigin, absSize);
154
155         me.realFontSize_y = me.fontSize / (me.itemAbsSize_y = (absSize_y * me.itemHeight));
156         me.realFontSize_x = me.fontSize / (me.itemAbsSize_x = (absSize_x * (1 - me.controlWidth)));
157         me.realUpperMargin1 = 0.5 * me.realFontSize_y;
158         me.realUpperMargin2 = me.realUpperMargin1 + 2 * me.realFontSize_y;
159
160         me.checkMarkSize = (eX * (me.itemAbsSize_y / me.itemAbsSize_x) + eY) * 0.5;
161
162         me.columnPreviewOrigin = 0;
163         me.columnPreviewSize = me.itemAbsSize_y / me.itemAbsSize_x * 4 / 3;
164         me.columnCheckMarkSize = me.checkMarkSize_x;
165         me.columnNameSize = 1 - me.columnPreviewSize - me.columnCheckMarkSize - 4 * me.realFontSize_x;
166         me.columnNameOrigin = me.columnPreviewOrigin + me.columnPreviewSize + me.realFontSize_x;
167         me.columnCheckMarkOrigin = me.columnNameOrigin + me.columnNameSize + me.realFontSize_x * 2;
168
169         me.checkMarkOrigin = eY + eX * (me.columnCheckMarkOrigin + me.columnCheckMarkSize) - me.checkMarkSize;
170
171         rewrapCampaign(me.columnNameSize / me.realFontSize_x, me.rowsPerItem - 3, me.emptyLineHeight);
172 }
173 void clickListBoxItemNexuizCampaignList(entity me, float i, vector where)
174 {
175         if(i == me.lastClickedMap)
176                 if(time < me.lastClickedTime + 0.3)
177                 {
178                         // DOUBLE CLICK!
179                         // start game
180                         CampaignList_LoadMap(me, me);
181                         return;
182                 }
183         me.lastClickedMap = i;
184         me.lastClickedTime = time;
185 }
186 void drawListBoxItemNexuizCampaignList(entity me, float i, vector absSize, float isSelected)
187 {
188         string s;
189         float p;
190         vector theColor;
191         float theAlpha;
192         float j, n;
193         vector o;
194
195         if(i < me.campaignIndex)
196         {
197                 theAlpha = SKINALPHA_CAMPAIGN_SELECTABLE;
198                 theColor = SKINCOLOR_CAMPAIGN_SELECTABLE;
199         }
200         else if(i == me.campaignIndex)
201         {
202                 theAlpha = SKINALPHA_CAMPAIGN_CURRENT;
203                 theColor = SKINCOLOR_CAMPAIGN_CURRENT;
204         }
205         else
206         {
207                 theAlpha = SKINALPHA_CAMPAIGN_FUTURE;
208                 theColor = SKINCOLOR_CAMPAIGN_FUTURE;
209         }
210
211         if(isSelected)
212                 draw_Fill('0 0 0', '1 1 0', SKINCOLOR_LISTBOX_SELECTED, SKINALPHA_LISTBOX_SELECTED);
213
214         s = ftos(p);
215         draw_Picture(me.columnPreviewOrigin * eX, strcat("/maps/", campaign_mapname[i]), me.columnPreviewSize * eX + eY, '1 1 1', theAlpha);
216         if(i < me.campaignIndex)
217                 draw_Picture(me.checkMarkOrigin, "checkmark", me.checkMarkSize, '1 1 1', 1);
218         if(i <= me.campaignIndex)
219                 s = campaign_shortdesc[i]; // fteqcc sucks
220         else
221                 s = "???";
222         s = draw_TextShortenToWidth(strcat("Level ", ftos(i + 1), ": ", s), me.columnNameSize / me.realFontSize_x, 0);
223         draw_Text(me.realUpperMargin1 * eY + (me.columnNameOrigin + 0.00 * (me.columnNameSize - draw_TextWidth(s, 0) * me.realFontSize_x)) * eX, s, me.realFontSize, theColor, theAlpha, 0);
224
225         if(i <= me.campaignIndex)
226         {
227                 s = campaign_longdesc_wrapped[i];
228                 n = tokenizebyseparator(s, "\n");
229                 o = me.realUpperMargin2 * eY + me.columnNameOrigin * eX;
230                 for(j = 0; j < n; ++j)
231                         if(argv(j) != "")
232                         {
233                                 draw_Text(o, argv(j), me.realFontSize, theColor, theAlpha * SKINALPHA_CAMPAIGN_DESCRIPTION, 0);
234                                 o_y += me.realFontSize_y;
235                         }
236                         else
237                                 o_y += me.realFontSize_y * me.emptyLineHeight;
238         }
239 }
240 void CampaignList_LoadMap(entity btn, entity me)
241 {
242         if(me.selectedItem >= me.nItems || me.selectedItem < 0)
243                 return;
244         CampaignSetup(me.selectedItem);
245 }
246
247 void setSelectedNexuizCampaignList(entity me, float i)
248 {
249         // prevent too late items from being played
250         setSelectedListBox(me, min(i, me.campaignIndex));
251 }
252
253 float keyDownNexuizCampaignList(entity me, float scan, float ascii, float shift)
254 {
255         if(scan == K_ENTER || scan == K_SPACE)
256                 CampaignList_LoadMap(me, me);
257         else
258                 return keyDownListBox(me, scan, ascii, shift);
259         return 1;
260 }
261 #endif