]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/menu/xonotic/playermodel.qc
Merge branch 'master' into terencehill/menu_optimization
[xonotic/xonotic-data.pk3dir.git] / qcsrc / menu / xonotic / playermodel.qc
1 #ifndef PLAYERMODEL_H
2 #define PLAYERMODEL_H
3 #include "image.qc"
4 CLASS(XonoticPlayerModelSelector, XonoticImage)
5         METHOD(XonoticPlayerModelSelector, configureXonoticPlayerModelSelector, void(entity));
6         METHOD(XonoticPlayerModelSelector, loadModels, void(entity));
7         METHOD(XonoticPlayerModelSelector, loadCvars, void(entity));
8         METHOD(XonoticPlayerModelSelector, saveCvars, void(entity));
9         METHOD(XonoticPlayerModelSelector, draw, void(entity));
10         METHOD(XonoticPlayerModelSelector, resizeNotify, void(entity, vector, vector, vector, vector));
11         METHOD(XonoticPlayerModelSelector, showNotify, void(entity));
12         ATTRIB(XonoticPlayerModelSelector, currentModel, string, string_null)
13         ATTRIB(XonoticPlayerModelSelector, currentSkin, float, 0)
14         ATTRIB(XonoticPlayerModelSelector, currentModelImage, string, string_null)
15         ATTRIB(XonoticPlayerModelSelector, currentModelTitle, string, string_null)
16         ATTRIB(XonoticPlayerModelSelector, currentModelDescription, string, string_null)
17         METHOD(XonoticPlayerModelSelector, go, void(entity, float));
18         METHOD(XonoticPlayerModelSelector, destroy, void(entity));
19         ATTRIB(XonoticPlayerModelSelector, origin, vector, '0 0 0')
20         ATTRIB(XonoticPlayerModelSelector, size, vector, '0 0 0')
21         ATTRIB(XonoticPlayerModelSelector, realFontSize, vector, '0 0 0')
22         ATTRIB(XonoticPlayerModelSelector, fontSize, float, SKINFONTSIZE_NORMAL)
23         ATTRIB(XonoticPlayerModelSelector, titleFontSize, float, SKINFONTSIZE_TITLE)
24         ATTRIB(XonoticPlayerModelSelector, bufModels, float, -1)
25         ATTRIB(XonoticPlayerModelSelector, numModels, float, -1)
26         ATTRIB(XonoticPlayerModelSelector, idxModels, float, -1)
27 ENDCLASS(XonoticPlayerModelSelector)
28 entity makeXonoticPlayerModelSelector();
29 void PlayerModelSelector_Next_Click(entity btn, entity me);
30 void PlayerModelSelector_Prev_Click(entity btn, entity me);
31 #endif
32
33 #ifdef IMPLEMENTATION
34 entity makeXonoticPlayerModelSelector()
35 {
36         entity me;
37         me = NEW(XonoticPlayerModelSelector);
38         me.configureXonoticPlayerModelSelector(me);
39         return me;
40 }
41
42 const float BUFMODELS_TITLE = 0;
43 const float BUFMODELS_IMAGE = 1;
44 const float BUFMODELS_MODEL = 2;
45 const float BUFMODELS_SKIN = 3;
46 const float BUFMODELS_DESC = 4;
47 const float BUFMODELS_COUNT = 5;
48
49 #define XONVOTE186 1 // (nyov) removal of model text description
50
51 void XonoticPlayerModelSelector_configureXonoticPlayerModelSelector(entity me)
52 {
53         me.configureXonoticImage(me, string_null, -1);
54 }
55
56 void XonoticPlayerModelSelector_loadModels(entity me)
57 {
58         int i;
59         string fn;
60
61         float glob = search_begin(language_filename(get_model_datafilename(string_null, -1, "txt")), true, true);
62         if (glob < 0)
63                 return;
64
65         float sortbuf = buf_create();
66         for(i = 0; i < search_getsize(glob); ++i)
67         {
68                 // select model #i!
69                 fn = search_getfilename(glob, i);
70                 if(!get_model_parameters(fn, -1))
71                         continue;
72                 bufstr_add(sortbuf, sprintf("%-128s%s", get_model_parameters_name, fn), 1);
73         }
74         search_end(glob);
75         buf_sort(sortbuf, 128, 0);
76         me.numModels = buf_getsize(sortbuf);
77         me.bufModels = buf_create();
78         for(i = 0; i < me.numModels; ++i)
79         {
80                 fn = substring(bufstr_get(sortbuf, i), 128, -1);
81                 if(!get_model_parameters(fn, -1))
82                         error("But it JUST worked!");
83                 bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_TITLE, get_model_parameters_name);
84                 bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_IMAGE, strcat("/", substring(get_model_datafilename(get_model_parameters_modelname, get_model_parameters_modelskin, "tga"), 0, -5)));
85                 bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_MODEL, get_model_parameters_modelname);
86                 bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_SKIN, ftos(get_model_parameters_modelskin));
87                 get_model_parameters_desc = strcat(get_model_parameters_desc, "\n");
88 #if XONVOTE186
89                 if(get_model_parameters_sex)
90                         get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\n%s", get_model_parameters_sex));
91 #else
92                 if(get_model_parameters_description)
93                         get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\n%s\n", get_model_parameters_description));
94                 if(get_model_parameters_sex)
95                         get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nSex: %s", get_model_parameters_sex));
96                 if(get_model_parameters_weight)
97                         get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nWeight: %g kg", get_model_parameters_weight));
98                 if(get_model_parameters_age)
99                         get_model_parameters_desc = strcat(get_model_parameters_desc, sprintf("\nAge: %g", get_model_parameters_age));
100 #endif
101                 while(substring(get_model_parameters_desc, -1, 1) == "\n")
102                         get_model_parameters_desc = substring(get_model_parameters_desc, 0, -2);
103                 bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_DESC, get_model_parameters_desc);
104         }
105         buf_del(sortbuf);
106         get_model_parameters(string_null, 0);
107         me.loadCvars(me); // this will select the initial model, depending on the current cvars
108         me.go(me, 0); // this will set the vars for the selected model
109 }
110
111 void XonoticPlayerModelSelector_destroy(entity me)
112 {
113         if(me.bufModels >= 0)
114         {
115                 buf_del(me.bufModels);
116                 me.bufModels = -1;
117         }
118 }
119
120 void XonoticPlayerModelSelector_loadCvars(entity me)
121 {
122         string skin, modelname;
123         float i;
124
125         skin = cvar_string("_cl_playerskin");
126         modelname = cvar_string("_cl_playermodel");
127
128         for(i = 0; i < me.numModels; ++i)
129         {
130                 if(bufstr_get(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_MODEL) == modelname)
131                 if(bufstr_get(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_SKIN) == skin)
132                         break;
133         }
134         if(i >= me.numModels) // fail
135                 i = 0;
136         me.idxModels = i;
137 }
138
139 void XonoticPlayerModelSelector_go(entity me, float d)
140 {
141         me.idxModels = mod(me.idxModels + d + me.numModels, me.numModels);
142
143         if(me.currentModel)
144                 strunzone(me.currentModel);
145         if(me.currentModelTitle)
146                 strunzone(me.currentModelTitle);
147         if(me.currentModelImage)
148                 strunzone(me.currentModelImage);
149         if(me.currentModelDescription)
150                 strunzone(me.currentModelDescription);
151
152         // select model #i!
153         me.currentModelTitle = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_TITLE));
154         me.currentModelImage = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_IMAGE));
155         me.currentSkin = stof(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_SKIN));
156         me.currentModel = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_MODEL));
157         me.currentModelDescription = strzone(bufstr_get(me.bufModels, BUFMODELS_COUNT*me.idxModels+BUFMODELS_DESC));
158
159         // fix the image
160         if(draw_PictureSize(me.currentModelImage) == '0 0 0')
161                 me.src = "nopreview_player";
162         else
163                 me.src = me.currentModelImage;
164         me.updateAspect(me);
165 }
166
167 void PlayerModelSelector_Next_Click(entity btn, entity me)
168 {
169         if (me.numModels <= 0)
170                 return;
171         me.go(me, +1);
172         me.saveCvars(me);
173 }
174
175 void PlayerModelSelector_Prev_Click(entity btn, entity me)
176 {
177         if (me.numModels <= 0)
178                 return;
179         me.go(me, -1);
180         me.saveCvars(me);
181 }
182
183 void XonoticPlayerModelSelector_saveCvars(entity me)
184 {
185         // we can't immediately apply here because of flood control
186         cvar_set("_cl_playermodel", me.currentModel);
187         cvar_set("_cl_playerskin", ftos(me.currentSkin));
188 }
189
190 void XonoticPlayerModelSelector_draw(entity me)
191 {
192         float i, n;
193         vector o;
194
195         if (me.numModels <= 0)
196         {
197                 draw_CenterText('0.5 0.5 0', _("<no model found>"), me.realFontSize, SKINCOLOR_TEXT, 0.6, false);
198                 return;
199         }
200
201         SUPER(XonoticPlayerModelSelector).draw(me);
202         // draw text on the image, handle \n in the description
203
204         draw_beginBoldFont();
205
206 #if XONVOTE186 // (nyov) lower name display looks better when there is no description text
207         draw_CenterText('0.5 0.8 0', me.currentModelTitle, me.realFontSize * (me.titleFontSize / me.fontSize), SKINCOLOR_MODELTITLE, SKINALPHA_MODELTITLE, false);
208 #else
209         draw_CenterText('0.5 0 0', me.currentModelTitle, me.realFontSize * (me.titleFontSize / me.fontSize), SKINCOLOR_MODELTITLE, SKINALPHA_MODELTITLE, false);
210 #endif
211
212         draw_endBoldFont();
213
214         o = '0.5 1 0' - eY * me.realFontSize.y * ((n = tokenizebyseparator(me.currentModelDescription, "\n")) + 0.5);
215         for(i = 0; i < n; ++i)
216         {
217                 draw_CenterText(o, argv(i), me.realFontSize, SKINCOLOR_TEXT, 1, false);
218                 o += eY * me.realFontSize.y;
219         }
220 }
221
222 void XonoticPlayerModelSelector_resizeNotify(entity me, vector relOrigin, vector relSize, vector absOrigin, vector absSize)
223 {
224         SUPER(XonoticPlayerModelSelector).resizeNotify(me, relOrigin, relSize, absOrigin, absSize);
225         me.realFontSize_y = me.fontSize / absSize.y;
226         me.realFontSize_x = me.fontSize / absSize.x;
227 }
228
229 void XonoticPlayerModelSelector_showNotify(entity me)
230 {
231         // Reinitialize self.
232         me.destroy(me);
233         me.loadModels(me);
234 }
235 #endif