1 #include <stdlib.h>
2 #include <string.h>
3 #include <math.h>
4 #include <SDL_keyboard.h>
5
6 #include "asc.h"
7 #include "buddy.h"
8 #include "consolewin.h"
9 #include "cursors.h"
10 #include "elconfig.h"
11 #include "emotes.h"
12 #include "gamewin.h"
13 #include "gl_init.h"
14 #include "hud.h"
15 #include "hud_indicators.h"
16 #include "hud_misc_window.h"
17 #include "hud_quickbar_window.h"
18 #include "hud_quickspells_window.h"
19 #include "hud_statsbar_window.h"
20 #include "icon_window.h"
21 #include "interface.h"
22 #include "manufacture.h"
23 #include "mapwin.h"
24 #include "minimap.h"
25 #include "missiles.h"
26 #include "new_character.h"
27 #include "questlog.h"
28 #include "spells.h"
29 #include "storage.h"
30 #include "tabs.h"
31 #include "textures.h"
32 #include "trade.h"
33 #include "user_menus.h"
34 #include "url.h"
35
36
37 int hud_x= 64;
38 int hud_y= 48;
39 int hud_text;
40 int show_help_text=1;
41 int always_enlarge_text=1;
42 Uint32 exp_lev[MAX_EXP_LEVEL];
43 int logo_click_to_url = 1;
44 char LOGO_URL_LINK[128] = "http://www.eternal-lands.com";
45
46 static hud_interface last_interface = HUD_INTERFACE_NEW_CHAR; //Current interface (game or new character)
47
48 /* called on client exit to free resources */
cleanup_hud(void)49 void cleanup_hud(void)
50 {
51 destroy_hud_indicators();
52 destroy_icon_window();
53 destroy_window(misc_win);
54 destroy_window(stats_bar_win);
55 destroy_window(get_id_MW(MW_QUICKBAR));
56 stats_bar_win = misc_win = -1;
57 set_id_MW(MW_QUICKBAR, -1);
58 }
59
60
61 /* #exp console command, display current exp information */
show_exp(char * text,int len)62 int show_exp(char *text, int len)
63 {
64 int thestat;
65 char buf[256];
66 for (thestat=0; thestat<NUM_WATCH_STAT-1; thestat++)
67 {
68 safe_snprintf(buf, sizeof(buf), "%s: level %u, %u/%u exp (%u to go)",
69 statsinfo[thestat].skillnames->name, statsinfo[thestat].skillattr->base,
70 *statsinfo[thestat].exp, *statsinfo[thestat].next_lev,
71 *statsinfo[thestat].next_lev - *statsinfo[thestat].exp );
72 LOG_TO_CONSOLE(c_green1, buf);
73 }
74 return 1;
75 }
76
77 // initialize anything related to the hud
init_hud_interface(hud_interface type)78 void init_hud_interface (hud_interface type)
79 {
80 if (type == HUD_INTERFACE_LAST)
81 type = last_interface;
82
83 if (type == HUD_INTERFACE_NEW_CHAR)
84 {
85 if (newchar_root_win >= 0 && newchar_root_win < windows_list.num_windows)
86 {
87 hud_x = (int)(0.5 + windows_list.window[newchar_root_win].current_scale * NEW_CHARACTER_BASE_HUD_X);
88 resize_root_window();
89 init_icon_window (NEW_CHARACTER_ICONS);
90 }
91 }
92 else
93 {
94 if (hud_x>0)
95 hud_x=HUD_MARGIN_X;
96 resize_root_window();
97 init_icon_window (MAIN_WINDOW_ICONS);
98 init_stats_display ();
99 init_misc_display ();
100 init_quickbar ();
101 init_quickspell ();
102 init_hud_indicators ();
103 ready_for_user_menus = 1;
104 if (enable_user_menus)
105 display_user_menus();
106 if ((get_id_MW(MW_MINIMAP) < 0) && open_minimap_on_start)
107 {
108 static int first_time = 1;
109 if (first_time)
110 view_window(MW_MINIMAP);
111 first_time = 0;
112 }
113 }
114
115 last_interface = type;
116 }
117
show_moveable_hud_windows(void)118 void show_moveable_hud_windows(void)
119 {
120 show_window_MW(MW_QUICKBAR);
121 show_window_MW(MW_QUICKSPELLS);
122 show_hud_indicators_window();
123 }
124
show_hud_windows(void)125 void show_hud_windows (void)
126 {
127 if (icons_win >= 0) show_window (icons_win);
128 if (stats_bar_win >= 0) show_window (stats_bar_win);
129 if (misc_win >= 0) show_window (misc_win);
130 show_moveable_hud_windows();
131 }
132
hide_hud_windows(void)133 void hide_hud_windows (void)
134 {
135 if (icons_win >= 0) hide_window (icons_win);
136 if (stats_bar_win >= 0) hide_window (stats_bar_win);
137 if (misc_win >= 0) hide_window (misc_win);
138 hide_window_MW(MW_QUICKBAR);
139 hide_window_MW(MW_QUICKSPELLS);
140 hide_hud_indicators_window();
141 }
142
hide_moved_hud_windows(void)143 void hide_moved_hud_windows(void)
144 {
145 size_t i;
146 int list_of_windows[2] = { get_id_MW(MW_QUICKBAR), get_id_MW(MW_QUICKSPELLS) };
147 for (i=0; i<2; i++)
148 {
149 if (get_show_window (list_of_windows[i])
150 && windows_list.window[list_of_windows[i]].cur_x < window_width - HUD_MARGIN_X
151 && window_height - windows_list.window[list_of_windows[i]].cur_y > HUD_MARGIN_Y)
152 hide_window (list_of_windows[i]);
153 }
154 }
155
test_over_active_logo(window_info * win,int mx,int my)156 static int test_over_active_logo(window_info *win, int mx, int my)
157 {
158 int dead_space = (int)(0.5 + win->current_scale * 10);
159 int hud_logo_size = get_hud_logo_size();
160 return logo_click_to_url && hud_x && (mx > (win->len_x - (hud_logo_size - dead_space))) && (my < (hud_logo_size - dead_space));
161 }
162
hud_mouse_over(window_info * win,int mx,int my)163 int hud_mouse_over(window_info *win, int mx, int my)
164 {
165 // exclude some dead space to try to prevent accidental misclicks
166 if (test_over_active_logo(win, mx, my))
167 {
168 elwin_mouse = CURSOR_USE;
169 return 1;
170 }
171 if (hud_x && hud_y && ((mx > win->len_x - hud_x) || (my > win->len_y - hud_y)))
172 {
173 elwin_mouse = CURSOR_ARROW;
174 return 1;
175 }
176 return 0;
177 }
178
hud_click(window_info * win,int mx,int my,Uint32 flags)179 int hud_click(window_info *win, int mx, int my, Uint32 flags)
180 {
181 if (test_over_active_logo(win, mx, my))
182 {
183 if (logo_click_to_url)
184 open_web_link(LOGO_URL_LINK);
185 return 1;
186 }
187 return 0;
188 }
189
get_hud_logo_size(void)190 int get_hud_logo_size(void)
191 {
192 return HUD_MARGIN_X;
193 }
194
draw_hud_interface(window_info * win)195 void draw_hud_interface(window_info *win)
196 {
197 const float vertical_bar_u_start = (float)192/256;
198 const float vertical_bar_u_end = 1.0f;
199 const float vertical_bar_v_start = 0.0f;
200 const float horizontal_bar_u_start = (float)144/256;
201 const float horizontal_bar_u_end = (float)191/256;
202 const float horizontal_bar_v_end = 0.0f;
203 const float logo_u_start = (float)64/256;
204 const float logo_v_start = (float)128/256;
205 const float logo_u_end = (float)127/256;
206 const float logo_v_end = (float)191/256;
207 float vertical_bar_v_end = (float)window_height/256;
208 float horizontal_bar_v_start = (float)(window_width-hud_x)/256;
209 int hud_logo_size = get_hud_logo_size();
210
211 #ifdef OPENGL_TRACE
212 CHECK_GL_ERRORS();
213 #endif //OPENGL_TRACE
214 glColor3f(1.0f, 1.0f, 1.0f);
215 bind_texture(hud_text);
216 glBegin(GL_QUADS);
217 draw_2d_thing_r(horizontal_bar_u_start, horizontal_bar_v_start, horizontal_bar_u_end, horizontal_bar_v_end,0,window_height,window_width, window_height-hud_y);
218 if(last_interface == HUD_INTERFACE_GAME)
219 {
220 draw_2d_thing(vertical_bar_u_start, vertical_bar_v_start, vertical_bar_u_end, vertical_bar_v_end,window_width-hud_x, 0, window_width, window_height);
221 //draw the logo
222 if (hud_x)
223 draw_2d_thing(logo_u_start, logo_v_start, logo_u_end, logo_v_end, window_width - hud_logo_size, 0, window_width, hud_logo_size);
224 }
225 glEnd();
226 #ifdef OPENGL_TRACE
227 CHECK_GL_ERRORS();
228 #endif //OPENGL_TRACE
229 }
230
view_console_win(void)231 static void view_console_win(void)
232 {
233 if ( get_show_window_MW(MW_CONSOLE) && !locked_to_console )
234 return_to_gamewin_common();
235 else
236 {
237 if ( get_show_window (game_root_win) )
238 hide_window (game_root_win);
239 if ( get_show_window_MW(MW_TABMAP) )
240 hide_window_MW(MW_TABMAP);
241 show_window_MW(MW_CONSOLE);
242 }
243 }
244
view_map_win(void)245 static void view_map_win(void)
246 {
247 if ( get_show_window_MW(MW_TABMAP) && !locked_to_console )
248 return_to_gamewin_common();
249 else if ( switch_to_game_map () && !locked_to_console )
250 {
251 if ( get_show_window (game_root_win) )
252 hide_window (game_root_win);
253 if ( get_show_window_MW(MW_CONSOLE) )
254 hide_window_MW(MW_CONSOLE);
255 show_window_MW(MW_TABMAP);
256 }
257 }
258
view_window(enum managed_window_enum managed_win)259 void view_window(enum managed_window_enum managed_win)
260 {
261 if (managed_win >= MW_MAX)
262 return;
263
264 if (managed_win == MW_TABMAP)
265 {
266 view_map_win();
267 return;
268 }
269
270 if (managed_win == MW_CONSOLE)
271 {
272 view_console_win();
273 return;
274 }
275
276 if(managed_win == MW_SPELLS || managed_win == MW_MANU)
277 {
278 if(get_show_window_MW(MW_TRADE))
279 {
280 LOG_TO_CONSOLE(c_red2,no_open_on_trade);
281 return;
282 }
283 }
284
285 // If not created, call the display function, otherwise toggle the window.
286 if(get_id_MW(managed_win) < 0)
287 call_display_MW(managed_win);
288 else
289 toggle_window_MW(managed_win);
290 }
291
view_tab(enum managed_window_enum managed_win,int col_id,int tab)292 void view_tab (enum managed_window_enum managed_win, int col_id, int tab)
293 {
294 if (get_show_window_MW(managed_win))
295 {
296 if (tab_collection_get_tab(get_id_MW(managed_win), col_id) == tab)
297 {
298 hide_window_MW(managed_win);
299 }
300 else
301 {
302 tab_collection_select_tab(get_id_MW(managed_win), col_id, tab);
303 }
304 }
305 else
306 {
307 view_window(managed_win);
308 tab_collection_select_tab(get_id_MW(managed_win), col_id, tab);
309 }
310 }
311
enlarge_text(void)312 int enlarge_text(void)
313 {
314 if (always_enlarge_text)
315 return 1;
316 return ((SDL_GetModState() & (KMOD_CTRL|KMOD_ALT)));
317 }
318
build_levels_table()319 void build_levels_table()
320 {
321 int i;
322 Uint64 exp=100;
323
324 exp_lev[0]=0;
325 for(i=1;i<MAX_EXP_LEVEL;i++)
326 {
327 if(i<=10)exp+=exp*40/100;
328 else
329 if(i<=20)exp+=exp*30/100;
330 else
331 if(i<=30)exp+=exp*20/100;
332 else
333 if(i<=40)exp+=exp*14/100;
334 else
335 if(i<=90)exp+=exp*7/100;
336 else exp+=exp*5/100;
337 exp_lev[i]=(Uint32)exp;
338 }
339 }
340
341