vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --[[ |
2 | |||
3 | TargetOfTarget: Keeps Target of Target shown below TargetFrame |
||
4 | |||
5 | Copyright (c) 2005 Itchyban of Veeshan |
||
6 | |||
7 | Version 2.1 Beta 1 |
||
8 | |||
9 | $Header: /usr/local/cvsroot/WoW/Interface/AddOns/TargetOfTarget/TargetOfTarget.lua,v 1.122 2005/05/30 17:43:33 jeff Exp $ |
||
10 | |||
11 | |||
12 | ]] |
||
13 | |||
14 | |||
15 | --- |
||
16 | --- Where should the dead/ghost/corpse be done? |
||
17 | --- |
||
18 | |||
19 | ------------------------- |
||
20 | --- Versioning params --- |
||
21 | ------------------------- |
||
22 | |||
23 | --- |
||
24 | --- WARNING |
||
25 | --- |
||
26 | --- Checking this into CVS or RCS without -ko can screw this up for now |
||
27 | --- |
||
28 | --- (If you don't know what CVS or RCS are, you can ignore that) |
||
29 | --- |
||
30 | |||
31 | local version_table_data = {}; |
||
32 | |||
33 | version_table_data.object = "1.0"; |
||
34 | version_table_data.apps = {}; |
||
35 | version_table_data.apps.TargetOfTarget = {}; |
||
36 | version_table_data.apps.TargetOfTarget.params = "2.0"; |
||
37 | version_table_data.apps.TargetOfTarget.lua_CVS = "$Revision: 1.122 $"; |
||
38 | version_table_data.apps.TargetOfTarget.XML_CVS = ""; |
||
39 | |||
40 | |||
41 | |||
42 | ------------------------------------------------------- |
||
43 | --- Check for existing globals before declaring any --- |
||
44 | ------------------------------------------------------- |
||
45 | |||
46 | local globals_to_check = { |
||
47 | "HoTT_Aggro_Callback", |
||
48 | "HoTT_Debug", |
||
49 | "HoTT_Display", |
||
50 | "HoTT_Display_Bar", |
||
51 | "HoTT_Display_Bar_OnEvent", |
||
52 | "HoTT_Display_Bar_OnUpdate", |
||
53 | "HoTT_Display_Bar_OnValueChanged", |
||
54 | "HoTT_Display_NameArea", |
||
55 | "HoTT_Display_NameArea_Text", |
||
56 | "HoTT_Display_OnClick", |
||
57 | "HoTT_Display_OnEvent", |
||
58 | "HoTT_Display_OnUpdate", |
||
59 | "HoTT_InputBoxTemplate", |
||
60 | "HoTT_InputBoxTemplateLeft", |
||
61 | "HoTT_InputBoxTemplateMiddle", |
||
62 | "HoTT_InputBoxTemplateRight", |
||
63 | "HoTT_MainFrame", |
||
64 | "HoTT_MainFrame_OnEvent", |
||
65 | "HoTT_MainFrame_OnLoad", |
||
66 | "HoTT_Params", |
||
67 | "HoTT_Params_FourDigitInputBox", |
||
68 | "HoTT_Params_Frame", |
||
69 | "HoTT_Params_Frame_AggroMessage_Changed", |
||
70 | "HoTT_Params_Frame_AggroMessage_EditBox", |
||
71 | "HoTT_Params_Frame_AggroText", |
||
72 | "HoTT_Params_Frame_AlertsText", |
||
73 | "HoTT_Params_Frame_Alignment_Changed", |
||
74 | "HoTT_Params_Frame_BuffsText", |
||
75 | "HoTT_Params_Frame_BuffsText0", |
||
76 | "HoTT_Params_Frame_BuffsText1", |
||
77 | "HoTT_Params_Frame_BuffsText2", |
||
78 | "HoTT_Params_Frame_ButtonCenter", |
||
79 | "HoTT_Params_Frame_ButtonCenterText", |
||
80 | "HoTT_Params_Frame_ButtonLeft", |
||
81 | "HoTT_Params_Frame_ButtonLeftText", |
||
82 | "HoTT_Params_Frame_ButtonRight", |
||
83 | "HoTT_Params_Frame_ButtonRightText", |
||
84 | "HoTT_Params_Frame_Cancel", |
||
85 | "HoTT_Params_Frame_CheckRefocus", |
||
86 | "HoTT_Params_Frame_ClearFocus", |
||
87 | "HoTT_Params_Frame_Defaults", |
||
88 | "HoTT_Params_Frame_DisplayInsetsText", |
||
89 | "HoTT_Params_Frame_DisplayLeft_Changed", |
||
90 | "HoTT_Params_Frame_DisplayLeft_EditBox", |
||
91 | "HoTT_Params_Frame_DisplayLeft_EditBoxLeft", |
||
92 | "HoTT_Params_Frame_DisplayLeft_EditBoxMiddle", |
||
93 | "HoTT_Params_Frame_DisplayLeft_EditBoxRight", |
||
94 | "HoTT_Params_Frame_DisplayRight_Changed", |
||
95 | "HoTT_Params_Frame_DisplayRight_EditBox", |
||
96 | "HoTT_Params_Frame_DisplayRight_EditBoxLeft", |
||
97 | "HoTT_Params_Frame_DisplayRight_EditBoxMiddle", |
||
98 | "HoTT_Params_Frame_DisplayRight_EditBoxRight", |
||
99 | "HoTT_Params_Frame_Drop0_Changed", |
||
100 | "HoTT_Params_Frame_Drop0_EditBox", |
||
101 | "HoTT_Params_Frame_Drop0_EditBoxLeft", |
||
102 | "HoTT_Params_Frame_Drop0_EditBoxMiddle", |
||
103 | "HoTT_Params_Frame_Drop0_EditBoxRight", |
||
104 | "HoTT_Params_Frame_Drop1_Changed", |
||
105 | "HoTT_Params_Frame_Drop1_EditBox", |
||
106 | "HoTT_Params_Frame_Drop1_EditBoxLeft", |
||
107 | "HoTT_Params_Frame_Drop1_EditBoxMiddle", |
||
108 | "HoTT_Params_Frame_Drop1_EditBoxRight", |
||
109 | "HoTT_Params_Frame_Drop2_Changed", |
||
110 | "HoTT_Params_Frame_Drop2_EditBox", |
||
111 | "HoTT_Params_Frame_Drop2_EditBoxLeft", |
||
112 | "HoTT_Params_Frame_Drop2_EditBoxMiddle", |
||
113 | "HoTT_Params_Frame_Drop2_EditBoxRight", |
||
114 | "HoTT_Params_Frame_DropsText", |
||
115 | "HoTT_Params_Frame_LoadValues", |
||
116 | "HoTT_Params_Frame_ObjectName_Changed", |
||
117 | "HoTT_Params_Frame_ObjectName_EditBox", |
||
118 | "HoTT_Params_Frame_ObjectName_EditBoxLeft", |
||
119 | "HoTT_Params_Frame_ObjectName_EditBoxMiddle", |
||
120 | "HoTT_Params_Frame_ObjectName_EditBoxRight", |
||
121 | "HoTT_Params_Frame_ObjectText", |
||
122 | "HoTT_Params_Frame_Okay", |
||
123 | "HoTT_Params_Frame_OnCancel", |
||
124 | "HoTT_Params_Frame_OnDefaults", |
||
125 | "HoTT_Params_Frame_OnOkay", |
||
126 | "HoTT_Params_Frame_PositioningText", |
||
127 | "HoTT_Params_Frame_Scale_Changed", |
||
128 | "HoTT_Params_Frame_Scale_EditBox", |
||
129 | "HoTT_Params_Frame_Scale_EditBoxLeft", |
||
130 | "HoTT_Params_Frame_Scale_EditBoxMiddle", |
||
131 | "HoTT_Params_Frame_Scale_EditBoxRight", |
||
132 | "HoTT_Params_Frame_ShowAlignmentFrame", |
||
133 | "HoTT_Params_Frame_Title", |
||
134 | "HoTT_Params_Frame_Title_Text", |
||
135 | "HoTT_Params_Frame_TextInsetsText", |
||
136 | "HoTT_Params_Frame_TextLeft_Changed", |
||
137 | "HoTT_Params_Frame_TextLeft_EditBox", |
||
138 | "HoTT_Params_Frame_TextLeft_EditBoxLeft", |
||
139 | "HoTT_Params_Frame_TextLeft_EditBoxMiddle", |
||
140 | "HoTT_Params_Frame_TextLeft_EditBoxRight", |
||
141 | "HoTT_Params_Frame_TextRight_Changed", |
||
142 | "HoTT_Params_Frame_TextRight_EditBox", |
||
143 | "HoTT_Params_Frame_TextRight_EditBoxLeft", |
||
144 | "HoTT_Params_Frame_TextRight_EditBoxMiddle", |
||
145 | "HoTT_Params_Frame_TextRight_EditBoxRight", |
||
146 | "HoTT_Set_XML_CVS", |
||
147 | "HoTT_Settings", |
||
148 | "HoTT_Settings_Unparsed", |
||
149 | "SLASH_TARGETOFTARGET_TOT1", |
||
150 | "SLASH_TARGETOFTARGET_TOT2", |
||
151 | "SLASH_TARGETOFTARGET_TOTOFF1", |
||
152 | "SLASH_TARGETOFTARGET_TOTON1", |
||
153 | "SlashCmdList[\"TARGETOFTARGET_TOT\"]", |
||
154 | "SlashCmdList[\"TARGETOFTARGET_TOTON\"]", |
||
155 | "SlashCmdList[\"TARGETOFTARGET_TOTOFF\"]", |
||
156 | } |
||
157 | |||
158 | local slash_commands_to_check = { |
||
159 | "/tot", |
||
160 | "/toton", |
||
161 | "/totoff", |
||
162 | "/hott" |
||
163 | } |
||
164 | |||
165 | local all_checked_globals = {}; |
||
166 | |||
167 | local k,v |
||
168 | |||
169 | for k,v in pairs (globals_to_check) do |
||
170 | table.insert(all_checked_globals, v); |
||
171 | end |
||
172 | |||
173 | for k,v in pairs (slash_commands_to_check) do |
||
174 | table.insert(all_checked_globals, v); |
||
175 | end |
||
176 | |||
177 | |||
178 | |||
179 | |||
180 | |||
181 | local global_check_failures = nil; |
||
182 | |||
183 | for k,v in pairs(globals_to_check) do |
||
184 | |||
185 | if ( type(getglobal(v)) ~= "nil" ) then |
||
186 | if ( type(global_check_failures) == "nil" ) then |
||
187 | global_check_failures = {}; |
||
188 | end |
||
189 | table.insert(global_check_failures, v); |
||
190 | end |
||
191 | |||
192 | end |
||
193 | |||
194 | |||
195 | |||
196 | --- |
||
197 | --- NOTE: This is not quite right yet, as slash_commands_to_check |
||
198 | --- somehow needs to be localized in the process |
||
199 | --- |
||
200 | |||
201 | |||
202 | --- |
||
203 | --- check_localized_slash_commands |
||
204 | --- |
||
205 | |||
206 | |||
207 | local function check_localized_slash_commands () |
||
208 | |||
209 | for k,v in pairs(slash_commands_to_check) do |
||
210 | |||
211 | local scl_key, scl_value; |
||
212 | |||
213 | for scl_key, scl_value in pairs(SlashCmdList) do |
||
214 | |||
215 | |||
216 | local idx = 1; |
||
217 | local slash_var = "SLASH_"..scl_key..idx; |
||
218 | local slash_cmd_string = getglobal(slash_var); |
||
219 | |||
220 | repeat |
||
221 | if ( slash_cmd_string == v ) then |
||
222 | if ( type(global_check_failures) == "nil" ) then |
||
223 | global_check_failures = {}; |
||
224 | end |
||
225 | table.insert(global_check_failures, |
||
226 | v .. "( == " .. slash_cmd_string .. " )"); |
||
227 | end |
||
228 | idx = idx+1; |
||
229 | slash_var = "SLASH_"..scl_key..idx; |
||
230 | slash_cmd_string = getglobal(slash_var); |
||
231 | |||
232 | until ( not slash_cmd_string ) |
||
233 | |||
234 | end |
||
235 | |||
236 | end |
||
237 | |||
238 | end |
||
239 | |||
240 | |||
241 | --- |
||
242 | --- "Safe" to declare globals now |
||
243 | --- at least we know what we are going to clobber! |
||
244 | --- |
||
245 | |||
246 | |||
247 | |||
248 | |||
249 | --- |
||
250 | --- Stray Global, here for clarity |
||
251 | --- |
||
252 | --- HoTT_Set_XML_CVS |
||
253 | --- |
||
254 | |||
255 | --- Called <OnLoad> in the XML file |
||
256 | --- Should probably make sure that it "flows through" properly |
||
257 | --- before I start relying on it for anything |
||
258 | |||
259 | function HoTT_Set_XML_CVS (version_string) |
||
260 | version_table_data.apps.TargetOfTarget.XML_CVS = version_string; |
||
261 | |||
262 | return version_table_data.apps.TargetOfTarget.XML_CVS; |
||
263 | end |
||
264 | |||
265 | |||
266 | --- |
||
267 | --- HoTT_Patch_Warning |
||
268 | --- |
||
269 | |||
270 | local function HoTT_Patch_Warning () |
||
271 | |||
272 | local patch_not_ok = (type(UnitIsVisible) ~= "function"); |
||
273 | |||
274 | if ( patch_not_ok ) then |
||
275 | message("This version requires patch 1.5.0, not present on this server. Enjoy this version on Test, but run the latest 1.x version here for now."); |
||
276 | end |
||
277 | |||
278 | return patch_not_ok; |
||
279 | end |
||
280 | |||
281 | |||
282 | --------------------------- |
||
283 | --- Localizable Strings --- |
||
284 | --------------------------- |
||
285 | |||
286 | local no_target_string = ""; |
||
287 | local stunned_string = "(stunned)"; |
||
288 | local undetermined_string = "(undetermined)"; |
||
289 | |||
290 | local aggro_message = "--- AGGRO --- AGGRO ---"; |
||
291 | |||
292 | local ras_format = "Duplicate UnitID for %s; %s, %s"; |
||
293 | |||
294 | local toton_string = "/toton"; |
||
295 | local totoff_string = "/totoff"; |
||
296 | |||
297 | local loaded_string = "Itchy's TargetOfTarget AddOn loaded"; |
||
298 | local loaded_variables_string = "TargetOfTarget SavedVariables settings restored" |
||
299 | |||
300 | local shift_at_load_string = "TargetOfTarget [Shift] at load"; |
||
301 | local invalid_settings_string = "TargetOfTarget invalid saved settings. Copied to HoTT_Settings_Unparsed"; |
||
302 | |||
303 | local on_string = "TargetOfTarget is now " .. GREEN_FONT_COLOR_CODE .. "ON"; |
||
304 | local off_string = "TargetOfTarget is now OFF"; |
||
305 | |||
306 | local saved_format = "TargetOfTarget saved settings: %s"; |
||
307 | local save_failed_format = "TargetOfTarget no settings to save for: %s"; |
||
308 | |||
309 | local restored_defaults = "TargetOfTarget restored default settings"; |
||
310 | local restored_format = "TargetOfTarget restored settings: %s"; |
||
311 | local restore_failed_format = "TargetOfTarget no settings to restore for: %s"; |
||
312 | |||
313 | local help_message = [[ |
||
314 | Itchy's ToT |
||
315 | |||
316 | /tot on -- enable ToT (or /toton) |
||
317 | /tot off -- disable ToT (or /totoff) |
||
318 | |||
319 | /tot params -- brings up dialog to edit aggro message and position display. |
||
320 | /tot version -- displays file versions. Please report these with any bugs or suggestions.]]; |
||
321 | |||
322 | local help_ui = "/tot ui is obsolete. Use /tot params"; |
||
323 | |||
324 | local string_global_check_failed = "TargetOfTarget found possible " .. |
||
325 | RED_FONT_COLOR_CODE .. "global variable conflict" .. |
||
326 | FONT_COLOR_CODE_CLOSE .. " on loading. For details, /tot globals"; |
||
327 | |||
328 | local string_global_list = "TargetOfTarget global variable check list is in TargetOfTarget.lua, if you are curious." |
||
329 | |||
330 | local string_global_check_explanation = "TargetOfTarget checks that the global variables it uses are not already in use when it loads. If they are already present, it is likely that another AddOn will conflict with TargetOfTarget, or you have two versions loading. The following variables were found in conflict:"; |
||
331 | local string_global_variable_check_trailer = "If there are a lot of variables listed, it is likely that you have another copy of TargetOfTarget loading. Please check your AddOns." |
||
332 | |||
333 | local string_assert_set_exists_fmt = "Change settings to %s, no set returned"; |
||
334 | local string_assert_no_player = "Player name unexpectedly missing"; |
||
335 | local string_assert_no_realm = "Realm name unexpectedly missing"; |
||
336 | |||
337 | local fmt_no_such_object = "%s does not exist in this UI. Use '/tot ui default' to restore defaults, or '/tot ui' to see other options"; |
||
338 | |||
339 | local string_no_ui_description = "(no description given)" |
||
340 | |||
341 | local string_cleared_ui = "Cleared ToT UI parameters"; |
||
342 | local string_default_ui_copied = "Copied default ToT UI parameters to your active set"; |
||
343 | |||
344 | local fmt_copied_ui = "Copied ToT UI parameters to your active set: %s -- %s"; |
||
345 | |||
346 | local fmt_no_such_ui = "No such ToT UI parameters, %s, available. For help, /tot ui"; |
||
347 | |||
348 | local string_help_cmd = "help"; |
||
349 | local string_on_cmd = "on"; |
||
350 | local string_off_cmd = "off"; |
||
351 | local string_ui_cmd = "ui"; |
||
352 | local string_version_cmd = "version"; |
||
353 | local string_globals_cmd = "globals"; |
||
354 | local string_params_cmd = "params" |
||
355 | |||
356 | local string_unrecognized_cmd_help = "Unrecognized command -- try /tot help"; |
||
357 | |||
358 | local string_slash_tot = "/tot" |
||
359 | local string_slash_hott = "/hott" |
||
360 | |||
361 | local ellipsis = "..."; -- Used as suffix in shortened names |
||
362 | |||
363 | local fmt_ro_access = "No write access to %s permitted."; |
||
364 | local fmt_not_a_table = "%s not a table, passed as %s"; |
||
365 | |||
366 | local fmt_too_narrow = "Too narrow a window. %s set to previous value."; |
||
367 | local fmt_no_obj_edit = "%s does not exist in this UI. Previous value restored."; |
||
368 | |||
369 | |||
370 | |||
371 | ----------------------------------------- |
||
372 | --- Parameter list and default values --- |
||
373 | ----------------------------------------- |
||
374 | |||
375 | |||
376 | --- Application defaults |
||
377 | --- |
||
378 | --- DO NOT CHANGE THESE HERE |
||
379 | --- |
||
380 | --- Use HoTT_Params handle to keep overrides in SavedVariables |
||
381 | --- |
||
382 | |||
383 | local default_params = {}; |
||
384 | |||
385 | default_params.bar_unreliable_time = 0.500; -- time after which bar |
||
386 | -- is marked "unreliable" |
||
387 | |||
388 | default_params.poll_timer_period = 0.400; -- check ToT/health this often |
||
389 | -- (Only if not getting events) |
||
390 | |||
391 | default_params.aggro_message = aggro_message; -- or false or blank to disable |
||
392 | |||
393 | default_params.ui = {}; |
||
394 | |||
395 | default_params.ui.display = {}; |
||
396 | |||
397 | default_params.ui.display.relative_to = "TargetFrameHealthBar"; |
||
398 | |||
399 | default_params.ui.display.scale = 1.0; |
||
400 | |||
401 | default_params.ui.display.inset = {}; |
||
402 | |||
403 | default_params.ui.display.inset.left = -5; |
||
404 | default_params.ui.display.inset.right = -3; |
||
405 | |||
406 | |||
407 | default_params.ui.display.drops = {}; |
||
408 | |||
409 | default_params.ui.display.drops[0] = 12; |
||
410 | default_params.ui.display.drops[1] = 36; |
||
411 | default_params.ui.display.drops[2] = 58; |
||
412 | |||
413 | default_params.ui.display.tot_name = {}; |
||
414 | |||
415 | default_params.ui.display.tot_name.min_width = 20; -- prevent dynamic |
||
416 | -- adjustment too small |
||
417 | |||
418 | default_params.ui.display.tot_name.alignment = "CENTER"; |
||
419 | |||
420 | default_params.ui.display.tot_name.inset = {}; |
||
421 | |||
422 | default_params.ui.display.tot_name.inset.left = 6; -- padding for trimming |
||
423 | default_params.ui.display.tot_name.inset.right = 6; -- of strings to fit |
||
424 | |||
425 | |||
426 | |||
427 | -------------------------------- |
||
428 | --- Locking tables read-only --- |
||
429 | -------------------------------- |
||
430 | |||
431 | --- |
||
432 | --- format_table_key |
||
433 | --- |
||
434 | |||
435 | local function format_table_key (table_string, k) |
||
436 | |||
437 | local table_key; |
||
438 | |||
439 | if ( type(k) == "string" ) then |
||
440 | table_key = string.format("%s.%s", table_string, k); |
||
441 | else |
||
442 | table_key = string.format("%s[%s]", table_string, tostring(k)); |
||
443 | end |
||
444 | |||
445 | return table_key; |
||
446 | end |
||
447 | |||
448 | |||
449 | |||
450 | |||
451 | --- |
||
452 | --- wrap_readonly |
||
453 | --- |
||
454 | |||
455 | local function wrap_readonly (table1, table_name) |
||
456 | |||
457 | if ( type(table_name) ~= "string" ) then |
||
458 | table_name = ""; |
||
459 | end |
||
460 | |||
461 | local wrapper = {}; |
||
462 | local ro_mt = {}; |
||
463 | ro_mt.__index = table1; |
||
464 | ro_mt.__newindex = function (t,k,v) |
||
465 | error(string.format(fmt_ro_access, |
||
466 | format_table_key(table_name, k)), |
||
467 | 2); |
||
468 | end; |
||
469 | |||
470 | setmetatable(wrapper, ro_mt); |
||
471 | |||
472 | return wrapper; |
||
473 | end |
||
474 | |||
475 | |||
476 | |||
477 | --- |
||
478 | --- wrap_readonly_recursively |
||
479 | --- |
||
480 | |||
481 | local function wrap_readonly_recursively (table1, table_name, visited) |
||
482 | |||
483 | local k,v; |
||
484 | local next_table_name; |
||
485 | local wrapper; |
||
486 | |||
487 | if ( type(table_name) ~= "string" ) then |
||
488 | table_name = ""; |
||
489 | end |
||
490 | |||
491 | if ( not visited ) then |
||
492 | visited = {}; |
||
493 | visited[table1] = true; |
||
494 | end |
||
495 | |||
496 | for k,v in pairs(table1) do |
||
497 | if ( ( type(v) == "table" ) and |
||
498 | ( not visited[v] ) ) then |
||
499 | next_table_name = format_table_key(table_name, k); |
||
500 | table1[k] = wrap_readonly_recursively (v, next_table_name, visited) |
||
501 | end |
||
502 | end |
||
503 | |||
504 | wrapper = wrap_readonly(table1, table_name); |
||
505 | |||
506 | return wrapper; |
||
507 | end |
||
508 | |||
509 | |||
510 | |||
511 | --- |
||
512 | --- Lock default_params |
||
513 | --- |
||
514 | |||
515 | default_params = wrap_readonly_recursively(default_params, "default_params"); |
||
516 | |||
517 | |||
518 | |||
519 | |||
520 | |||
521 | ----------------------------- |
||
522 | --- Local state variables --- |
||
523 | ----------------------------- |
||
524 | |||
525 | local hott_is_on; -- master |
||
526 | |||
527 | local t_target_info = {}; -- the "target" for which ToT applies |
||
528 | local tot_target_info = {}; -- the ToT itself |
||
529 | |||
530 | local player_name; |
||
531 | local realm_name; |
||
532 | |||
533 | local last_tot; -- name of the last ToT for "AGGRO" messaging |
||
534 | local this_tot; |
||
535 | |||
536 | local roster = {}; -- reverse lookup for UnitIDs |
||
537 | local roster_assertion_seen; -- so as to only show an error once |
||
538 | |||
539 | local time_since_bar_update = 0; -- internal for bar coloring |
||
540 | local bar_set_unreliable = nil; -- internal for bar coloring |
||
541 | |||
542 | local variables_loaded = false; -- Event has fired |
||
543 | local saved_variables_loaded = false; -- Event responded to completely |
||
544 | |||
545 | local this_frame_tot; -- internals for detecting most target changes |
||
546 | local last_frame_tot; |
||
547 | |||
548 | local poll_timer = 0; -- handles the cases events don't cover |
||
549 | local poll_timer_fired = false; |
||
550 | |||
551 | local placed_names = {}; -- cache for name strings that fit |
||
552 | |||
553 | local refocus_object = nil; -- Params frame object that needs focus |
||
554 | |||
555 | |||
556 | |||
557 | |||
558 | |||
559 | ------------------------ |
||
560 | --- Local parameters --- |
||
561 | ------------------------ |
||
562 | |||
563 | |||
564 | |||
565 | --- UnitIDs that generate UNIT_HEALTH events (health bar reliability check) |
||
566 | |||
567 | local units_getting_events = {}; |
||
568 | |||
569 | units_getting_events.player = true; |
||
570 | units_getting_events.pet = true; |
||
571 | |||
572 | for idx = 1, 4 do |
||
573 | units_getting_events[format("party%i",idx)] = true; |
||
574 | units_getting_events[format("partypet%i",idx)] = true; |
||
575 | end |
||
576 | |||
577 | for idx = 1, 40 do |
||
578 | units_getting_events[format("raid%i",idx)] = true; |
||
579 | units_getting_events[format("raidpet%i",idx)] = true; |
||
580 | end |
||
581 | |||
582 | |||
583 | |||
584 | --- Colors for bars and for text |
||
585 | |||
586 | local colors = {}; |
||
587 | |||
588 | colors.bar = {}; |
||
589 | |||
590 | colors.bar.unreliable = { r = 1.00, g = 1.00, b = 1.00 }; |
||
591 | |||
592 | colors.name = {}; |
||
593 | |||
594 | colors.name.dead = { r = 0.50, g = 0.50, b = 0.50 }; |
||
595 | |||
596 | colors.name.normal = { r = NORMAL_FONT_COLOR.r, |
||
597 | g = NORMAL_FONT_COLOR.g, |
||
598 | b = NORMAL_FONT_COLOR.b }; |
||
599 | |||
600 | colors.name.unreliable = { r = 1.00, g = 1.00, b = 1.00 }; |
||
601 | |||
602 | colors.name.unreliable_no_unit = { r = 0.83, g = 0.83, b = 0.83 }; |
||
603 | |||
604 | colors.name.undetermined = { r = NORMAL_FONT_COLOR.r, |
||
605 | g = NORMAL_FONT_COLOR.g, |
||
606 | b = NORMAL_FONT_COLOR.b }; |
||
607 | |||
608 | |||
609 | |||
610 | |||
611 | ---------------------------------------------------------------- |
||
612 | --- Globals for pre-release testing/tuning without reloading --- |
||
613 | ---------------------------------------------------------------- |
||
614 | |||
615 | HoTT_Debug = {}; |
||
616 | |||
617 | HoTT_Debug.enabled = false; |
||
618 | |||
619 | HoTT_Debug.pn = placed_names; |
||
620 | |||
621 | HoTT_Debug.pnt = {}; |
||
622 | |||
623 | |||
624 | --- |
||
625 | --- dprint |
||
626 | --- |
||
627 | |||
628 | local function dprint (message) |
||
629 | |||
630 | if ( HoTT_Debug.enabled ) then |
||
631 | |||
632 | if ( type(print) == "function" ) then |
||
633 | print(message); |
||
634 | else |
||
635 | DEFAULT_CHAT_FRAME:AddMessage(message) |
||
636 | end |
||
637 | |||
638 | end |
||
639 | |||
640 | end |
||
641 | |||
642 | |||
643 | |||
644 | |||
645 | --- |
||
646 | --- tprint |
||
647 | --- |
||
648 | |||
649 | local function tprint (message, relative_time) |
||
650 | |||
651 | if ( HoTT_Debug.enabled ) then |
||
652 | |||
653 | if ( not relative_time ) then |
||
654 | relative_time = 0; |
||
655 | end |
||
656 | |||
657 | dprint(format("%7.3f %s", |
||
658 | GetTime() - relative_time, |
||
659 | tostring(message))); |
||
660 | |||
661 | end |
||
662 | |||
663 | end |
||
664 | |||
665 | |||
666 | |||
667 | |||
668 | ------------------------------- |
||
669 | --- Stubbed local functions --- |
||
670 | ------------------------------- |
||
671 | |||
672 | |||
673 | local refresh_ui_positions; |
||
674 | local position_display; |
||
675 | |||
676 | local update_tot; |
||
677 | local update_tot_health; |
||
678 | |||
679 | local reset_poll_timer; |
||
680 | |||
681 | local launch_params_browser; |
||
682 | |||
683 | |||
684 | |||
685 | -------------------- |
||
686 | --- Other locals --- |
||
687 | -------------------- |
||
688 | |||
689 | --local current_params; |
||
690 | |||
691 | |||
692 | |||
693 | |||
694 | --------------------- |
||
695 | --- Table utility --- |
||
696 | --------------------- |
||
697 | |||
698 | --- |
||
699 | --- clear_table |
||
700 | --- |
||
701 | |||
702 | local function clear_table (table1) |
||
703 | |||
704 | local k,v; |
||
705 | |||
706 | for k,v in pairs(table1) do |
||
707 | table1[k] = nil; |
||
708 | end |
||
709 | |||
710 | return table; |
||
711 | end |
||
712 | |||
713 | |||
714 | |||
715 | --- |
||
716 | --- copy_table_recursively |
||
717 | --- |
||
718 | |||
719 | --- only used by add_settings_object_versioning() |
||
720 | --- will not copy non-iteratable tables |
||
721 | |||
722 | local function copy_table_recursively (table1, table2, missing_keys_only) |
||
723 | |||
724 | --- |
||
725 | --- NOTE: Is this kind of potential self-copy "safe" in Lua? |
||
726 | --- Would be if iterator is static -- CHECK THIS! |
||
727 | --- Also applies to copy_table() |
||
728 | --- |
||
729 | |||
730 | --- |
||
731 | --- NOTE: Lua logic means that a nil entry in the destination |
||
732 | --- is always overwritten, even with missing_keys_only true |
||
733 | --- |
||
734 | |||
735 | --- |
||
736 | --- NOTE: Should really not copy field if dest == source |
||
737 | --- This should prevent infinite recursion as well |
||
738 | --- |
||
739 | |||
740 | local k,v, copy_this |
||
741 | |||
742 | for k,v in pairs (table1) do |
||
743 | |||
744 | copy_this = ( table2[k] ~= v ) and |
||
745 | ( ( not missing_keys_only ) or |
||
746 | ( ( table2[k] == nil ) and ( v ~= nil ) ) ); |
||
747 | |||
748 | if ( type(v) == "table" ) then |
||
749 | if ( copy_this ) then |
||
750 | table2[k] = {}; |
||
751 | end |
||
752 | copy_table_recursively(v, table2[k], missing_keys_only); |
||
753 | |||
754 | else |
||
755 | if ( copy_this ) then |
||
756 | table2[k] = v; |
||
757 | end |
||
758 | end |
||
759 | |||
760 | end |
||
761 | |||
762 | return table2; |
||
763 | end |
||
764 | |||
765 | |||
766 | |||
767 | --- |
||
768 | --- copy_table_structure |
||
769 | --- |
||
770 | |||
771 | local function copy_table_structure (table1, table2, visited_nodes) |
||
772 | |||
773 | local k,v |
||
774 | |||
775 | if ( not visited_nodes ) then |
||
776 | visited_nodes = {}; |
||
777 | visited_nodes[tostring(table1)] = true; |
||
778 | end |
||
779 | |||
780 | for k,v in pairs (table1) do |
||
781 | |||
782 | if ( ( type(v) == "table" ) and |
||
783 | ( not ( visited_nodes[tostring(v)] ) ) ) then |
||
784 | |||
785 | if ( not ( type(table2[k]) == "table" ) ) then |
||
786 | table2[k] = {}; |
||
787 | end |
||
788 | |||
789 | visited_nodes[tostring(v)] = true; |
||
790 | copy_table_structure(v, table2[k], visited_nodes); |
||
791 | |||
792 | end |
||
793 | |||
794 | end |
||
795 | |||
796 | return table2; |
||
797 | end |
||
798 | |||
799 | |||
800 | |||
801 | ---------------------------- |
||
802 | --- Handling params sets --- |
||
803 | ---------------------------- |
||
804 | |||
805 | local params = {}; -- will point to the current params object |
||
806 | HoTT_Params = {}; -- as well as a global handle to it |
||
807 | |||
808 | local scratch_params = {}; -- need something before HoTT_Settings is ready |
||
809 | |||
810 | |||
811 | |||
812 | --- |
||
813 | --- set_deferral |
||
814 | --- |
||
815 | |||
816 | local function set_deferral (child, parent, child_name, parent_name) |
||
817 | |||
818 | if ( type(child_name) ~= "string" ) then |
||
819 | child_name = ""; |
||
820 | end |
||
821 | |||
822 | if ( type(parent_name) ~= "string" ) then |
||
823 | parent_name = ""; |
||
824 | end |
||
825 | |||
826 | if ( type(child) ~= "table" ) then |
||
827 | error(string.format(fmt_not_a_table, child_name, "child")); |
||
828 | end |
||
829 | |||
830 | if ( type(parent) ~= "table" ) then |
||
831 | error(string.format(fmt_not_a_table, parent_name, "parent")); |
||
832 | end |
||
833 | |||
834 | local mt_defer = {}; |
||
835 | |||
836 | mt_defer.__index = function (t, k) |
||
837 | |||
838 | local retval; |
||
839 | local pv = parent[k]; |
||
840 | |||
841 | if ( type(pv) == "table" ) then |
||
842 | t[k] = {}; |
||
843 | set_deferral(t[k], parent[k], |
||
844 | child_name, parent_name); |
||
845 | retval = t[k]; |
||
846 | |||
847 | else |
||
848 | retval = pv; |
||
849 | |||
850 | end |
||
851 | |||
852 | return retval; |
||
853 | end; |
||
854 | |||
855 | -- mt_defer.__newindex = function (t, k, v) |
||
856 | -- |
||
857 | -- local pv = parent[k]; |
||
858 | -- |
||
859 | -- if ( pv ) then |
||
860 | -- rawset(t, k, v); -- need rawset! |
||
861 | -- |
||
862 | -- else |
||
863 | -- error(string.format(fmt_no_such_field, |
||
864 | -- format_table_key(parent_name, k)), |
||
865 | -- 2); |
||
866 | -- end |
||
867 | -- |
||
868 | -- end; |
||
869 | |||
870 | |||
871 | setmetatable(child, mt_defer); |
||
872 | |||
873 | return child; |
||
874 | end |
||
875 | |||
876 | |||
877 | |||
878 | --- |
||
879 | --- set_deferral_recursively |
||
880 | --- |
||
881 | |||
882 | local function set_deferral_recursively (child, parent, |
||
883 | child_name, parent_name, visited) |
||
884 | |||
885 | |||
886 | local k,v; |
||
887 | local next_child_name; |
||
888 | local next_parent_name; |
||
889 | |||
890 | if ( type(child_name) ~= "string" ) then |
||
891 | child_name = ""; |
||
892 | end |
||
893 | |||
894 | if ( type(parent_name) ~= "string" ) then |
||
895 | parent_name = ""; |
||
896 | end |
||
897 | |||
898 | if ( type(child) ~= "table" ) then |
||
899 | error(string.format(fmt_not_a_table, child_name, "child")); |
||
900 | end |
||
901 | |||
902 | if ( type(parent) ~= "table" ) then |
||
903 | error(string.format(fmt_not_a_table, parent_name, "parent")); |
||
904 | end |
||
905 | |||
906 | if ( not visited ) then |
||
907 | visited = {}; |
||
908 | visited[child] = true; |
||
909 | end |
||
910 | |||
911 | |||
912 | for k,v in pairs(child) do |
||
913 | if ( ( type(v) == "table" ) and |
||
914 | ( not visited[v] ) ) then |
||
915 | |||
916 | if ( type(parent[k]) ~= "table" ) then |
||
917 | |||
918 | --- |
||
919 | --- WARNING: This wipes masking data |
||
920 | --- |
||
921 | |||
922 | child[k] = nil; |
||
923 | |||
924 | else |
||
925 | next_child_name = format_table_key(child_name, k); |
||
926 | next_parent_name = format_table_key(parent_name, k); |
||
927 | |||
928 | set_deferral_recursively (v, parent[k], |
||
929 | next_child_name, |
||
930 | next_parent_name, |
||
931 | visited); |
||
932 | |||
933 | end |
||
934 | |||
935 | end |
||
936 | |||
937 | end |
||
938 | |||
939 | set_deferral(child, parent, child_name, parent_name); |
||
940 | |||
941 | return child; |
||
942 | end |
||
943 | |||
944 | |||
945 | |||
946 | --- |
||
947 | --- init_preload_params |
||
948 | --- |
||
949 | |||
950 | local function init_preload_params () |
||
951 | |||
952 | set_deferral_recursively(scratch_params, default_params, |
||
953 | "scratch_params", "default_params"); |
||
954 | |||
955 | params = scratch_params; |
||
956 | HoTT_Params = scratch_params; |
||
957 | |||
958 | return params; |
||
959 | end |
||
960 | |||
961 | --- and init_preload_params for safety! |
||
962 | |||
963 | init_preload_params(); |
||
964 | |||
965 | |||
966 | |||
967 | |||
968 | --- |
||
969 | --- get_settings_set |
||
970 | --- |
||
971 | |||
972 | local function get_settings_set (set_name) |
||
973 | |||
974 | return HoTT_Settings._sets[set_name]; |
||
975 | end |
||
976 | |||
977 | |||
978 | |||
979 | --- |
||
980 | --- change_settings |
||
981 | --- |
||
982 | |||
983 | local function change_settings (set_name) |
||
984 | |||
985 | -- Assumes set_name exists and is valid |
||
986 | |||
987 | local new_settings_set = get_settings_set(set_name); |
||
988 | |||
989 | assert(new_settings_set, format(string_assert_set_exists_fmt, |
||
990 | tostring(set_name))); |
||
991 | |||
992 | set_deferral_recursively(new_settings_set, default_params, |
||
993 | "HoTT_Params", "default_params"); |
||
994 | |||
995 | -- params.hott_was_on = hott_is_on; -- this borks on-load behavior? |
||
996 | |||
997 | params = new_settings_set; |
||
998 | HoTT_Params = new_settings_set; |
||
999 | |||
1000 | refresh_ui_positions(); |
||
1001 | |||
1002 | return params; |
||
1003 | end |
||
1004 | |||
1005 | |||
1006 | |||
1007 | --- |
||
1008 | --- restore_defaults |
||
1009 | --- |
||
1010 | |||
1011 | local function restore_defaults () |
||
1012 | |||
1013 | clear_table(params); |
||
1014 | |||
1015 | refresh_ui_positions(); |
||
1016 | |||
1017 | -- DEFAULT_CHAT_FRAME:AddMessage(restored_defaults); |
||
1018 | |||
1019 | return params; |
||
1020 | end |
||
1021 | |||
1022 | |||
1023 | |||
1024 | |||
1025 | |||
1026 | |||
1027 | |||
1028 | ----------------------------------------------- |
||
1029 | --- Parameters sets and persistent settings --- |
||
1030 | ----------------------------------------------- |
||
1031 | |||
1032 | |||
1033 | --- |
||
1034 | --- NOTE: I should split these out some day |
||
1035 | --- |
||
1036 | --- outside variables refered to: |
||
1037 | --- |
||
1038 | --- player_name |
||
1039 | --- realm_name |
||
1040 | --- HoTT_Settings |
||
1041 | --- |
||
1042 | --- various strings |
||
1043 | --- |
||
1044 | |||
1045 | |||
1046 | |||
1047 | --- |
||
1048 | --- The following methods assume that the object is initalized |
||
1049 | --- and is self-consistent |
||
1050 | --- |
||
1051 | |||
1052 | |||
1053 | |||
1054 | --- |
||
1055 | --- get_default_settings_set_name |
||
1056 | --- |
||
1057 | |||
1058 | local function get_default_settings_set_name () |
||
1059 | |||
1060 | --- DO NOT LOCALIZE THIS FORMAT STRING |
||
1061 | --- Doing so will invalidate settings if the player changes locale |
||
1062 | |||
1063 | return format("%s of %s", player_name, realm_name); |
||
1064 | end |
||
1065 | |||
1066 | |||
1067 | |||
1068 | --- |
||
1069 | --- settings_set_exists |
||
1070 | --- |
||
1071 | |||
1072 | local function settings_set_exists (set_name) |
||
1073 | |||
1074 | return HoTT_Settings._sets[set_name]; |
||
1075 | end |
||
1076 | |||
1077 | |||
1078 | |||
1079 | --- |
||
1080 | --- init_settings_set |
||
1081 | --- |
||
1082 | |||
1083 | local function init_settings_set (set_name) |
||
1084 | |||
1085 | HoTT_Settings._sets[set_name] = {}; |
||
1086 | |||
1087 | return HoTT_Settings._sets[set_name]; |
||
1088 | end |
||
1089 | |||
1090 | |||
1091 | |||
1092 | --- |
||
1093 | --- get_active_settings_set_name |
||
1094 | --- |
||
1095 | |||
1096 | local function get_active_settings_set_name () |
||
1097 | |||
1098 | return HoTT_Settings._players[realm_name][player_name].active_set; |
||
1099 | end |
||
1100 | |||
1101 | |||
1102 | |||
1103 | --- |
||
1104 | --- change_active_settings_set |
||
1105 | --- |
||
1106 | |||
1107 | local function change_active_settings_set (set_name) |
||
1108 | |||
1109 | HoTT_Settings._players[realm_name][player_name].active_set = set_name; |
||
1110 | |||
1111 | return HoTT_Settings._sets[set_name]; |
||
1112 | end |
||
1113 | |||
1114 | |||
1115 | |||
1116 | --- |
||
1117 | --- get_active_settings_set |
||
1118 | --- |
||
1119 | |||
1120 | local function get_active_settings_set () |
||
1121 | |||
1122 | return get_settings_set(get_active_settings_set_name()); |
||
1123 | end |
||
1124 | |||
1125 | |||
1126 | |||
1127 | --- |
||
1128 | --- add_settings_object_versioning |
||
1129 | --- |
||
1130 | |||
1131 | local function add_settings_object_versioning (settings_object) |
||
1132 | |||
1133 | if ( type(settings_object._version) == "table" ) then |
||
1134 | clear_table(settings_object._version) |
||
1135 | else |
||
1136 | settings_object._version = {}; |
||
1137 | end |
||
1138 | |||
1139 | copy_table_recursively(version_table_data, settings_object._version); |
||
1140 | |||
1141 | return settings_object; |
||
1142 | end |
||
1143 | |||
1144 | |||
1145 | |||
1146 | --- |
||
1147 | --- NOTE: These will need serious re-working |
||
1148 | --- |
||
1149 | |||
1150 | |||
1151 | --- |
||
1152 | --- valid_settings_object |
||
1153 | --- |
||
1154 | |||
1155 | local function valid_settings_object (settings_object) |
||
1156 | |||
1157 | return ( type(settings_object) == "table") and |
||
1158 | ( type(settings_object._version) == "table" ) and |
||
1159 | ( string.sub(settings_object._version.object, 1, 2) == "1." ) |
||
1160 | ; |
||
1161 | end |
||
1162 | |||
1163 | |||
1164 | |||
1165 | --- |
||
1166 | --- repopulate_settings_object |
||
1167 | --- |
||
1168 | |||
1169 | local function repopulate_settings_object (settings_object) |
||
1170 | |||
1171 | -- nothing to do right now |
||
1172 | return settings_object; |
||
1173 | end |
||
1174 | |||
1175 | |||
1176 | |||
1177 | --- ######################################## |
||
1178 | --- update_settings_object ##### THIS ONE NEEDS TO BE CHANGED ##### |
||
1179 | --- ######################################## |
||
1180 | |||
1181 | local function update_settings_object (settings_object) |
||
1182 | |||
1183 | -- nothing to do right now, only one valid version |
||
1184 | return settings_object; |
||
1185 | end |
||
1186 | |||
1187 | |||
1188 | |||
1189 | |||
1190 | --- |
||
1191 | --- load_saved_settings |
||
1192 | --- |
||
1193 | |||
1194 | local function load_saved_settings () |
||
1195 | |||
1196 | |||
1197 | --- |
||
1198 | --- A mish-mosh of validation, object creation, initialization |
||
1199 | --- error reporting, and some application-specific tie-ins |
||
1200 | --- |
||
1201 | --- Will need to be cleaned up a lot to split out |
||
1202 | --- |
||
1203 | |||
1204 | --- |
||
1205 | --- Should really use getglobal(), but can't find "setglobal()" |
||
1206 | --- |
||
1207 | |||
1208 | |||
1209 | local player_ptr; |
||
1210 | local set_ptr; |
||
1211 | |||
1212 | local default_set_name; |
||
1213 | local active_set_name; |
||
1214 | |||
1215 | |||
1216 | if ( not valid_settings_object(HoTT_Settings) ) then |
||
1217 | |||
1218 | if (HoTT_Settings) then |
||
1219 | |||
1220 | HoTT_Settings_Unparsed = HoTT_Settings; |
||
1221 | |||
1222 | DEFAULT_CHAT_FRAME:AddMessage(invalid_settings_string); |
||
1223 | |||
1224 | end |
||
1225 | |||
1226 | |||
1227 | -- Initialize from scratch |
||
1228 | dprint("initializing object"); |
||
1229 | |||
1230 | HoTT_Settings = {}; |
||
1231 | |||
1232 | add_settings_object_versioning(HoTT_Settings); |
||
1233 | |||
1234 | HoTT_Settings._players = {}; |
||
1235 | HoTT_Settings._sets = {}; |
||
1236 | |||
1237 | end |
||
1238 | |||
1239 | |||
1240 | -- Add anything that is lost in the write/read cycle |
||
1241 | -- Ok, we have a valid, but possibly outdated settings object |
||
1242 | dprint("repopulate and update"); |
||
1243 | |||
1244 | repopulate_settings_object(HoTT_Settings); |
||
1245 | update_settings_object(HoTT_Settings); |
||
1246 | |||
1247 | |||
1248 | -- Now its good to go, though possibly empty |
||
1249 | |||
1250 | |||
1251 | assert(player_name, string_assert_no_player); |
||
1252 | assert(realm_name, string_assert_no_realm); |
||
1253 | |||
1254 | |||
1255 | -- Make sure this player's default set exists first |
||
1256 | |||
1257 | |||
1258 | default_set_name = get_default_settings_set_name(); |
||
1259 | dprint("default_set_name: "..tostring(default_set_name)); |
||
1260 | if ( not settings_set_exists(default_set_name) ) then |
||
1261 | dprint("initializing default set for "..tostring(default_set_name)); |
||
1262 | init_settings_set(default_set_name); |
||
1263 | end |
||
1264 | |||
1265 | |||
1266 | -- Then make sure the player exists |
||
1267 | |||
1268 | |||
1269 | if ( not HoTT_Settings._players[realm_name] ) then |
||
1270 | dprint("._players"); |
||
1271 | HoTT_Settings._players[realm_name] = {}; |
||
1272 | end |
||
1273 | |||
1274 | if ( not HoTT_Settings._players[realm_name][player_name] ) then |
||
1275 | dprint("._players."..tostring(realm_name)); |
||
1276 | HoTT_Settings._players[realm_name][player_name] = {}; |
||
1277 | end |
||
1278 | |||
1279 | if ( not HoTT_Settings._players[realm_name][player_name] ) then |
||
1280 | dprint("._players."..tostring(realm_name)..tostring(player_name)); |
||
1281 | HoTT_Settings._players[realm_name][player_name] = {}; |
||
1282 | end |
||
1283 | |||
1284 | |||
1285 | -- and tie them to their default set if they don't have one already |
||
1286 | |||
1287 | |||
1288 | active_set_name = get_active_settings_set_name(); |
||
1289 | |||
1290 | if ( not active_set_name ) then |
||
1291 | dprint("change to default"); |
||
1292 | change_active_settings_set(default_set_name); |
||
1293 | end |
||
1294 | |||
1295 | |||
1296 | -- Realm, player, and default set should be present now |
||
1297 | -- Check that their active set is a good one |
||
1298 | |||
1299 | |||
1300 | active_set_name = get_active_settings_set_name(); |
||
1301 | |||
1302 | |||
1303 | |||
1304 | if ( not settings_set_exists(active_set_name) ) then |
||
1305 | |||
1306 | -- Go to their default set |
||
1307 | |||
1308 | DEFAULT_CHAT_FRAME:AddMessage(format(restore_failed_format, |
||
1309 | active_set_name)); |
||
1310 | |||
1311 | change_active_settings_set(default_set_name); |
||
1312 | |||
1313 | DEFAULT_CHAT_FRAME:AddMessage(format(restored_format, |
||
1314 | active_set_name)); |
||
1315 | |||
1316 | end |
||
1317 | |||
1318 | -- which really exists |
||
1319 | dprint("Change to: "..tostring(active_set_name)); |
||
1320 | return change_settings(active_set_name); |
||
1321 | end |
||
1322 | |||
1323 | |||
1324 | |||
1325 | ----------------------- |
||
1326 | ----------------------- |
||
1327 | --- LOCAL FUNCTIONS --- |
||
1328 | ----------------------- |
||
1329 | ----------------------- |
||
1330 | |||
1331 | |||
1332 | -------------------------- |
||
1333 | --- target_info tables --- |
||
1334 | -------------------------- |
||
1335 | |||
1336 | --- |
||
1337 | --- clear_target_info |
||
1338 | --- |
||
1339 | |||
1340 | local function clear_target_info (target_info) |
||
1341 | |||
1342 | clear_table(target_info); |
||
1343 | |||
1344 | return target_info; |
||
1345 | end |
||
1346 | |||
1347 | |||
1348 | |||
1349 | --- |
||
1350 | --- copy_target_info |
||
1351 | --- |
||
1352 | |||
1353 | local function copy_target_info (target_info1, target_info2) |
||
1354 | |||
1355 | local k,v; |
||
1356 | |||
1357 | clear_target_info(target_info2); |
||
1358 | for k,v in pairs(target_info1) do |
||
1359 | target_info2[k] = v; |
||
1360 | end |
||
1361 | |||
1362 | return target_info2; |
||
1363 | end |
||
1364 | |||
1365 | |||
1366 | |||
1367 | --- |
||
1368 | --- exact_target_info |
||
1369 | --- |
||
1370 | |||
1371 | local function exact_target_info (target_info1, target_info2) |
||
1372 | |||
1373 | return ( target_info1.name == target_info2.name ) and |
||
1374 | ( target_info1.level == target_info2.level ) and |
||
1375 | ( target_info1.sex == target_info2.sex ) and |
||
1376 | ( target_info1.player == target_info2.player ) and |
||
1377 | ( target_info1.enemy == target_info2.enemy ) and |
||
1378 | ( target_info1.canattack == target_info2.canattack ) and |
||
1379 | ( target_info1.canattackme == target_info2.canattackme ) and |
||
1380 | ( target_info1.friend == target_info2.friend ) and |
||
1381 | ( target_info1.shapeshifted == target_info2.shapeshifted ); |
||
1382 | end |
||
1383 | |||
1384 | |||
1385 | |||
1386 | --- |
||
1387 | --- clear_t |
||
1388 | --- |
||
1389 | |||
1390 | local function clear_t () |
||
1391 | |||
1392 | clear_target_info(t_target_info); |
||
1393 | |||
1394 | return t_target_info; |
||
1395 | end |
||
1396 | |||
1397 | |||
1398 | |||
1399 | --- |
||
1400 | --- clear_tot |
||
1401 | --- |
||
1402 | |||
1403 | local function clear_tot () |
||
1404 | |||
1405 | last_tot = tot_target_info.name; |
||
1406 | |||
1407 | clear_target_info(tot_target_info); |
||
1408 | |||
1409 | this_tot = nil; |
||
1410 | |||
1411 | return tot_target_info; |
||
1412 | end |
||
1413 | |||
1414 | |||
1415 | |||
1416 | --- |
||
1417 | --- target_to_t |
||
1418 | --- |
||
1419 | |||
1420 | local function target_to_t () |
||
1421 | |||
1422 | if ( UnitExists("target") ) then |
||
1423 | |||
1424 | t_target_info.name = UnitName("target"); |
||
1425 | t_target_info.level = UnitLevel("target"); |
||
1426 | t_target_info.sex = UnitSex("target"); |
||
1427 | t_target_info.player = UnitIsPlayer("target"); |
||
1428 | t_target_info.enemy = UnitIsEnemy("target", "player"); |
||
1429 | t_target_info.canattack = UnitCanAttack("player", "target"); |
||
1430 | t_target_info.canattackme = UnitCanAttack("target", "player"); |
||
1431 | t_target_info.friend = UnitIsFriend("target", "player"); |
||
1432 | t_target_info.shapeshifted = nil; -- for later expansion |
||
1433 | |||
1434 | else |
||
1435 | clear_t(); |
||
1436 | |||
1437 | end |
||
1438 | |||
1439 | return t_target_info; |
||
1440 | end |
||
1441 | |||
1442 | |||
1443 | |||
1444 | --- |
||
1445 | --- targettarget_to_tot |
||
1446 | --- |
||
1447 | |||
1448 | local function targettarget_to_tot () |
||
1449 | |||
1450 | last_tot = tot_target_info.name; |
||
1451 | |||
1452 | if ( UnitExists("targettarget") ) then |
||
1453 | |||
1454 | tot_target_info.name = UnitName("targettarget"); |
||
1455 | tot_target_info.level = UnitLevel("targettarget"); |
||
1456 | tot_target_info.sex = UnitSex("targettarget"); |
||
1457 | tot_target_info.player = UnitIsPlayer("targettarget"); |
||
1458 | tot_target_info.enemy = UnitIsEnemy("targettarget", "player"); |
||
1459 | tot_target_info.canattack = UnitCanAttack("player", "targettarget"); |
||
1460 | tot_target_info.canattackme = UnitCanAttack("targettarget", "player"); |
||
1461 | tot_target_info.friend = UnitIsFriend("targettarget", "player"); |
||
1462 | tot_target_info.shapeshifted = nil; -- for later expansion |
||
1463 | |||
1464 | else |
||
1465 | clear_tot(); |
||
1466 | |||
1467 | end |
||
1468 | |||
1469 | this_tot = tot_target_info.name; |
||
1470 | |||
1471 | return tot_target_info; |
||
1472 | end |
||
1473 | |||
1474 | |||
1475 | |||
1476 | --- |
||
1477 | --- self_to_tot |
||
1478 | --- |
||
1479 | |||
1480 | local function self_to_tot () |
||
1481 | |||
1482 | -- Yep, this could be simpler, but leave it be for clarity |
||
1483 | -- It shouldn't be called except on target change to self |
||
1484 | -- and then when the idle check times out |
||
1485 | |||
1486 | last_tot = tot_target_info.name; |
||
1487 | |||
1488 | if ( UnitExists("player") ) then |
||
1489 | |||
1490 | tot_target_info.name = UnitName("player"); |
||
1491 | tot_target_info.level = UnitLevel("player"); |
||
1492 | tot_target_info.sex = UnitSex("player"); |
||
1493 | tot_target_info.player = UnitIsPlayer("player"); |
||
1494 | tot_target_info.enemy = UnitIsEnemy("player", "player"); |
||
1495 | tot_target_info.canattack = UnitCanAttack("player", "player"); |
||
1496 | tot_target_info.canattackme = UnitCanAttack("player", "player"); |
||
1497 | tot_target_info.friend = UnitIsFriend("player", "player"); |
||
1498 | tot_target_info.shapeshifted = nil; -- for later expansion |
||
1499 | |||
1500 | else |
||
1501 | clear_tot(); |
||
1502 | |||
1503 | end |
||
1504 | |||
1505 | this_tot = tot_target_info.name; |
||
1506 | |||
1507 | return tot_target_info; |
||
1508 | end |
||
1509 | |||
1510 | |||
1511 | |||
1512 | --- |
||
1513 | --- new_target_appears_same_as_before |
||
1514 | --- |
||
1515 | |||
1516 | local function new_target_appears_same_as_before () |
||
1517 | |||
1518 | local retval = UnitExists("target"); |
||
1519 | |||
1520 | if ( retval ) then |
||
1521 | |||
1522 | local target_sex = UnitSex("target"); |
||
1523 | |||
1524 | if ( ( UnitName("target") ~= t_target_info.name ) or |
||
1525 | ( UnitLevel("target") ~= t_target_info.level ) ) then |
||
1526 | retval = false; |
||
1527 | |||
1528 | elseif ( target_sex == t_target_info.sex ) then |
||
1529 | retval = true; |
||
1530 | |||
1531 | -- well, except for shapeshifted mobs, |
||
1532 | -- which we very poorly handle with |
||
1533 | |||
1534 | elseif ( (target_sex == 2) or (t_target_info.sex == 2) ) then |
||
1535 | retval = true; |
||
1536 | |||
1537 | else |
||
1538 | retval = false; |
||
1539 | |||
1540 | end |
||
1541 | |||
1542 | end |
||
1543 | |||
1544 | return retval; |
||
1545 | end |
||
1546 | |||
1547 | |||
1548 | |||
1549 | ------------------------------------ |
||
1550 | --- Maintain a roster of UnitIDs --- |
||
1551 | ------------------------------------ |
||
1552 | |||
1553 | --- |
||
1554 | --- insert_possible_unit |
||
1555 | --- |
||
1556 | |||
1557 | local function insert_possible_unit (unit, type) |
||
1558 | |||
1559 | local retval = true; |
||
1560 | |||
1561 | local name = UnitName(unit); |
||
1562 | local existing_unit; |
||
1563 | |||
1564 | if ( name and (name ~= UNKNOWNOBJECT) and (name ~= UKNOWNBEING) ) then |
||
1565 | |||
1566 | existing_unit = roster[name]; |
||
1567 | |||
1568 | if ( existing_unit and |
||
1569 | ( string.sub(existing_unit, 1, string.len(type)) == type ) ) then |
||
1570 | assert(roster_assertion_seen, |
||
1571 | format(ras_format, |
||
1572 | name, existing_unit, unit)); |
||
1573 | roster_assertion_seen = true; |
||
1574 | retval = nil; |
||
1575 | else |
||
1576 | roster[name] = unit; |
||
1577 | retval = name; |
||
1578 | end |
||
1579 | |||
1580 | end |
||
1581 | |||
1582 | return retval; |
||
1583 | end |
||
1584 | |||
1585 | |||
1586 | |||
1587 | --- |
||
1588 | --- update_roster |
||
1589 | --- |
||
1590 | |||
1591 | local function update_roster () |
||
1592 | |||
1593 | local retval = true; |
||
1594 | local this_ok; |
||
1595 | |||
1596 | local unit, name, idx; |
||
1597 | local nraid = GetNumRaidMembers(); |
||
1598 | local nparty = GetNumPartyMembers(); |
||
1599 | |||
1600 | clear_table(roster); |
||
1601 | |||
1602 | if ( nraid > 1 ) then |
||
1603 | |||
1604 | for idx = 1, 40 do -- as they are by slot, and may not be sequential |
||
1605 | unit = format("raid%i",idx); |
||
1606 | this_ok = insert_possible_unit(unit, "raid"); |
||
1607 | retval = retval and this_ok; |
||
1608 | unit = format("raidpet%i",idx); |
||
1609 | this_ok = insert_possible_unit(unit, "raidpet"); |
||
1610 | retval = retval and this_ok; |
||
1611 | end |
||
1612 | |||
1613 | end |
||
1614 | |||
1615 | if ( nparty > 1 ) then |
||
1616 | |||
1617 | for idx = 1, 4 do -- its only 4 and nparty-1 was seemingly one short |
||
1618 | unit = format("party%i",idx); |
||
1619 | this_ok =insert_possible_unit(unit, "party"); |
||
1620 | retval = retval and this_ok; |
||
1621 | unit = format("partypet%i",idx); |
||
1622 | this_ok =insert_possible_unit(unit, "partypet"); |
||
1623 | retval = retval and this_ok; |
||
1624 | end |
||
1625 | |||
1626 | end |
||
1627 | |||
1628 | this_ok = insert_possible_unit("player", "player"); |
||
1629 | retval = retval and this_ok; |
||
1630 | this_ok = insert_possible_unit("pet", "pet"); |
||
1631 | retval = retval and this_ok; |
||
1632 | |||
1633 | return retval; |
||
1634 | end |
||
1635 | |||
1636 | |||
1637 | |||
1638 | --- |
||
1639 | --- best_tot_unit |
||
1640 | --- |
||
1641 | |||
1642 | local function best_tot_unit() |
||
1643 | |||
1644 | local retval = nil; |
||
1645 | |||
1646 | if ( ( UnitExists("targettarget") ) and |
||
1647 | ( UnitName("targettarget") == tot_target_info.name ) ) then |
||
1648 | retval = "targettarget"; |
||
1649 | |||
1650 | else |
||
1651 | retval = roster[tot_target_info.name]; |
||
1652 | |||
1653 | end |
||
1654 | |||
1655 | return retval; |
||
1656 | end |
||
1657 | |||
1658 | |||
1659 | |||
1660 | |||
1661 | --- |
||
1662 | --- update_bar_unit |
||
1663 | --- |
||
1664 | |||
1665 | local function update_bar_unit() |
||
1666 | |||
1667 | -- Returns true unless "real" unit is known not to have changed |
||
1668 | |||
1669 | local try_unit = roster[tot_target_info.name]; |
||
1670 | local old_unit = HoTT_Display_Bar.unit; |
||
1671 | if ( not units_getting_events[try_unit] ) then |
||
1672 | try_unit = nil; |
||
1673 | end |
||
1674 | HoTT_Display_Bar.unit = try_unit; |
||
1675 | if ( HoTT_Debug.UBU and ( HoTT_Display_Bar.unit ~= old_unit) ) then |
||
1676 | dprint("Bar now using "..tostring(HoTT_Display_Bar.unit)); |
||
1677 | end |
||
1678 | |||
1679 | return not ( HoTT_Display_Bar.unit and |
||
1680 | ( HoTT_Display_Bar.unit == old_unit ) |
||
1681 | ); |
||
1682 | end |
||
1683 | |||
1684 | |||
1685 | |||
1686 | --- |
||
1687 | --- clear_bar |
||
1688 | --- |
||
1689 | |||
1690 | local function clear_bar () |
||
1691 | |||
1692 | HoTT_Display_Bar.unit = nil; |
||
1693 | HoTT_Display_Bar:SetValue(0); |
||
1694 | HoTT_Display_Dead:Hide(); |
||
1695 | |||
1696 | end |
||
1697 | |||
1698 | |||
1699 | |||
1700 | --- |
||
1701 | --- available_name_width |
||
1702 | --- |
||
1703 | |||
1704 | local function available_name_width () |
||
1705 | |||
1706 | local right = HoTT_Display:GetRight(); |
||
1707 | local left = HoTT_Display:GetLeft(); |
||
1708 | |||
1709 | local anw = 115; -- Covers start-up nil problem |
||
1710 | |||
1711 | if ( right and left ) then |
||
1712 | anw = (right - left) |
||
1713 | - params.ui.display.tot_name.inset.right |
||
1714 | - params.ui.display.tot_name.inset.left; |
||
1715 | end |
||
1716 | |||
1717 | return anw; |
||
1718 | |||
1719 | end |
||
1720 | |||
1721 | |||
1722 | |||
1723 | --- |
||
1724 | --- set_display_name_color |
||
1725 | --- |
||
1726 | |||
1727 | --- Typcially ~ 5 ms for a new name and a reasonably-sized window |
||
1728 | --- About 10-15 ms to truncate down a long name to nothing |
||
1729 | --- regexp is not the culprit |
||
1730 | |||
1731 | local function set_display_name_color(name, color) |
||
1732 | |||
1733 | |||
1734 | if ( name ) then |
||
1735 | |||
1736 | if ( placed_names.available_name_width ~= available_name_width() ) then |
||
1737 | clear_table(placed_names); |
||
1738 | placed_names.available_name_width = available_name_width(); |
||
1739 | |||
1740 | end |
||
1741 | |||
1742 | local fits = placed_names[name]; |
||
1743 | |||
1744 | if ( fits ) then |
||
1745 | HoTT_Display_NameArea_Text:SetText(fits); |
||
1746 | |||
1747 | else |
||
1748 | |||
1749 | local now; |
||
1750 | |||
1751 | if ( HoTT_Debug.name_time ) then |
||
1752 | now = GetTime(); |
||
1753 | end |
||
1754 | |||
1755 | HoTT_Display_NameArea_Text:SetText(name); |
||
1756 | if ( ( HoTT_Display_NameArea_Text:GetStringWidth() <= |
||
1757 | placed_names.available_name_width ) or |
||
1758 | ( string.len(name) <= 2 ) |
||
1759 | ) then |
||
1760 | fits = name; |
||
1761 | |||
1762 | else |
||
1763 | |||
1764 | local try = string.sub(name, 1, -2); |
||
1765 | local ellipsis_chars = string.len(ellipsis); |
||
1766 | |||
1767 | while ( not fits ) do |
||
1768 | HoTT_Display_NameArea_Text:SetText(try); |
||
1769 | if ( ( HoTT_Display_NameArea_Text:GetStringWidth() <= |
||
1770 | placed_names.available_name_width ) or |
||
1771 | ( string.len(try) <= 2 ) |
||
1772 | ) then |
||
1773 | fits = try; |
||
1774 | else |
||
1775 | try = string.sub(try, 1, -2); |
||
1776 | end |
||
1777 | end |
||
1778 | |||
1779 | try = string.sub(try, 1, -2) .. ellipsis; |
||
1780 | fits = false; |
||
1781 | |||
1782 | while ( not fits ) do |
||
1783 | HoTT_Display_NameArea_Text:SetText(try); |
||
1784 | if ( ( HoTT_Display_NameArea_Text:GetStringWidth() <= |
||
1785 | placed_names.available_name_width ) or |
||
1786 | ( string.len(try) <= ( 1 + ellipsis_chars ) ) |
||
1787 | ) then |
||
1788 | fits = try; |
||
1789 | else |
||
1790 | try = string.sub(try, 1, -2-ellipsis_chars) .. ellipsis; |
||
1791 | end |
||
1792 | end |
||
1793 | |||
1794 | fits = string.gsub(fits, "%s"..ellipsis.."$", ellipsis); |
||
1795 | |||
1796 | end -- did name fit first time |
||
1797 | |||
1798 | placed_names[name] = fits; |
||
1799 | if ( HoTT_Debug.name_time ) then |
||
1800 | local dt = GetTime() - now; |
||
1801 | if ( dt > 0.0015 ) then |
||
1802 | HoTT_Debug.pnt[name] = format("%5.3f",GetTime() - now); |
||
1803 | end |
||
1804 | tprint("Name time", now); |
||
1805 | end |
||
1806 | HoTT_Display_NameArea_Text:SetText(fits); |
||
1807 | |||
1808 | end |
||
1809 | |||
1810 | end |
||
1811 | |||
1812 | if ( color ) then |
||
1813 | HoTT_Display_NameArea_Text:SetTextColor(color.r, |
||
1814 | color.g, |
||
1815 | color.b); |
||
1816 | end |
||
1817 | |||
1818 | return true; |
||
1819 | end |
||
1820 | |||
1821 | |||
1822 | |||
1823 | --- |
||
1824 | --- position_display |
||
1825 | --- |
||
1826 | |||
1827 | -- local |
||
1828 | function position_display () |
||
1829 | |||
1830 | local buff_rows_shown; |
||
1831 | local anw = available_name_width(); |
||
1832 | |||
1833 | local puid = params.ui.display; |
||
1834 | local relative_to = puid.relative_to; |
||
1835 | local relative_to_object = getglobal(relative_to); |
||
1836 | |||
1837 | if ( not relative_to_object ) then |
||
1838 | message(format(fmt_no_such_object, puid.relative_to)); |
||
1839 | |||
1840 | return false; |
||
1841 | end |
||
1842 | |||
1843 | |||
1844 | if ( HoTT_Debug.PD ) then |
||
1845 | dprint("Positioning for " .. ( UnitName("target") or "<nil>")); |
||
1846 | end |
||
1847 | |||
1848 | |||
1849 | local has_buffs = UnitBuff("target",1); |
||
1850 | local has_debuffs = UnitDebuff("target",1); |
||
1851 | local is_friend = UnitIsFriend("player", "target"); |
||
1852 | |||
1853 | if ( not ( has_buffs or has_debuffs ) ) then |
||
1854 | buff_rows_shown = 0; |
||
1855 | |||
1856 | elseif ( ( has_debuffs and is_friend ) or |
||
1857 | ( has_buffs and not is_friend ) ) then |
||
1858 | buff_rows_shown = 2; |
||
1859 | |||
1860 | else |
||
1861 | buff_rows_shown = 1; |
||
1862 | |||
1863 | end |
||
1864 | |||
1865 | -- Check for "too narrow" problems and silently rectify |
||
1866 | |||
1867 | if ( anw < puid.tot_name.min_width ) then |
||
1868 | puid.inset.right = puid.inset.right + ( puid.tot_name.min_width - anw ); |
||
1869 | end |
||
1870 | |||
1871 | |||
1872 | --- Need to adjust relative offsets to UIParent scale |
||
1873 | |||
1874 | local s = 1/params.ui.display.scale; |
||
1875 | |||
1876 | |||
1877 | if ( ( relative_to_object == UIParent ) or |
||
1878 | ( relative_to_object == WorldFrame ) ) then |
||
1879 | |||
1880 | HoTT_Display:SetPoint("TOPLEFT", |
||
1881 | puid.relative_to, |
||
1882 | "TOPLEFT", |
||
1883 | s*puid.inset.left, |
||
1884 | -s*puid.drops[buff_rows_shown]); |
||
1885 | |||
1886 | HoTT_Display:SetPoint("TOPRIGHT", |
||
1887 | puid.relative_to, |
||
1888 | "TOPRIGHT", |
||
1889 | -s*puid.inset.right, |
||
1890 | -s*puid.drops[buff_rows_shown]); |
||
1891 | |||
1892 | else |
||
1893 | |||
1894 | HoTT_Display:SetPoint("TOPLEFT", |
||
1895 | puid.relative_to, |
||
1896 | "BOTTOMLEFT", |
||
1897 | s*puid.inset.left, |
||
1898 | -s*puid.drops[buff_rows_shown]); |
||
1899 | |||
1900 | HoTT_Display:SetPoint("TOPRIGHT", |
||
1901 | puid.relative_to, |
||
1902 | "BOTTOMRIGHT", |
||
1903 | -s*puid.inset.right, |
||
1904 | -s*puid.drops[buff_rows_shown]); |
||
1905 | |||
1906 | end |
||
1907 | |||
1908 | return true; |
||
1909 | end |
||
1910 | |||
1911 | |||
1912 | |||
1913 | --- |
||
1914 | --- refresh_ui_positions |
||
1915 | --- |
||
1916 | |||
1917 | --- |
||
1918 | --- NOTE: Call on /tot ui, and any time settings change |
||
1919 | --- |
||
1920 | |||
1921 | -- stubbed local earlier: |
||
1922 | -- |
||
1923 | -- local |
||
1924 | function refresh_ui_positions () |
||
1925 | |||
1926 | local name_offset; |
||
1927 | |||
1928 | local puid = params.ui.display; |
||
1929 | |||
1930 | HoTT_Display:SetScale(puid.scale * UIParent:GetScale()); |
||
1931 | |||
1932 | HoTT_Display_NameArea_Text:SetPoint("LEFT", |
||
1933 | "HoTT_Display_NameArea", |
||
1934 | "LEFT", |
||
1935 | puid.tot_name.inset.left, 0); |
||
1936 | |||
1937 | HoTT_Display_NameArea_Text:SetPoint("RIGHT", |
||
1938 | "HoTT_Display_NameArea", |
||
1939 | "RIGHT", |
||
1940 | -puid.tot_name.inset.right, 0); |
||
1941 | |||
1942 | HoTT_Display_NameArea_Text:SetJustifyH(puid.tot_name.alignment); |
||
1943 | |||
1944 | position_display(); |
||
1945 | |||
1946 | return true; |
||
1947 | end |
||
1948 | |||
1949 | |||
1950 | |||
1951 | --- |
||
1952 | --- global_check_warning |
||
1953 | --- |
||
1954 | |||
1955 | local function global_check_warning () |
||
1956 | |||
1957 | local global_check_failed = ( type(global_check_failures) ~= "nil" ); |
||
1958 | |||
1959 | if ( global_check_failed ) then |
||
1960 | DEFAULT_CHAT_FRAME:AddMessage(string_global_check_failed); |
||
1961 | end |
||
1962 | |||
1963 | return global_check_failed; |
||
1964 | end |
||
1965 | |||
1966 | |||
1967 | --- |
||
1968 | --- hott_init |
||
1969 | --- |
||
1970 | |||
1971 | local function hott_init () |
||
1972 | |||
1973 | clear_t(); |
||
1974 | clear_tot(); |
||
1975 | hott_is_on = false; |
||
1976 | last_tot = nil; |
||
1977 | last_frame_tot = nil; |
||
1978 | |||
1979 | clear_table(roster); |
||
1980 | |||
1981 | clear_bar(); |
||
1982 | |||
1983 | reset_poll_timer(); |
||
1984 | |||
1985 | set_display_name_color(undetermined_string, colors.name.undetermined); |
||
1986 | |||
1987 | return true; |
||
1988 | end |
||
1989 | |||
1990 | |||
1991 | |||
1992 | --- |
||
1993 | --- hott_off |
||
1994 | --- |
||
1995 | |||
1996 | local function hott_off () |
||
1997 | |||
1998 | global_check_warning(); |
||
1999 | |||
2000 | hott_init(); |
||
2001 | |||
2002 | HoTT_Display:Hide(); |
||
2003 | |||
2004 | params.hott_was_on = false; |
||
2005 | |||
2006 | -- DEFAULT_CHAT_FRAME:AddMessage(off_string); |
||
2007 | |||
2008 | return true; |
||
2009 | end |
||
2010 | |||
2011 | |||
2012 | |||
2013 | --- |
||
2014 | --- hott_on |
||
2015 | --- |
||
2016 | |||
2017 | local function hott_on () |
||
2018 | |||
2019 | global_check_warning(); |
||
2020 | |||
2021 | if ( HoTT_Patch_Warning() ) then |
||
2022 | return; |
||
2023 | end |
||
2024 | |||
2025 | if ( not hott_is_on ) then |
||
2026 | hott_init(); |
||
2027 | update_roster(); |
||
2028 | end |
||
2029 | |||
2030 | hott_is_on = true; |
||
2031 | |||
2032 | update_tot(); |
||
2033 | |||
2034 | refresh_ui_positions(); |
||
2035 | |||
2036 | if UnitExists("target") then |
||
2037 | HoTT_Display:Show(); |
||
2038 | end |
||
2039 | |||
2040 | params.hott_was_on = true; |
||
2041 | |||
2042 | -- DEFAULT_CHAT_FRAME:AddMessage(on_string); |
||
2043 | |||
2044 | return true; |
||
2045 | end |
||
2046 | |||
2047 | |||
2048 | |||
2049 | --- |
||
2050 | --- better_target_by_name |
||
2051 | --- |
||
2052 | |||
2053 | local function better_target_by_name (desiredTarget, second_pass) |
||
2054 | |||
2055 | local oldTarget = UnitName("target"); |
||
2056 | local newTarget; |
||
2057 | local retval; |
||
2058 | |||
2059 | local reverse_unit = roster[desiredTarget]; |
||
2060 | if ( UnitName("targettarget") == desiredTarget ) then |
||
2061 | TargetUnit("targettarget"); |
||
2062 | |||
2063 | elseif (reverse_unit) then |
||
2064 | TargetUnit(reverse_unit); |
||
2065 | |||
2066 | else |
||
2067 | TargetByName(desiredTarget); |
||
2068 | |||
2069 | end |
||
2070 | |||
2071 | newTarget = UnitName("target"); |
||
2072 | |||
2073 | if ( newTarget == desiredTarget ) then |
||
2074 | |||
2075 | retval = newTarget; |
||
2076 | |||
2077 | else |
||
2078 | -- restore target to the "best" option, return nil |
||
2079 | |||
2080 | if ( not second_pass ) then |
||
2081 | better_target_by_name(oldTarget, true); |
||
2082 | |||
2083 | else |
||
2084 | ClearTarget(); |
||
2085 | |||
2086 | end |
||
2087 | |||
2088 | retval = nil; |
||
2089 | |||
2090 | end |
||
2091 | |||
2092 | return retval; |
||
2093 | |||
2094 | end |
||
2095 | |||
2096 | |||
2097 | |||
2098 | --- |
||
2099 | --- bar_set_unreliable_callback |
||
2100 | --- |
||
2101 | |||
2102 | local function bar_set_unreliable_callback () |
||
2103 | -- placeholder |
||
2104 | end |
||
2105 | |||
2106 | |||
2107 | |||
2108 | --- |
||
2109 | --- load_saved_variables |
||
2110 | --- |
||
2111 | |||
2112 | local function load_saved_variables () |
||
2113 | |||
2114 | --- |
||
2115 | --- On entering this, VARIABLES_LOADED should have fired |
||
2116 | --- and the flag indicating this has run should not be set |
||
2117 | --- |
||
2118 | --- Return a true value to set that flag |
||
2119 | --- |
||
2120 | |||
2121 | load_saved_settings(); |
||
2122 | |||
2123 | if ( IsShiftKeyDown() ) then |
||
2124 | |||
2125 | DEFAULT_CHAT_FRAME:AddMessage(shift_at_load_string); |
||
2126 | |||
2127 | hott_off(); |
||
2128 | |||
2129 | else |
||
2130 | |||
2131 | if ( params.hott_was_on ) then |
||
2132 | |||
2133 | hott_on(); |
||
2134 | |||
2135 | else |
||
2136 | |||
2137 | hott_off(); |
||
2138 | |||
2139 | end |
||
2140 | |||
2141 | end |
||
2142 | |||
2143 | return true; |
||
2144 | end |
||
2145 | |||
2146 | |||
2147 | |||
2148 | ------------------------------------ |
||
2149 | --- Command parsing and dispatch --- |
||
2150 | ------------------------------------ |
||
2151 | |||
2152 | |||
2153 | --- |
||
2154 | --- HoTT_Command_Dispatch |
||
2155 | --- |
||
2156 | |||
2157 | local function command_dispatch (command_string) |
||
2158 | |||
2159 | local i1, i2; |
||
2160 | local command, command_arguments |
||
2161 | |||
2162 | command_string = string.gsub(string.lower(command_string), "^%s*", ""); |
||
2163 | command_string = string.gsub(command_string, "%s*$", ""); |
||
2164 | |||
2165 | i1, i2, command, command_arguments = |
||
2166 | string.find(command_string, "^(%w+)%s*(.*)$"); |
||
2167 | |||
2168 | |||
2169 | if ( ( command == string_help_cmd ) or ( command == nil ) ) then |
||
2170 | DEFAULT_CHAT_FRAME:AddMessage(help_message); |
||
2171 | |||
2172 | |||
2173 | elseif ( command == string_on_cmd ) then |
||
2174 | hott_on(); |
||
2175 | |||
2176 | |||
2177 | elseif ( command == string_off_cmd ) then |
||
2178 | hott_off(); |
||
2179 | |||
2180 | |||
2181 | elseif ( command == string_ui_cmd ) then |
||
2182 | DEFAULT_CHAT_FRAME:AddMessage(help_ui); |
||
2183 | |||
2184 | |||
2185 | elseif ( command == string_version_cmd ) then |
||
2186 | DEFAULT_CHAT_FRAME:AddMessage( |
||
2187 | format("ToT CVS versions:\nLua: %s\nXML: %s", |
||
2188 | version_table_data.apps.TargetOfTarget.lua_CVS, |
||
2189 | version_table_data.apps.TargetOfTarget.XML_CVS)); |
||
2190 | |||
2191 | |||
2192 | elseif ( command == string_globals_cmd ) then |
||
2193 | |||
2194 | if ( not global_check_failures ) then |
||
2195 | DEFAULT_CHAT_FRAME:AddMessage(string_global_list); |
||
2196 | |||
2197 | else |
||
2198 | DEFAULT_CHAT_FRAME:AddMessage(string_global_check_explanation); |
||
2199 | table_to_list = global_check_failures; |
||
2200 | for k,v in pairs(global_check_failures) do |
||
2201 | DEFAULT_CHAT_FRAME:AddMessage(v); |
||
2202 | end |
||
2203 | DEFAULT_CHAT_FRAME:AddMessage(string_global_variable_check_trailer); |
||
2204 | |||
2205 | end |
||
2206 | |||
2207 | |||
2208 | elseif ( command == string_params_cmd ) then |
||
2209 | launch_params_browser(); |
||
2210 | |||
2211 | |||
2212 | else |
||
2213 | DEFAULT_CHAT_FRAME:AddMessage(string_unrecognized_cmd_help); |
||
2214 | |||
2215 | end |
||
2216 | |||
2217 | end |
||
2218 | |||
2219 | |||
2220 | |||
2221 | |||
2222 | |||
2223 | |||
2224 | |||
2225 | ------------------------ |
||
2226 | ------------------------ |
||
2227 | --- GLOBAL FUNCTIONS --- |
||
2228 | ------------------------ |
||
2229 | ------------------------ |
||
2230 | |||
2231 | |||
2232 | ---------------------- |
||
2233 | --- Event Handlers --- |
||
2234 | ---------------------- |
||
2235 | |||
2236 | |||
2237 | ------------------- |
||
2238 | --- HoTT Itself --- |
||
2239 | ------------------- |
||
2240 | |||
2241 | |||
2242 | --- |
||
2243 | --- HoTT_MainFrame_OnLoad |
||
2244 | --- |
||
2245 | |||
2246 | function HoTT_MainFrame_OnLoad () |
||
2247 | |||
2248 | check_localized_slash_commands(); |
||
2249 | |||
2250 | init_preload_params(); |
||
2251 | restore_defaults(); |
||
2252 | hott_init(); |
||
2253 | |||
2254 | -- Register slash commands |
||
2255 | |||
2256 | SLASH_TARGETOFTARGET_TOTON1 = toton_string; |
||
2257 | SlashCmdList["TARGETOFTARGET_TOTON"] = function () |
||
2258 | hott_on(); |
||
2259 | end |
||
2260 | |||
2261 | SLASH_TARGETOFTARGET_TOTOFF1 = totoff_string; |
||
2262 | SlashCmdList["TARGETOFTARGET_TOTOFF"] = function () |
||
2263 | hott_off(); |
||
2264 | end |
||
2265 | |||
2266 | SLASH_TARGETOFTARGET_TOT1 = string_slash_tot; |
||
2267 | SLASH_TARGETOFTARGET_TOT2 = string_slash_hott; |
||
2268 | SlashCmdList["TARGETOFTARGET_TOT"] = function (command_string) |
||
2269 | command_dispatch(command_string); |
||
2270 | end |
||
2271 | |||
2272 | player_name = UnitName("player"); |
||
2273 | realm_name = GetCVar("realmName"); |
||
2274 | |||
2275 | |||
2276 | -- Register for events |
||
2277 | |||
2278 | this:RegisterEvent("VARIABLES_LOADED"); |
||
2279 | this:RegisterEvent("PLAYER_ENTERING_WORLD"); |
||
2280 | this:RegisterEvent("UNIT_NAME_UPDATE"); |
||
2281 | |||
2282 | this:RegisterEvent("PARTY_MEMBERS_CHANGED"); |
||
2283 | this:RegisterEvent("RAID_ROSTER_UPDATE"); |
||
2284 | |||
2285 | this:RegisterEvent("PLAYER_TARGET_CHANGED"); |
||
2286 | |||
2287 | this:RegisterEvent("UNIT_AURA"); |
||
2288 | |||
2289 | if(UltimateUI_RegisterButton) then |
||
2290 | UltimateUI_RegisterButton ( |
||
2291 | "TargetofTarget", |
||
2292 | "Params", |
||
2293 | "|cFF00CC00TargetOfTarget|r\nShows the target of the target! To use, type\n /tot on", |
||
2294 | "Interface\\Icons\\Spell_Holy_SealOfSalvation", |
||
2295 | launch_params_browser |
||
2296 | ); |
||
2297 | end |
||
2298 | |||
2299 | |||
2300 | --DEFAULT_CHAT_FRAME:AddMessage(loaded_string); |
||
2301 | |||
2302 | end |
||
2303 | |||
2304 | |||
2305 | |||
2306 | --- |
||
2307 | --- HoTT_MainFrame_OnEvent |
||
2308 | --- |
||
2309 | |||
2310 | function HoTT_MainFrame_OnEvent() |
||
2311 | |||
2312 | |||
2313 | if ( event == "VARIABLES_LOADED" ) then |
||
2314 | load_saved_variables(); |
||
2315 | end |
||
2316 | |||
2317 | |||
2318 | if ( not hott_is_on ) then |
||
2319 | |||
2320 | -- we shouldn't be doing anything else... |
||
2321 | |||
2322 | else |
||
2323 | |||
2324 | if ( ( event == "PLAYER_ENTERING_WORLD" ) or |
||
2325 | ( event == "UNIT_NAME_UPDATE" ) or |
||
2326 | ( event == "PARTY_MEMBERS_CHANGED" ) or |
||
2327 | ( event == "RAID_ROSTER_UPDATE" ) ) then |
||
2328 | |||
2329 | update_roster(); |
||
2330 | if ( update_bar_unit() ) then update_tot_health() end; |
||
2331 | |||
2332 | end |
||
2333 | |||
2334 | if ( ( event == "PLAYER_TARGET_CHANGED" ) or |
||
2335 | ( event == "PLAYER_ENTERING_WORLD" ) ) then |
||
2336 | dprint("PTC or PEW event"); |
||
2337 | update_tot(); |
||
2338 | position_display(); |
||
2339 | |||
2340 | end |
||
2341 | |||
2342 | if ( ( event == "UNIT_AURA" ) and ( arg1 == "target" ) ) then |
||
2343 | |||
2344 | position_display(); |
||
2345 | |||
2346 | end |
||
2347 | |||
2348 | end -- hott_is_on |
||
2349 | |||
2350 | end |
||
2351 | |||
2352 | |||
2353 | |||
2354 | --------------- |
||
2355 | --- Display --- |
||
2356 | --------------- |
||
2357 | |||
2358 | --- |
||
2359 | --- HoTT_Display_OnClick |
||
2360 | --- |
||
2361 | |||
2362 | function HoTT_Display_OnClick(button) |
||
2363 | |||
2364 | local name = tot_target_info.name; |
||
2365 | local unit = best_tot_unit(); |
||
2366 | |||
2367 | if ( button == "RightButton") then |
||
2368 | return; |
||
2369 | end |
||
2370 | |||
2371 | if ( button == "LeftButton" ) then |
||
2372 | |||
2373 | if ( SpellIsTargeting() and unit ) then |
||
2374 | SpellTargetUnit(unit); |
||
2375 | |||
2376 | elseif ( unit ) then |
||
2377 | TargetUnit(unit); |
||
2378 | |||
2379 | else |
||
2380 | better_target_by_name(name); -- think about glowy hand impact... |
||
2381 | |||
2382 | end |
||
2383 | |||
2384 | end -- LeftButton |
||
2385 | |||
2386 | end |
||
2387 | |||
2388 | |||
2389 | |||
2390 | --- |
||
2391 | --- reset_poll_timer |
||
2392 | --- |
||
2393 | |||
2394 | -- local |
||
2395 | function reset_poll_timer() |
||
2396 | |||
2397 | poll_timer = 0; |
||
2398 | poll_timer_fired = false; |
||
2399 | |||
2400 | return true; |
||
2401 | end |
||
2402 | |||
2403 | |||
2404 | |||
2405 | --- |
||
2406 | --- HoTT_Display_OnUpdate |
||
2407 | --- |
||
2408 | |||
2409 | function HoTT_Display_OnUpdate (interval) |
||
2410 | |||
2411 | if ( not UnitExists("target") ) then |
||
2412 | last_frame_tot = nil; |
||
2413 | reset_poll_timer(); |
||
2414 | this:Hide(); |
||
2415 | |||
2416 | else |
||
2417 | |||
2418 | poll_timer = poll_timer + interval; -- can be moved inside .unit test |
||
2419 | -- left here for debugging output |
||
2420 | |||
2421 | this_frame_tot = UnitName("targettarget"); |
||
2422 | |||
2423 | if ( this_frame_tot ~= last_frame_tot ) then -- fast, but... |
||
2424 | dprint("tot change"); |
||
2425 | update_tot(); |
||
2426 | |||
2427 | elseif ( ( not HoTT_Display_Bar.unit ) and |
||
2428 | ( UnitIsPlayer("target") or |
||
2429 | UnitAffectingCombat("target") ) ) then |
||
2430 | |||
2431 | -- Bar.unit take care of their own health and should have unique names |
||
2432 | -- Only players or in-combat NPCs can change health or targets |
||
2433 | |||
2434 | if ( ( poll_timer > params.poll_timer_period ) and |
||
2435 | ( not poll_timer_fired ) ) then |
||
2436 | |||
2437 | |||
2438 | elseif ( tot_target_info.player ) then |
||
2439 | dprint("player timeout"); |
||
2440 | update_tot_health(); |
||
2441 | |||
2442 | else |
||
2443 | dprint("NPC timeout") |
||
2444 | update_tot(); |
||
2445 | |||
2446 | end |
||
2447 | |||
2448 | poll_timer_fired = true; |
||
2449 | |||
2450 | end -- tot changed or Bar.unit exists |
||
2451 | |||
2452 | last_frame_tot = this_frame_tot; |
||
2453 | |||
2454 | end -- target exists |
||
2455 | |||
2456 | end |
||
2457 | |||
2458 | |||
2459 | |||
2460 | --- |
||
2461 | --- HoTT_Display_OnEvent |
||
2462 | --- |
||
2463 | |||
2464 | function HoTT_Display_OnEvent () |
||
2465 | |||
2466 | if ( UnitExists("target") and hott_is_on ) then |
||
2467 | this:Show(); |
||
2468 | else |
||
2469 | this:Hide(); |
||
2470 | end |
||
2471 | |||
2472 | end |
||
2473 | |||
2474 | |||
2475 | |||
2476 | |||
2477 | |||
2478 | ------------------ |
||
2479 | --- Health Bar --- |
||
2480 | ------------------ |
||
2481 | |||
2482 | |||
2483 | --- |
||
2484 | --- HoTT_Display_Bar_OnEvent |
||
2485 | --- |
||
2486 | |||
2487 | function HoTT_Display_Bar_OnEvent (event_arg1) |
||
2488 | |||
2489 | if (this.unit and ( event_arg1 == this.unit ) and hott_is_on ) then |
||
2490 | UnitFrameHealthBar_Update(this, this.unit) |
||
2491 | end |
||
2492 | |||
2493 | return true; |
||
2494 | end |
||
2495 | |||
2496 | |||
2497 | |||
2498 | --- |
||
2499 | --- HoTT_Display_Bar_OnValueChanged |
||
2500 | --- |
||
2501 | |||
2502 | function HoTT_Display_Bar_OnValueChanged (new_value) |
||
2503 | |||
2504 | if ( HoTT_Debug.BOVC and |
||
2505 | units_getting_events[this.unit] and |
||
2506 | ( time_since_bar_update > 0.001 ) ) then |
||
2507 | dprint(format("Bar update interval: %7.3f", time_since_bar_update)) |
||
2508 | end |
||
2509 | |||
2510 | HealthBar_OnValueChanged(new_value, true); |
||
2511 | time_since_bar_update = 0; |
||
2512 | bar_set_unreliable = false; |
||
2513 | |||
2514 | return true; |
||
2515 | end |
||
2516 | |||
2517 | |||
2518 | |||
2519 | --- |
||
2520 | --- HoTT_Display_Bar_OnUpdate |
||
2521 | --- |
||
2522 | |||
2523 | function HoTT_Display_Bar_OnUpdate (interval) |
||
2524 | |||
2525 | time_since_bar_update = time_since_bar_update + interval; |
||
2526 | |||
2527 | if ( ( not this.unit ) and |
||
2528 | ( time_since_bar_update > params.bar_unreliable_time ) and |
||
2529 | ( not bar_set_unreliable ) |
||
2530 | ) then |
||
2531 | this:SetStatusBarColor(colors.bar.unreliable.r, |
||
2532 | colors.bar.unreliable.g, |
||
2533 | colors.bar.unreliable.b); |
||
2534 | bar_set_unreliable = true; |
||
2535 | if ( type(bar_set_unreliable_callback) == "function" ) then |
||
2536 | bar_set_unreliable_callback(this); |
||
2537 | end |
||
2538 | |||
2539 | end |
||
2540 | |||
2541 | return true; |
||
2542 | end |
||
2543 | |||
2544 | |||
2545 | |||
2546 | -------------------------- |
||
2547 | --- Core functionality --- |
||
2548 | -------------------------- |
||
2549 | |||
2550 | --- NOTE: These need to be moved and made local, once confirmed working |
||
2551 | |||
2552 | --- |
||
2553 | --- update_tot_health |
||
2554 | --- |
||
2555 | |||
2556 | function update_tot_health () |
||
2557 | local now = GetTime(); |
||
2558 | local retval = UnitExists("targettarget"); |
||
2559 | |||
2560 | if ( retval ) then |
||
2561 | HoTT_Display_Bar:SetMinMaxValues(0, UnitHealthMax("targettarget")); |
||
2562 | HoTT_Display_Bar:SetValue(UnitHealth("targettarget")); |
||
2563 | if ( UnitIsCorpse("targettarget") or |
||
2564 | UnitIsDeadOrGhost("targettarget") ) then |
||
2565 | HoTT_Display_Dead:Show(); |
||
2566 | else |
||
2567 | HoTT_Display_Dead:Hide(); |
||
2568 | end |
||
2569 | end |
||
2570 | |||
2571 | reset_poll_timer(); |
||
2572 | tprint("update_tot_health", now); |
||
2573 | return retval; |
||
2574 | end |
||
2575 | |||
2576 | |||
2577 | |||
2578 | --- |
||
2579 | --- update_tot |
||
2580 | --- |
||
2581 | |||
2582 | function update_tot () |
||
2583 | local now = GetTime(); |
||
2584 | local retval; |
||
2585 | local may_be_stunned_mob; |
||
2586 | |||
2587 | if ( not UnitExists("target") ) then |
||
2588 | |||
2589 | dprint("No target to check"); |
||
2590 | |||
2591 | clear_t(); |
||
2592 | clear_tot(); |
||
2593 | clear_bar(); |
||
2594 | set_display_name_color(no_target_string, colors.name.normal); |
||
2595 | HoTT_Display_Bar:Hide(); |
||
2596 | |||
2597 | |||
2598 | elseif ( ( not UnitIsPlayer("target") ) and |
||
2599 | ( not UnitAffectingCombat("target") ) ) then |
||
2600 | |||
2601 | dprint("Non-aggro NPC"); |
||
2602 | |||
2603 | clear_t(); |
||
2604 | clear_tot(); |
||
2605 | clear_bar(); |
||
2606 | set_display_name_color(no_target_string, colors.name.normal); |
||
2607 | HoTT_Display_Bar:Hide(); |
||
2608 | |||
2609 | |||
2610 | elseif ( UnitIsUnit("target", "player") ) then |
||
2611 | |||
2612 | dprint("Self-target case"); |
||
2613 | |||
2614 | target_to_t(); |
||
2615 | self_to_tot(); |
||
2616 | if ( update_bar_unit() ) then update_tot_health() end; |
||
2617 | set_display_name_color(tot_target_info.name, colors.name.normal); |
||
2618 | HoTT_Display_Bar:Show(); |
||
2619 | |||
2620 | |||
2621 | else |
||
2622 | |||
2623 | -- Check stunned mob while we have "target" reliably |
||
2624 | |||
2625 | may_be_stunned_mob = ( ( not UnitIsPlayer("target") ) and |
||
2626 | ( UnitAffectingCombat("target") ) ); |
||
2627 | |||
2628 | -- then go ahead and do the check |
||
2629 | |||
2630 | if ( UnitExists("targettarget") ) then |
||
2631 | |||
2632 | target_to_t(); |
||
2633 | targettarget_to_tot(); |
||
2634 | if ( update_bar_unit() ) then update_tot_health() end; |
||
2635 | set_display_name_color(tot_target_info.name, colors.name.normal); |
||
2636 | HoTT_Display_Bar:Show(); |
||
2637 | |||
2638 | |||
2639 | |||
2640 | elseif ( may_be_stunned_mob ) then |
||
2641 | |||
2642 | if ( new_target_appears_same_as_before() ) then |
||
2643 | |||
2644 | dprint("Assuming stunned - same mob"); |
||
2645 | |||
2646 | -- and keep the old info |
||
2647 | -- NOTE THAT THIS DOES NOT UPDATE HEALTH BAR! |
||
2648 | |||
2649 | if ( roster[tot_target_info.name] ) then |
||
2650 | set_display_name_color(nil, colors.name.unreliable); |
||
2651 | else |
||
2652 | set_display_name_color(nil, colors.name.unreliable_no_unit); |
||
2653 | end |
||
2654 | |||
2655 | |||
2656 | else |
||
2657 | |||
2658 | dprint("Assuming stunned - new mob"); |
||
2659 | |||
2660 | set_display_name_color(stunned_string, |
||
2661 | colors.name.unreliable); |
||
2662 | |||
2663 | end |
||
2664 | |||
2665 | |||
2666 | else |
||
2667 | -- |
||
2668 | -- Target probably doesn't have a target (or is stunned PC) |
||
2669 | -- |
||
2670 | |||
2671 | dprint("No target of target found"); |
||
2672 | |||
2673 | target_to_t(); |
||
2674 | clear_tot(); |
||
2675 | clear_bar(); |
||
2676 | set_display_name_color(no_target_string, colors.name.normal); |
||
2677 | HoTT_Display_Bar:Hide(); |
||
2678 | |||
2679 | end |
||
2680 | |||
2681 | |||
2682 | end |
||
2683 | |||
2684 | if ( ( this_tot ) and |
||
2685 | ( this_tot == player_name ) and |
||
2686 | ( this_tot ~= last_tot ) and |
||
2687 | ( t_target_info.canattackme ) ) then |
||
2688 | |||
2689 | if ( params.aggro_message and |
||
2690 | string.find(params.aggro_message, "%S" ) ) then |
||
2691 | UIErrorsFrame:AddMessage(params.aggro_message, |
||
2692 | 1.0, 1.0, 1.0, 1.0, UIERRORS_HOLD_TIME); |
||
2693 | end |
||
2694 | |||
2695 | if ( type(HoTT_Aggro_Callback) == "function" ) then |
||
2696 | HoTT_Aggro_Callback(); |
||
2697 | end |
||
2698 | |||
2699 | end |
||
2700 | |||
2701 | reset_poll_timer(); |
||
2702 | tprint("update_tot", now); |
||
2703 | return tot_target_info; |
||
2704 | |||
2705 | end |
||
2706 | |||
2707 | |||
2708 | --------------------------------- |
||
2709 | --- Params Frame here for now --- |
||
2710 | --------------------------------- |
||
2711 | |||
2712 | |||
2713 | |||
2714 | --[[ |
||
2715 | |||
2716 | window_offset[ => ui.display.drops[ |
||
2717 | window_offset.right => ui.display.inset.right |
||
2718 | window_offset.left => ui.display.inset.left |
||
2719 | window_offset.object => ui.display.relative_to |
||
2720 | window_offset.scale => ui.display.scale |
||
2721 | name_alignment => ui.display.tot_name.alignment |
||
2722 | name_inset_left => ui.display.tot_name.inset.left |
||
2723 | name_inset_right => ui.display.tot_name.inset.right |
||
2724 | |||
2725 | |||
2726 | sign changes needed: |
||
2727 | |||
2728 | -window_offset[0] => ui.display.drops[0] |
||
2729 | -window_offset[1] => ui.display.drops[1] |
||
2730 | -window_offset[2] => ui.display.drops[2] |
||
2731 | -window_offset.right => ui.display.inset.right |
||
2732 | |||
2733 | |||
2734 | specials: |
||
2735 | |||
2736 | window_offset.text_offset: |
||
2737 | |||
2738 | "CENTER" => (ignore) |
||
2739 | "LEFT" => ui.display.tot_name.inset.left |
||
2740 | "RIGHT" => -ui.display.tot_name.inset.right |
||
2741 | |||
2742 | |||
2743 | |||
2744 | ]] |
||
2745 | |||
2746 | |||
2747 | |||
2748 | --- |
||
2749 | --- params_refresh |
||
2750 | --- |
||
2751 | |||
2752 | local function params_refresh () |
||
2753 | refresh_ui_positions(); |
||
2754 | |||
2755 | end |
||
2756 | |||
2757 | |||
2758 | |||
2759 | --- |
||
2760 | --- params_frame_int_check |
||
2761 | --- |
||
2762 | |||
2763 | local function params_frame_int_check (str, err_str) |
||
2764 | |||
2765 | local retval; |
||
2766 | |||
2767 | if ( string.find(str, "^-?%d+$") ) then |
||
2768 | retval = tonumber(str); |
||
2769 | |||
2770 | else |
||
2771 | message(string.format("%s must be an integer. Previous value restored.", |
||
2772 | err_str)); |
||
2773 | HoTT_Params_Frame_LoadValues(); |
||
2774 | retval = false; |
||
2775 | end |
||
2776 | |||
2777 | return retval; |
||
2778 | end |
||
2779 | |||
2780 | |||
2781 | |||
2782 | --- |
||
2783 | --- anw_check |
||
2784 | --- |
||
2785 | |||
2786 | local function anw_check (obj, dl, dr, tl, tr, field_name_string) |
||
2787 | |||
2788 | obj = getglobal(obj or params.ui.display.relative_to); |
||
2789 | dl = dl or params.ui.display.inset.left; |
||
2790 | dr = dr or params.ui.display.inset.right; |
||
2791 | tl = tl or params.ui.display.tot_name.inset.left; |
||
2792 | tr = tr or params.ui.display.tot_name.inset.right; |
||
2793 | |||
2794 | local retval; |
||
2795 | |||
2796 | if ( ( obj:GetRight() - obj:GetLeft() - dl - dr - tl - tr ) < |
||
2797 | params.ui.display.tot_name.min_width ) then |
||
2798 | |||
2799 | message(string.format(fmt_too_narrow, field_name_string)); |
||
2800 | HoTT_Params_Frame_LoadValues(); |
||
2801 | retval = false; |
||
2802 | |||
2803 | else |
||
2804 | retval = true; |
||
2805 | |||
2806 | end |
||
2807 | |||
2808 | return retval; |
||
2809 | end |
||
2810 | |||
2811 | |||
2812 | |||
2813 | --- |
||
2814 | --- HoTT_Params_Frame_LoadValues |
||
2815 | --- |
||
2816 | |||
2817 | function HoTT_Params_Frame_LoadValues () |
||
2818 | |||
2819 | local puid = params.ui.display; |
||
2820 | |||
2821 | HoTT_Params_Frame_ObjectName_EditBox:SetText(tostring(puid.relative_to)); |
||
2822 | |||
2823 | HoTT_Params_Frame_DisplayLeft_EditBox:SetText(tostring(puid.inset.left)); |
||
2824 | HoTT_Params_Frame_DisplayRight_EditBox:SetText(tostring(puid.inset.right)); |
||
2825 | HoTT_Params_Frame_TextLeft_EditBox:SetText( |
||
2826 | tostring(puid.tot_name.inset.left)); |
||
2827 | HoTT_Params_Frame_TextRight_EditBox:SetText( |
||
2828 | tostring(puid.tot_name.inset.right)); |
||
2829 | |||
2830 | HoTT_Params_Frame_ButtonLeft:SetChecked(false); |
||
2831 | HoTT_Params_Frame_ButtonCenter:SetChecked(false); |
||
2832 | HoTT_Params_Frame_ButtonRight:SetChecked(false); |
||
2833 | |||
2834 | if ( puid.tot_name.alignment == "CENTER" ) then |
||
2835 | HoTT_Params_Frame_ButtonCenter:SetChecked(true); |
||
2836 | |||
2837 | elseif ( puid.tot_name.alignment == "LEFT" ) then |
||
2838 | HoTT_Params_Frame_ButtonLeft:SetChecked(true); |
||
2839 | |||
2840 | elseif ( puid.tot_name.alignment == "RIGHT" ) then |
||
2841 | HoTT_Params_Frame_ButtonRight:SetChecked(true); |
||
2842 | |||
2843 | end |
||
2844 | |||
2845 | HoTT_Params_Frame_Scale_EditBox:SetText(format("%5.3f", puid.scale)); |
||
2846 | |||
2847 | HoTT_Params_Frame_Drop0_EditBox:SetText(tostring(puid.drops[0])); |
||
2848 | HoTT_Params_Frame_Drop1_EditBox:SetText(tostring(puid.drops[1])); |
||
2849 | HoTT_Params_Frame_Drop2_EditBox:SetText(tostring(puid.drops[2])); |
||
2850 | |||
2851 | |||
2852 | HoTT_Params_Frame_AggroMessage_EditBox:SetText(params.aggro_message); |
||
2853 | |||
2854 | end |
||
2855 | |||
2856 | |||
2857 | |||
2858 | |||
2859 | --- |
||
2860 | --- HoTT_Params_Frame_ObjectName_Changed |
||
2861 | --- |
||
2862 | |||
2863 | function HoTT_Params_Frame_ObjectName_Changed (new_text) |
||
2864 | |||
2865 | local obj = getglobal(new_text); |
||
2866 | |||
2867 | if ( not ( obj and |
||
2868 | ( type(obj.GetRight == "function") ) and |
||
2869 | ( type(obj.GetLeft == "function") ) |
||
2870 | ) |
||
2871 | ) then |
||
2872 | |||
2873 | message(string.format(fmt_no_obj_edit, new_text)); |
||
2874 | HoTT_Params_Frame_LoadValues(); |
||
2875 | refocus_object = HoTT_Params_Frame_ObjectName_EditBox; |
||
2876 | |||
2877 | elseif ( anw_check(new_text, nil, nil, nil, nil, "Relative-to object") |
||
2878 | ) then |
||
2879 | |||
2880 | params.ui.display.relative_to = new_text; |
||
2881 | params_refresh(); |
||
2882 | |||
2883 | else |
||
2884 | refocus_object = HoTT_Params_Frame_ObjectName_EditBox; |
||
2885 | |||
2886 | end |
||
2887 | |||
2888 | end |
||
2889 | |||
2890 | |||
2891 | |||
2892 | --- |
||
2893 | --- HoTT_Params_Frame_DisplayLeft_Changed |
||
2894 | --- |
||
2895 | |||
2896 | function HoTT_Params_Frame_DisplayLeft_Changed (new_string) |
||
2897 | |||
2898 | local new_number = params_frame_int_check(new_string, "Left display inset"); |
||
2899 | |||
2900 | if ( new_number and |
||
2901 | anw_check(nil, new_number, nil, nil, nil, "Left display inset") |
||
2902 | ) then |
||
2903 | params.ui.display.inset.left = new_number; |
||
2904 | params_refresh(); |
||
2905 | |||
2906 | else |
||
2907 | refocus_object = HoTT_Params_Frame_DisplayLeft_EditBox; |
||
2908 | |||
2909 | end |
||
2910 | |||
2911 | end |
||
2912 | |||
2913 | |||
2914 | |||
2915 | --- |
||
2916 | --- HoTT_Params_Frame_DisplayRight_Changed |
||
2917 | --- |
||
2918 | |||
2919 | function HoTT_Params_Frame_DisplayRight_Changed (new_string) |
||
2920 | |||
2921 | local new_number = params_frame_int_check(new_string,"Right display inset"); |
||
2922 | |||
2923 | if ( new_number and |
||
2924 | anw_check(nil, nil, new_number, nil, nil, "Right display inset" ) |
||
2925 | ) then |
||
2926 | params.ui.display.inset.right = new_number; |
||
2927 | params_refresh(); |
||
2928 | |||
2929 | else |
||
2930 | refocus_object = HoTT_Params_Frame_DisplayRight_EditBox; |
||
2931 | |||
2932 | end |
||
2933 | |||
2934 | end |
||
2935 | |||
2936 | |||
2937 | |||
2938 | --- |
||
2939 | --- HoTT_Params_Frame_TextLeft_Changed |
||
2940 | --- |
||
2941 | |||
2942 | function HoTT_Params_Frame_TextLeft_Changed (new_string) |
||
2943 | |||
2944 | local new_number = params_frame_int_check(new_string, "Left text inset"); |
||
2945 | |||
2946 | if ( new_number and |
||
2947 | anw_check(nil, nil, nil, new_number, nil, "Left text inset") |
||
2948 | ) then |
||
2949 | params.ui.display.tot_name.inset.left = new_number; |
||
2950 | params_refresh(); |
||
2951 | |||
2952 | else |
||
2953 | refocus_object = HoTT_Params_Frame_TextLeft_EditBox; |
||
2954 | |||
2955 | end |
||
2956 | |||
2957 | end |
||
2958 | |||
2959 | |||
2960 | |||
2961 | --- |
||
2962 | --- HoTT_Params_Frame_TextRight_Changed |
||
2963 | --- |
||
2964 | |||
2965 | function HoTT_Params_Frame_TextRight_Changed (new_string) |
||
2966 | |||
2967 | local new_number = params_frame_int_check(new_string, "Right text inset"); |
||
2968 | |||
2969 | if ( new_number and |
||
2970 | anw_check(nil, nil, nil, nil, new_number, "Right text inset" ) |
||
2971 | ) then |
||
2972 | params.ui.display.tot_name.inset.right = new_number; |
||
2973 | params_refresh(); |
||
2974 | |||
2975 | else |
||
2976 | refocus_object = HoTT_Params_Frame_TextRight_EditBox; |
||
2977 | |||
2978 | end |
||
2979 | |||
2980 | end |
||
2981 | |||
2982 | |||
2983 | |||
2984 | --- |
||
2985 | --- HoTT_Params_Frame_Alignment_Changed |
||
2986 | --- |
||
2987 | |||
2988 | function HoTT_Params_Frame_Alignment_Changed (new_alignment) |
||
2989 | |||
2990 | params.ui.display.tot_name.alignment = new_alignment; |
||
2991 | params_refresh(); |
||
2992 | |||
2993 | end |
||
2994 | |||
2995 | |||
2996 | |||
2997 | --- |
||
2998 | --- HoTT_Params_Frame_Scale_Changed |
||
2999 | --- |
||
3000 | |||
3001 | function HoTT_Params_Frame_Scale_Changed (new_string) |
||
3002 | |||
3003 | local new_number = tonumber(new_string); |
||
3004 | |||
3005 | if ( new_number and ( new_number > 0 ) ) then |
||
3006 | params.ui.display.scale = new_number; |
||
3007 | params_refresh(); |
||
3008 | |||
3009 | else |
||
3010 | message("Scale must be a positive value. Previous value restored."); |
||
3011 | HoTT_Params_Frame_LoadValues(); |
||
3012 | refocus_object = HoTT_Params_Frame_Scale_EditBox; |
||
3013 | retval = false; |
||
3014 | end |
||
3015 | |||
3016 | end |
||
3017 | |||
3018 | |||
3019 | |||
3020 | --- |
||
3021 | --- HoTT_Params_Frame_Drop0_Changed |
||
3022 | --- |
||
3023 | |||
3024 | function HoTT_Params_Frame_Drop0_Changed (new_string) |
||
3025 | |||
3026 | local new_number = params_frame_int_check(new_string, "No-buff drop"); |
||
3027 | |||
3028 | if ( new_number ) then |
||
3029 | params.ui.display.drops[0] = new_number; |
||
3030 | params_refresh(); |
||
3031 | |||
3032 | else |
||
3033 | refocus_object = HoTT_Params_Frame_Drop0_EditBox; |
||
3034 | |||
3035 | end |
||
3036 | |||
3037 | end |
||
3038 | |||
3039 | |||
3040 | |||
3041 | --- |
||
3042 | --- HoTT_Params_Frame_Drop1_Changed |
||
3043 | --- |
||
3044 | |||
3045 | function HoTT_Params_Frame_Drop1_Changed (new_string) |
||
3046 | |||
3047 | local new_number = params_frame_int_check(new_string, "First-row drop"); |
||
3048 | |||
3049 | if ( new_number ) then |
||
3050 | params.ui.display.drops[1] = new_number; |
||
3051 | params_refresh(); |
||
3052 | |||
3053 | else |
||
3054 | refocus_object = HoTT_Params_Frame_Drop1_EditBox; |
||
3055 | |||
3056 | end |
||
3057 | |||
3058 | end |
||
3059 | |||
3060 | |||
3061 | |||
3062 | --- |
||
3063 | --- HoTT_Params_Frame_Drop2_Changed |
||
3064 | --- |
||
3065 | |||
3066 | function HoTT_Params_Frame_Drop2_Changed (new_string) |
||
3067 | |||
3068 | local new_number = params_frame_int_check(new_string, "Second-row drop"); |
||
3069 | |||
3070 | if ( new_number ) then |
||
3071 | params.ui.display.drops[2] = new_number; |
||
3072 | params_refresh(); |
||
3073 | |||
3074 | else |
||
3075 | refocus_object = HoTT_Params_Frame_Drop2_EditBox; |
||
3076 | |||
3077 | end |
||
3078 | |||
3079 | end |
||
3080 | |||
3081 | |||
3082 | |||
3083 | --- |
||
3084 | --- HoTT_Params_Frame_AggroMessage_Changed |
||
3085 | --- |
||
3086 | |||
3087 | function HoTT_Params_Frame_AggroMessage_Changed (new_text) |
||
3088 | |||
3089 | params.aggro_message = new_text; |
||
3090 | params_refresh(); |
||
3091 | |||
3092 | end |
||
3093 | |||
3094 | |||
3095 | |||
3096 | --- |
||
3097 | --- launch_params_browser |
||
3098 | --- |
||
3099 | |||
3100 | -- local |
||
3101 | function launch_params_browser () |
||
3102 | |||
3103 | scratch_params = {}; |
||
3104 | |||
3105 | current_params = params; |
||
3106 | |||
3107 | set_deferral_recursively(scratch_params, params, |
||
3108 | "scratch_params", "current_params"); |
||
3109 | |||
3110 | params = scratch_params; |
||
3111 | HoTT_Params = scratch_params; |
||
3112 | |||
3113 | HoTT_Params_Frame:Show(); |
||
3114 | |||
3115 | end |
||
3116 | |||
3117 | |||
3118 | |||
3119 | --- |
||
3120 | --- HoTT_Params_Frame_OnCancel |
||
3121 | --- |
||
3122 | |||
3123 | function HoTT_Params_Frame_OnCancel () |
||
3124 | |||
3125 | HoTT_Params_Frame_LoadValues(); -- to prevent error messaging |
||
3126 | PlaySound("gsTitleOptionExit"); |
||
3127 | HideUIPanel(HoTT_Params_Frame); |
||
3128 | |||
3129 | params = current_params; |
||
3130 | HoTT_Params = current_params; |
||
3131 | |||
3132 | params_refresh(); |
||
3133 | |||
3134 | end |
||
3135 | |||
3136 | |||
3137 | |||
3138 | --- |
||
3139 | --- HoTT_Params_Frame_OnDefaults |
||
3140 | --- |
||
3141 | |||
3142 | function HoTT_Params_Frame_OnDefaults () |
||
3143 | |||
3144 | params.aggro_message = default_params.aggro_message; |
||
3145 | |||
3146 | -- copy_table_recursively(default_params.ui, params.ui); |
||
3147 | -- fails as default_params is write-locked and can't be iterated over |
||
3148 | |||
3149 | local dpuid = default_params.ui.display; |
||
3150 | local puid = params.ui.display; |
||
3151 | |||
3152 | puid.relative_to = dpuid.relative_to; |
||
3153 | puid.scale = dpuid.scale; |
||
3154 | puid.inset.left = dpuid.inset.left; |
||
3155 | puid.inset.right = dpuid.inset.right; |
||
3156 | puid.drops[0] = dpuid.drops[0]; |
||
3157 | puid.drops[1] = dpuid.drops[1]; |
||
3158 | puid.drops[2] = dpuid.drops[2]; |
||
3159 | puid.tot_name.alignment = dpuid.tot_name.alignment; |
||
3160 | puid.tot_name.inset.left = dpuid.tot_name.inset.left; |
||
3161 | puid.tot_name.inset.right = dpuid.tot_name.inset.right; |
||
3162 | |||
3163 | |||
3164 | HoTT_Params_Frame_LoadValues(); |
||
3165 | |||
3166 | params_refresh(); |
||
3167 | |||
3168 | end |
||
3169 | |||
3170 | |||
3171 | |||
3172 | --- |
||
3173 | --- HoTT_Params_Frame_OnOkay |
||
3174 | --- |
||
3175 | |||
3176 | function HoTT_Params_Frame_OnOkay () |
||
3177 | |||
3178 | --- |
||
3179 | --- Can't blindly accept and close! |
||
3180 | --- |
||
3181 | |||
3182 | HoTT_Params_Frame_ClearFocus(); |
||
3183 | |||
3184 | if ( refocus_object ) then |
||
3185 | refocus_object:SetFocus(); |
||
3186 | refocus_object = nil; |
||
3187 | |||
3188 | else |
||
3189 | |||
3190 | |||
3191 | if ( current_params.aggro_message ~= params.aggro_message ) then |
||
3192 | current_params.aggro_message = params.aggro_message; |
||
3193 | else |
||
3194 | current_params.aggro_message = nil; -- defer to defaults |
||
3195 | end |
||
3196 | |||
3197 | local puid = params.ui.display; |
||
3198 | local cpuid = current_params.ui.display; |
||
3199 | local dpuid = default_params.ui.display; |
||
3200 | |||
3201 | |||
3202 | if ( ( puid.relative_to ~= dpuid.relative_to ) or |
||
3203 | ( puid.scale ~= dpuid.scale ) or |
||
3204 | ( puid.inset.left ~= dpuid.inset.left ) or |
||
3205 | ( puid.inset.right ~= dpuid.inset.right ) or |
||
3206 | ( puid.drops[0] ~= dpuid.drops[0] ) or |
||
3207 | ( puid.drops[1] ~= dpuid.drops[1] ) or |
||
3208 | ( puid.drops[2] ~= dpuid.drops[2] ) or |
||
3209 | ( puid.tot_name.alignment ~= dpuid.tot_name.alignment ) or |
||
3210 | ( puid.tot_name.inset.left ~= dpuid.tot_name.inset.left ) or |
||
3211 | ( puid.tot_name.inset.right ~= dpuid.tot_name.inset.right ) |
||
3212 | ) then |
||
3213 | |||
3214 | cpuid.relative_to = puid.relative_to; |
||
3215 | cpuid.scale = puid.scale; |
||
3216 | cpuid.inset.left = puid.inset.left; |
||
3217 | cpuid.inset.right = puid.inset.right; |
||
3218 | cpuid.drops[0] = puid.drops[0]; |
||
3219 | cpuid.drops[1] = puid.drops[1]; |
||
3220 | cpuid.drops[2] = puid.drops[2]; |
||
3221 | cpuid.tot_name.alignment = puid.tot_name.alignment; |
||
3222 | cpuid.tot_name.inset.left = puid.tot_name.inset.left; |
||
3223 | cpuid.tot_name.inset.right = puid.tot_name.inset.right; |
||
3224 | |||
3225 | else |
||
3226 | |||
3227 | current_params.ui = nil; -- defer to defaults |
||
3228 | |||
3229 | end |
||
3230 | |||
3231 | PlaySound("gsTitleOptionOK"); |
||
3232 | HideUIPanel(HoTT_Params_Frame); |
||
3233 | |||
3234 | |||
3235 | params = current_params; |
||
3236 | HoTT_Params = current_params; |
||
3237 | |||
3238 | end |
||
3239 | |||
3240 | params_refresh(); |
||
3241 | |||
3242 | end |
||
3243 | |||
3244 | |||
3245 | |||
3246 | --- |
||
3247 | --- HoTT_Params_Frame_ClearFocus |
||
3248 | --- |
||
3249 | |||
3250 | function HoTT_Params_Frame_ClearFocus () |
||
3251 | |||
3252 | HoTT_Params_Frame_ObjectName_EditBox:ClearFocus(); |
||
3253 | HoTT_Params_Frame_DisplayLeft_EditBox:ClearFocus(); |
||
3254 | HoTT_Params_Frame_DisplayRight_EditBox:ClearFocus(); |
||
3255 | HoTT_Params_Frame_TextLeft_EditBox:ClearFocus(); |
||
3256 | HoTT_Params_Frame_TextRight_EditBox:ClearFocus(); |
||
3257 | HoTT_Params_Frame_Scale_EditBox:ClearFocus(); |
||
3258 | HoTT_Params_Frame_Drop0_EditBox:ClearFocus(); |
||
3259 | HoTT_Params_Frame_Drop1_EditBox:ClearFocus(); |
||
3260 | HoTT_Params_Frame_Drop2_EditBox:ClearFocus(); |
||
3261 | HoTT_Params_Frame_AggroMessage_EditBox:ClearFocus(); |
||
3262 | |||
3263 | end |
||
3264 | |||
3265 | |||
3266 | |||
3267 | --- |
||
3268 | --- HoTT_Params_Frame_CheckRefocus |
||
3269 | --- |
||
3270 | |||
3271 | function HoTT_Params_Frame_CheckRefocus () |
||
3272 | |||
3273 | if ( refocus_object ) then |
||
3274 | refocus_object:SetFocus(); |
||
3275 | refocus_object = nil; |
||
3276 | end |
||
3277 | |||
3278 | end |