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