1 #include <stdlib.h>
2 #include "emotes.h"
3 #include "client_serv.h"
4 #include "asc.h"
5 #include "elwindows.h"
6 #include "gamewin.h"
7 #include "hud.h"
8 #include "init.h"
9 #include "interface.h"
10 #include "multiplayer.h"
11 #include "textures.h"
12 #include "translate.h"
13 #include "sound.h"
14 #include "io/elpathwrapper.h"
15 #include "errors.h"
16 #include "items.h"
17 #include "actors.h"
18 #include "colors.h"
19 #include "text.h"
20 
21 #ifdef OPENGL_TRACE
22 #include "gl_init.h"
23 #endif
24 
25 // TO ENABLE POSES, follow comments for EMOTES_CATEGORIES, emote_cats and emote_sel
26 
27 #define EMOTES_CATEGORIES 1 //Set EMOTE_CATEGORIES to 5 for poses
28 #define EMOTES_SHOWN 9
29 
30 #define EMOTE_SPAM_TIME 1000
31 
32 #define SET_COLOR(x) glColor4f((float) colors_list[x].r1 / 255.0f,(float) colors_list[x].g1 / 255.0f,(float) colors_list[x].b1 / 255.0f,1.0f)
33 
34 static char *emote_cats[EMOTES_CATEGORIES]= {
35 	"Actions"/*,
36 	"Sit poses",
37 	"Walk poses",
38 	"Run poses",
39 	"Stand poses"*/ //remove this comment and change EMOTE_CATEGORIES to 5 to enable poses
40 };
41 
42 static int emotes_rect_x = 0;
43 static int emotes_rect_y = 0;
44 static int emotes_rect_x2 = 0;
45 static int emotes_rect_y2 = 0;
46 
47 static int border_space = 0;
48 static int inbox_space = 0;
49 static int top_border = 0;
50 static int box_width = 0;
51 static int box_sep = 0;
52 static int category_y_step = 0;
53 static int category_extra_y_step = 0;
54 static int EMOTES_SCROLLBAR_ITEMS = 1001;
55 
56 static int cur_cat=0;
57 static emote_data* emote_sel[EMOTES_CATEGORIES]={NULL/*,NULL,NULL,NULL,NULL*/}; //remove the comment for poses
58 static emote_data *selectables[EMOTES_SHOWN];
59 
60 static unsigned char emote_str1[100];
61 static unsigned char emote_str2[100];
62 
63 
send_emote(int emote_id)64 void send_emote(int emote_id)
65 {
66 	static int last_emote_time=0;
67 	Uint8 str[4];
68 
69 	if(cur_time-last_emote_time>EMOTE_SPAM_TIME) {
70 		//Send message to server...
71 		str[0]=DO_EMOTE;
72 		str[1]=emote_id;
73 		my_tcp_send(my_socket,str,2);
74 		last_emote_time=cur_time;
75 		//printf("Emote %i sent at time %i\n",emote_id,last_emote_time);
76 	}
77 
78 }
79 
do_handler(void)80 static int do_handler(void)
81 {
82 	if(emote_sel[cur_cat]) send_emote(emote_sel[cur_cat]->id);
83 	return 0;
84 }
85 
update_selectables(void)86 static void update_selectables(void)
87 {
88 	int pos,i;
89 	hash_entry *he;
90 
91 	i=0;
92 	pos=vscrollbar_get_pos(get_id_MW(MW_EMOTE), EMOTES_SCROLLBAR_ITEMS);
93 	memset(selectables,0,sizeof(emote_data*)*EMOTES_SHOWN);
94 	hash_start_iterator(emotes);
95 	while((he=hash_get_next(emotes))&&i<EMOTES_SHOWN){
96 		emote_data *emote;
97 
98 		emote=((emote_data *)he->item);
99 		if(!cur_cat&&emote->pose>EMOTE_STANDING) {
100 			//emotes
101 			pos--;
102 			if(pos>=0) continue;
103 			selectables[i]=emote;
104 			i++;
105 		} else if(cur_cat&&emote->pose==(cur_cat-1)){
106 			//poses
107 			pos--;
108 			if(pos>=0) continue;
109 			selectables[i]=emote;
110 			i++;
111 		}
112 	}
113 
114 	emote_str1[1] = emote_str2[0] = 0;
115 	if(emote_sel[cur_cat]){
116 		put_small_colored_text_in_box_zoomed(c_orange2,
117 			(const unsigned char*)emote_sel[cur_cat]->desc,
118 			strlen(emote_sel[cur_cat]->desc), box_width, emote_str1, 1.0);
119 		hash_start_iterator(emote_cmds);
120 		while((he=hash_get_next(emote_cmds))){
121 			const emote_dict *emd = (const emote_dict*)he->item;
122 			if (emd->emote==emote_sel[cur_cat])
123 			{
124 				safe_snprintf((char*)emote_str2, sizeof(emote_str2), "%cTrigger: %c%s",
125 					127+c_grey1, 127+c_green3, emd->command);
126 				break; //just one command
127 			}
128 		}
129 	}
130 
131 }
132 
display_emotes_handler(window_info * win)133 static int display_emotes_handler(window_info *win)
134 {
135 
136 	int i,pos;
137 	actor *act = get_actor_ptr_from_id(yourself);
138 	static int last_pos=0;
139 
140 	//check if vbar has been moved
141 	pos=vscrollbar_get_pos(win->window_id, EMOTES_SCROLLBAR_ITEMS);
142 	if(pos!=last_pos){
143 		last_pos=pos;
144 		update_selectables();
145 	}
146 
147 	//draw texts
148 	glEnable(GL_TEXTURE_2D);
149 
150 	glColor3fv(gui_bright_color);
151 	draw_string_small_zoomed(border_space, top_border - win->small_font_len_y, (unsigned char*)"Categories",1, win->current_scale);
152 	draw_string_small_zoomed(border_space, top_border + emotes_rect_y + box_sep  - win->small_font_len_y, (unsigned char*)"Emotes",1, win->current_scale);
153 
154 	for(i=0;i<EMOTES_CATEGORIES;i++){
155 		if(cur_cat==i) SET_COLOR(c_blue2);
156 		else glColor3f(1.0f, 1.0f, 1.0f);
157 		draw_string_small_zoomed(border_space + inbox_space, top_border + inbox_space + category_y_step * i, (unsigned char*)emote_cats[i],1, win->current_scale);
158 	}
159 
160 	for(i=0;i<EMOTES_SHOWN;i++){
161 		if(emote_sel[cur_cat]==selectables[i]) SET_COLOR(c_blue2);
162 		else glColor3f(1.0f, 1.0f, 1.0f);
163 		if(cur_cat&&act&&selectables[i]==act->poses[cur_cat-1]) SET_COLOR(c_green1);
164 		if(selectables[i])
165 			draw_string_small_zoomed(border_space + inbox_space, top_border + emotes_rect_y + box_sep + inbox_space + category_y_step * i, (unsigned char*)selectables[i]->name,1, win->current_scale);
166 	}
167 	glColor3fv(gui_color);
168 	//do grids
169 	glDisable(GL_TEXTURE_2D);
170 
171 	rendergrid(1, 1, border_space, top_border, emotes_rect_x, emotes_rect_y);
172 	rendergrid(1, 1, border_space, top_border + emotes_rect_y + box_sep, emotes_rect_x2, emotes_rect_y2);
173 	glEnable(GL_TEXTURE_2D);
174 
175 
176 	//draw description
177 	if(emote_sel[cur_cat]){
178 		draw_string_small_zoomed(border_space, win->len_y - border_space - (3 * win->small_font_len_y), emote_str1,2, win->current_scale);
179 		draw_string_small_zoomed(border_space, win->len_y - border_space - (1 * win->small_font_len_y), emote_str2,1, win->current_scale);
180 	}
181 
182 #ifdef OPENGL_TRACE
183 CHECK_GL_ERRORS();
184 #endif //OPENGL_TRACE
185 	return 1;
186 }
187 
click_emotes_handler(window_info * win,int mx,int my,Uint32 flags)188 static int click_emotes_handler(window_info *win, int mx, int my, Uint32 flags)
189 {
190 	static int last_clicked=0;
191 	static int last_pos=-1;
192 	int box_left = border_space;
193 	int box_right = box_left + emotes_rect_x2;
194 	int box_top = top_border + emotes_rect_y + box_sep;
195 	int box_bot = box_top + emotes_rect_y2;
196 
197 	//scroll if wheel on selectables
198 	if(flags&ELW_WHEEL_UP) {
199 		if(mx > box_left && mx < box_right && my > box_top && my < box_bot)
200 			vscrollbar_scroll_up(win->window_id, EMOTES_SCROLLBAR_ITEMS);
201 		update_selectables();
202 		last_pos=-1;
203 		return 0;
204 	} else if(flags&ELW_WHEEL_DOWN) {
205 		if(mx > box_left && mx < box_right && my > box_top && my < box_bot)
206 			vscrollbar_scroll_down(win->window_id, EMOTES_SCROLLBAR_ITEMS);
207 		update_selectables();
208 		last_pos=-1;
209 		return 0;
210 	} else if ( (flags & ELW_MOUSE_BUTTON) == 0) {
211 		last_pos=-1;
212 		return 0;
213 	}
214 
215 
216 	if(mx > border_space && mx < border_space + emotes_rect_x && my > top_border && my < top_border + emotes_rect_y){
217 		//click on a cat
218 		cur_cat=(my - top_border + category_extra_y_step / 2) / category_y_step;
219 		if(cur_cat>=EMOTES_CATEGORIES) cur_cat=0;
220 		if(cur_cat>EMOTE_STANDING) cur_cat=EMOTE_STANDING+1;
221 		update_selectables();
222 		last_pos=-1;
223 	} else if(mx > box_left && mx < box_right && my > box_top && my < box_bot) {
224 		//click on selectables
225 		int w=(my - top_border - emotes_rect_y - box_sep + category_extra_y_step / 2) / category_y_step;
226 		emote_sel[cur_cat]=selectables[(w>=EMOTES_SHOWN)?(EMOTES_SHOWN-1):(w)];
227 		update_selectables();
228 		if ( ((SDL_GetTicks() - last_clicked) < 300)&&last_pos==w) do_handler();
229 		last_pos=w;
230 	}
231 
232 	last_clicked = SDL_GetTicks();
233 	return 0;
234 }
235 
ui_scale_emotes_handler(window_info * win)236 static int ui_scale_emotes_handler(window_info *win)
237 {
238 	float zoom = win->current_scale_small;
239 	int trigger_width = get_string_width_zoom((const unsigned char*)"Trigger: ",
240 		win->font_category, zoom);
241 	emote_dict *emd;
242 	hash_entry *he;
243 
244 	box_width = 0;
245 	hash_start_iterator(emote_cmds);
246 	while ((he = hash_get_next(emote_cmds)))
247 	{
248 		emd = (emote_dict*)he->item;
249 		if (emd->emote)
250 		{
251 			int width = get_string_width_zoom((const unsigned char*)emd->emote->name,
252 				win->font_category, zoom);
253 			box_width = max2i(box_width, width);
254 			width = (get_string_width_zoom((const unsigned char*)emd->emote->desc,
255 				win->font_category, zoom) * 6) / 10;
256 			box_width = max2i(box_width, width);
257 			width = trigger_width + get_string_width_zoom((const unsigned char*)emd->command,
258 				win->font_category, zoom);
259 			box_width = max2i(box_width, width);
260 		}
261 	}
262 
263 	inbox_space = (int)(0.5 + win->current_scale * 2);
264 	border_space = (int)(0.5 + win->current_scale * 5);
265 	top_border = border_space + win->small_font_len_y;
266 	box_sep = 2 * border_space + win->small_font_len_y;
267 	category_extra_y_step = 0;
268 	category_y_step = win->small_font_len_y + category_extra_y_step;
269 
270 	emotes_rect_x = 2 * inbox_space + box_width;
271 	emotes_rect_y = 2 * inbox_space + category_y_step * EMOTES_CATEGORIES - category_extra_y_step;
272 	emotes_rect_x2 = 2 * inbox_space + box_width;
273 	emotes_rect_y2 = 2 * inbox_space + category_y_step * EMOTES_SHOWN - category_extra_y_step;
274 
275 	resize_window(win->window_id, emotes_rect_x2 + win->box_size + 2 * border_space,
276 		top_border + emotes_rect_y + box_sep + emotes_rect_y2 + 3 * win->small_font_len_y + 2 * border_space);
277 
278 	widget_resize(win->window_id, EMOTES_SCROLLBAR_ITEMS, win->box_size, emotes_rect_y2);
279 	widget_move(win->window_id, EMOTES_SCROLLBAR_ITEMS, emotes_rect_x2 + border_space, emotes_rect_y + top_border + box_sep);
280 
281 	return 0;
282 }
283 
change_emotes_font_handler(window_info * win,font_cat cat)284 static int change_emotes_font_handler(window_info* win, font_cat cat)
285 {
286 	if (cat != UI_FONT)
287 		return 0;
288 	ui_scale_emotes_handler(win);
289 	return 1;
290 }
291 
display_emotes_menu(void)292 void display_emotes_menu(void)
293 {
294 	int emotes_win = get_id_MW(MW_EMOTE);
295 
296 	if(emotes_win < 0){
297 		int num_emotes;
298 		hash_entry *he;
299 		emotes_win = create_window("Emotes", (not_on_top_now(MW_EMOTE) ?game_root_win : -1), 0,
300 			get_pos_x_MW(MW_EMOTE), get_pos_y_MW(MW_EMOTE), 0, 0, ELW_USE_UISCALE|ELW_WIN_DEFAULT);
301 		set_id_MW(MW_EMOTE, emotes_win);
302 		set_window_custom_scale(emotes_win, MW_EMOTE);
303 		set_window_handler(emotes_win, ELW_HANDLER_DISPLAY, &display_emotes_handler );
304 		set_window_handler(emotes_win, ELW_HANDLER_CLICK, &click_emotes_handler );
305 		set_window_handler(emotes_win, ELW_HANDLER_UI_SCALE, &ui_scale_emotes_handler );
306 		set_window_handler(emotes_win, ELW_HANDLER_FONT_CHANGE, &change_emotes_font_handler);
307 
308 		num_emotes = 0;
309 		hash_start_iterator(emotes);
310 		while((he=hash_get_next(emotes)))
311 			num_emotes++;
312 
313 		EMOTES_SCROLLBAR_ITEMS = vscrollbar_add_extended(emotes_win, EMOTES_SCROLLBAR_ITEMS, NULL,
314 			0, 0, 0, 0, 0, 1.0, 0, 1, num_emotes-EMOTES_SHOWN);
315 
316 		if (emotes_win >=0 && emotes_win < windows_list.num_windows)
317 			ui_scale_emotes_handler(&windows_list.window[emotes_win]);
318 		check_proportional_move(MW_EMOTE);
319 
320 		update_selectables();
321 
322 	} else {
323 		show_window(emotes_win);
324 		select_window(emotes_win);
325 	}
326 }
327 
328 
329 
330