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