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