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