· 9 years ago · Nov 24, 2016, 06:38 AM
1--[[
2 Author: grasmann
3
4 Injects custom options into menus
5--]]
6
7CreateModSettings = function()
8 local options_view = Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui.views.options_view
9 local settings_lists = Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui.views.options_view.settings_lists
10 local title_buttons = Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui.views.options_view.title_buttons
11 local ui_scenegraph = Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui.views.options_view.ui_scenegraph
12
13 options_view.title_buttons_n = 7
14
15 settings_lists.mod_settings = {
16 widgets = {},
17 visible_widgets_n = 0,
18 widgets_n = 0,
19 scenegraph_id_start = "mod_settings_liststart",
20 scrollbar = false,
21 scenegraph_id = "mod_settings_list",
22 max_offset_y = 0,
23 }
24
25 if #title_buttons > 6 then table.remove(title_buttons, 7) end
26 local definition = UIWidget.init(UIWidgets.create_menu_button("settings_view_mod", "mod_settings_button", true))
27
28 definition.content.button_hotspot = {
29 on_double_click = false,
30 is_clicked = 2.6799300023354595,
31 is_selected = false,
32 input_pressed = false,
33 on_release = false,
34 on_right_click = false,
35 cursor_hover = false,
36 disable_button = false,
37 parent = {},
38 }
39 definition.content.button_hotspot.parent = definition.content
40 definition.style.text_disabled.localize = false
41 definition.style.text_click.localize = false
42 definition.style.text_hover.localize = false
43 definition.style.text_selected.localize = false
44 definition.style.text.localize = false
45 definition.animations = table.clone(title_buttons[6].animations)
46 definition.content.text_field = "Mod Settings"
47 title_buttons[7] = definition
48
49 --table.insert(options_view.ui_scenegraph, "mod_settings_button" = {})
50 --options_view.ui_scenegraph["mod_settings_button"] = {}
51 --options_view.ui_scenegraph[#options_view.ui_scenegraph+1] = {"mod_settings_button"}
52 --options_view.ui_scenegraph["mod_settings_button"] = {}
53
54 --ui_scenegraph.["mod_settings_button"]
55
56 rawset(ui_scenegraph, "mod_settings_button", "")
57 ui_scenegraph.mod_settings_button = {
58 position = {
59 0,
60 -100,
61 1,
62 },
63 parent = "gamepad_settings_button",
64 vertical_alignment = "top",
65 world_position = {
66 289,
67 306,
68 519,
69 },
70 size = {
71 318,
72 84,
73 },
74 name = "mod_settings_button",
75 local_position = {
76 0,
77 -100,
78 1,
79 },
80 horizontal_alignment = "center",
81 }
82
83 rawset(ui_scenegraph, "mod_settings_list", "")
84 ui_scenegraph.mod_settings_list = {
85 position = {
86 0,
87 0,
88 -1,
89 },
90 children = {
91 },
92 parent = "list_mask",
93 vertical_alignment = "top",
94 num_children = 1,
95 offset = {
96 0,
97 0,
98 0,
99 },
100 world_position = {
101 1199,
102 80,
103 515,
104 },
105 size = {
106 840,
107 1150,
108 },
109 horizontal_alignment = "center",
110 local_position = {
111 0,
112 0,
113 -1,
114 },
115 name = "mod_settings_list",
116 }
117
118 rawset(ui_scenegraph, "mod_settings_liststart", "")
119 ui_scenegraph.mod_settings_liststart = {
120 world_position = {
121 1229,
122 80,
123 525,
124 },
125 horizontal_alignment = "left",
126 position = {
127 30,
128 0,
129 10,
130 },
131 local_position = {
132 30,
133 0,
134 10,
135 },
136 name = "mod_settings_liststart",
137 size = {
138 1,
139 1,
140 },
141 parent = "mod_settings_list",
142 vertical_alignment = "top",
143 }
144
145 --options_view.ui_scenegraph.mod_settings_list.num_children = 1
146 ui_scenegraph.mod_settings_list.children[1] = ui_scenegraph.mod_settings_liststart
147 --table.insert(options_view.ui_scenegraph.mod_settings_list.children, mod_settings_liststart)
148 ui_scenegraph.mod_settings_button.world_position[2] = options_view.ui_scenegraph.gamepad_settings_button.world_position[2] - 100
149
150 ui_scenegraph.gamepad_settings_button.num_children = 1
151 ui_scenegraph.gamepad_settings_button.children = {}
152 ui_scenegraph.gamepad_settings_button.children[1] = ui_scenegraph.mod_settings_button
153
154 ui_scenegraph.list_mask.children[8] = {
155 position = {
156 0,
157 0,
158 -1,
159 },
160 children = {},
161 parent = "list_mask",
162 vertical_alignment = "top",
163 num_children = 1,
164 offset = {
165 0,
166 0,
167 0,
168 },
169 world_position = {
170 1199,
171 80,
172 515,
173 },
174 size = {
175 840,
176 2350,
177 },
178 horizontal_alignment = "center",
179 local_position = {
180 0,
181 0,
182 -1,
183 },
184 name = "mod_settings_list",
185 }
186
187 ui_scenegraph.list_mask.children[8].children[1] = ui_scenegraph.mod_settings_liststart
188 ui_scenegraph.list_mask.num_children = 8
189
190 if not table.has_item(SettingsMenuNavigation, "mod_settings") then
191 SettingsMenuNavigation[#SettingsMenuNavigation+1] = "mod_settings"
192 end
193
194end
195
196NewStepperWidget = function(text, options, selected_option, tooltip_text, name, settings)
197 -- ##### Declare some shit ####################################################################################
198 local options_texts = {}
199 local options_values = {}
200 local base_offset = settings.offset.value
201 local scenegraph_id = settings.list_start
202 local num_options = #options
203 local STEPPER_WIDGET_SIZE = {
204 795,
205 50,
206 }
207
208 -- ##### Put options into objects #############################################################################
209 for i = 1, num_options, 1 do
210 options_texts[i] = options[i].text
211 options_values[i] = options[i].value
212 end
213
214 -- ##### Create widget ########################################################################################
215 base_offset[2] = base_offset[2] - STEPPER_WIDGET_SIZE[2]
216 local definition = {
217 element = {
218 passes = {
219 {
220 pass_type = "local_offset",
221 offset_function = function (ui_scenegraph, ui_style, ui_content, ui_renderer)
222 local selection_text = ui_content.options_texts[ui_content.current_selection]
223
224 if selection_text ~= ui_content.selection_text then
225 ui_content.selection_text = selection_text
226 end
227
228 return
229 end,
230 },
231 {
232 style_id = "left_arrow_hotspot",
233 pass_type = "hotspot",
234 content_id = "left_hotspot",
235 },
236 {
237 style_id = "right_arrow_hotspot",
238 pass_type = "hotspot",
239 content_id = "right_hotspot",
240 },
241 {
242 pass_type = "hotspot",
243 content_id = "highlight_hotspot",
244 },
245 {
246 pass_type = "texture",
247 style_id = "highlight_texture",
248 texture_id = "highlight_texture",
249 content_check_function = function (content)
250 return content.is_highlighted
251 end,
252 },
253 {
254 style_id = "tooltip_text",
255 pass_type = "tooltip_text",
256 text_id = "tooltip_text",
257 content_check_function = function (ui_content)
258 return ui_content.tooltip_text and ui_content.highlight_hotspot.is_hover
259 end,
260 },
261 {
262 pass_type = "local_offset",
263 offset_function = function (ui_scenegraph, ui_style, ui_content, ui_renderer)
264 local left_hotspot = ui_content.left_hotspot
265 local right_hotspot = ui_content.right_hotspot
266
267 if left_hotspot.on_hover_enter then
268 ui_content.on_hover_enter_callback("left_arrow_hover")
269 end
270
271 if left_hotspot.on_hover_exit then
272 ui_content.on_hover_exit_callback("left_arrow_hover")
273 end
274
275 if left_hotspot.on_release then
276 ui_content.on_pressed_callback("left_arrow", ui_content)
277 ui_content.on_pressed_callback("left_arrow_hover", ui_content)
278 end
279
280 if right_hotspot.on_hover_enter then
281 ui_content.on_hover_enter_callback("right_arrow_hover")
282 end
283
284 if right_hotspot.on_hover_exit then
285 ui_content.on_hover_exit_callback("right_arrow_hover")
286 end
287
288 if right_hotspot.on_release then
289 ui_content.on_pressed_callback("right_arrow", ui_content)
290 ui_content.on_pressed_callback("right_arrow_hover", ui_content)
291 end
292
293 if left_hotspot.is_hover or right_hotspot.is_hover then
294 ui_style.selection_text.text_color = ui_style.selection_text.highlight_color
295 else
296 ui_style.selection_text.text_color = ui_style.selection_text.default_color
297 end
298
299 return
300 end,
301 },
302 {
303 style_id = "text",
304 pass_type = "text",
305 text_id = "text",
306 },
307 {
308 pass_type = "texture",
309 style_id = "left_arrow",
310 texture_id = "left_arrow",
311 },
312 {
313 pass_type = "rotated_texture",
314 style_id = "right_arrow",
315 texture_id = "right_arrow",
316 },
317 {
318 pass_type = "texture",
319 style_id = "left_arrow_hover",
320 texture_id = "left_arrow_hover",
321 },
322 {
323 pass_type = "rotated_texture",
324 style_id = "right_arrow_hover",
325 texture_id = "right_arrow_hover",
326 },
327 {
328 style_id = "selection_text",
329 pass_type = "text",
330 text_id = "selection_text",
331 content_check_function = function (content)
332 local selection_text = content.selection_text
333
334 return selection_text and selection_text ~= ""
335 end,
336 },
337 {
338 pass_type = "rect",
339 content_check_function = function (content)
340 --return DEBUG_WIDGETS
341 end,
342 },
343 {
344 pass_type = "border",
345 content_check_function = function (content, style)
346 -- if DEBUG_WIDGETS then
347 -- style.thickness = 1
348 -- end
349
350 -- return DEBUG_WIDGETS
351 end,
352 },
353 {
354 style_id = "debug_middle_line",
355 pass_type = "rect",
356 content_check_function = function (content)
357 --return DEBUG_WIDGETS
358 end,
359 },
360 },
361 pass_data = {},
362 },
363 content = {
364 left_arrow = "settings_arrow_normal",
365 right_arrow_hover = "settings_arrow_clicked",
366 selection_text = "Off",
367 left_arrow_hover = "settings_arrow_clicked",
368 highlight_texture = "playerlist_hover",
369 right_arrow = "settings_arrow_normal",
370 left_hotspot = {
371 is_clicked = 11.947660636622457,
372 on_right_click = false,
373 on_double_click = false,
374 cursor_hover = false,
375 on_release = false,
376 disable_button = true,
377 parent = {},
378 },
379 right_hotspot = {
380 is_clicked = 11.947660636622457,
381 on_right_click = false,
382 on_double_click = false,
383 cursor_hover = false,
384 on_release = false,
385 disable_button = true,
386 parent = {},
387 },
388 highlight_hotspot = {
389 is_clicked = 11.947660636622457,
390 on_right_click = false,
391 on_double_click = false,
392 cursor_hover = false,
393 on_release = false,
394 disable_button = false,
395 parent = {},
396 },
397 text = text,
398 tooltip_text = tooltip_text,
399 current_selection = selected_option,
400 options_texts = options_texts,
401 options_values = options_values,
402 num_options = num_options,
403 hotspot_content_ids = {
404 "left_hotspot",
405 "right_hotspot"
406 },
407 saved_value_cb = function(widget)
408 for i=1, #widget.content.options_values do
409 if widget.content.options_values[i] == Application.user_setting(widget.content.name) then
410 widget.content.current_selection = i
411 break
412 end
413 end
414 end,
415 on_pressed_callback = function(arrow, content)
416 end,
417 on_hover_enter_callback = function()
418 end,
419 on_hover_exit_callback = function()
420 end,
421 visible = true,
422 default_value = selected_option,
423 callback = function(content)
424 local options_view = Managers.player.network_manager.matchmaking_manager.matchmaking_ui.ingame_ui.views.options_view
425 options_view.changed_user_settings[content.name] = content.options_values[content.current_selection]
426 end,
427 name = name,
428 },
429 style = {
430 offset = table.clone(base_offset),
431 size = table.clone(STEPPER_WIDGET_SIZE),
432 highlight_texture = {
433 masked = true,
434 offset = {
435 base_offset[1],
436 base_offset[2],
437 base_offset[3],
438 },
439 color = Colors.get_table("white"),
440 size = {
441 STEPPER_WIDGET_SIZE[1],
442 STEPPER_WIDGET_SIZE[2],
443 },
444 },
445 tooltip_text = {
446 font_size = 24,
447 max_width = 600,
448 localize = false,
449 horizontal_alignment = "left",
450 vertical_alignment = "top",
451 font_type = "hell_shark",
452 text_color = Colors.get_color_table_with_alpha("white", 255),
453 line_colors = {
454 Colors.get_color_table_with_alpha("cheeseburger", 255),
455 },
456 offset = {
457 0,
458 0,
459 base_offset[3] + 20,
460 },
461 },
462 left_arrow = {
463 masked = true,
464 offset = {
465 base_offset[1] + 520,
466 base_offset[2] + 5 + 2,
467 base_offset[3],
468 },
469 size = {
470 28,
471 34,
472 },
473 color = {
474 255,
475 255,
476 255,
477 255,
478 },
479 },
480 left_arrow_hover = {
481 masked = true,
482 offset = {
483 base_offset[1] + 520,
484 base_offset[2] + 5 + 2,
485 base_offset[3],
486 },
487 size = {
488 28,
489 34,
490 },
491 color = {
492 0,
493 255,
494 255,
495 255,
496 },
497 },
498 left_arrow_hotspot = {
499 offset = {
500 base_offset[1] + 520,
501 base_offset[2] + 5 + 2,
502 base_offset[3],
503 },
504 size = {
505 129,
506 34,
507 },
508 },
509 right_arrow = {
510 masked = true,
511 offset = {
512 base_offset[1] + 750,
513 base_offset[2] + 5 + 2,
514 base_offset[3],
515 },
516 size = {
517 28,
518 34,
519 },
520 color = {
521 255,
522 255,
523 255,
524 255,
525 },
526 angle = math.pi,
527 pivot = {
528 14,
529 17,
530 },
531 },
532 right_arrow_hover = {
533 masked = true,
534 offset = {
535 base_offset[1] + 750,
536 base_offset[2] + 5 + 2,
537 base_offset[3],
538 },
539 size = {
540 28,
541 34,
542 },
543 color = {
544 0,
545 255,
546 255,
547 255,
548 },
549 angle = math.pi,
550 pivot = {
551 14,
552 17,
553 },
554 },
555 right_arrow_hotspot = {
556 offset = {
557 (base_offset[1] + 750) - 101,
558 base_offset[2] + 5 + 2,
559 base_offset[3],
560 },
561 size = {
562 129,
563 34,
564 },
565 },
566 text = {
567 font_type = "hell_shark_masked",
568 dynamic_font = true,
569 localize = false,
570 font_size = 28,
571 offset = {
572 base_offset[1] + 2,
573 base_offset[2] + 5,
574 base_offset[3],
575 },
576 text_color = Colors.get_color_table_with_alpha("white", 255),
577 },
578 selection_text = {
579 dynamic_font = true,
580 font_size = 24,
581 font_type = "hell_shark_masked",
582 horizontal_alignment = "center",
583 offset = {
584 base_offset[1] + 650,
585 base_offset[2] + 6,
586 base_offset[3],
587 },
588 text_color = Colors.get_color_table_with_alpha("cheeseburger", 255),
589 highlight_color = Colors.get_color_table_with_alpha("white", 255),
590 default_color = Colors.get_color_table_with_alpha("cheeseburger", 255),
591 },
592 debug_middle_line = {
593 offset = {
594 base_offset[1],
595 (base_offset[2] + STEPPER_WIDGET_SIZE[2]/2) - 1,
596 base_offset[3] + 10,
597 },
598 size = {
599 STEPPER_WIDGET_SIZE[1],
600 2,
601 },
602 color = {
603 200,
604 0,
605 255,
606 0,
607 },
608 },
609 color = {
610 50,
611 255,
612 255,
613 255,
614 },
615 },
616 scenegraph_id = scenegraph_id,
617 ["type"] = "stepper",
618 ui_animations = {},
619 animations = {},
620 style_global = {},
621 name = name,
622 }
623
624 -- ##### Set references and text ids ##########################################################################
625 definition.element.pass_data[8] = {text_id = "text"}
626 definition.element.pass_data[13] = {text_id = "selection_text"}
627 definition.element.pass_data[6] = {text_id = "tooltip_text"}
628 definition.content.highlight_hotspot.parent = definition.content
629 definition.content.right_hotspot.parent = definition.content
630 definition.content.left_hotspot.parent = definition.content
631
632 -- ##### Add widget to desired options view ###################################################################
633 if settings.view ~= nil then
634 settings.view.widgets[#settings.view.widgets+1] = definition
635 settings.view.widgets_n = #settings.view.widgets
636 settings.view.max_offset_y = settings.view.max_offset_y + 50
637 settings.view.visible_widgets_n = settings.view.widgets_n
638 if settings.view.visible_widgets_n > 16 then settings.view.visible_widgets_n = 16 end
639 end
640
641 return definition
642end
643
644-- ####################################################################################################################
645-- ##### OptionsInjector ##############################################################################################
646-- ####################################################################################################################
647OptionsInjector = {
648
649 initialized = false,
650
651 -- ##### Gameplay settings manager ################################################################################
652 GameplaySettings = {
653 view = {},
654 max_offset_y = {},
655 offset = {
656 base = {
657 0,
658 -1150,
659 0,
660 },
661 value = {},
662 },
663 queue = {},
664 cache = {},
665 list_start = "gameplay_settings_liststart",
666 name = "Gameplay",
667 },
668 ModSettings = {
669 view = {},
670 max_offset_y = 0,
671 offset = {
672 base = {
673 0,
674 0,
675 0,
676 },
677 value = {
678 0,
679 0,
680 0,
681 },
682 },
683 queue = {},
684 cache = {},
685 list_start = "mod_settings_liststart",
686 name = "Mod",
687 },
688
689 HasOption = function(name, settings)
690 if settings then
691 for _, option in ipairs(settings.cache) do
692 if option.name == name then
693 return true
694 end
695 end
696 for _, option in ipairs(settings.queue) do
697 if option.name == name then
698 return true
699 end
700 end
701 end
702 return false
703 end,
704
705 GetWidgetIndex = function(name, settings)
706 for i=1, #settings.view.widgets do
707 local widget = settings.view.widgets[i]
708 if widget.name == name then
709 return i
710 end
711 end
712 return 0
713 end,
714
715 CreateStepperWidget = function(name, text, options, selected_option, tooltip_text, settings)
716 if not OptionsInjector.HasOption(name, settings) then
717 if OptionsInjector.initialized then
718 -- ##### Insert option into menu ######################################################################
719 NewStepperWidget(text, options, selected_option, tooltip_text, name, settings)
720 settings.max_offset_y = settings.view.max_offset_y
721 -- ##### Insert option into cache #####################################################################
722 settings.cache[#settings.cache + 1] = {
723 name = name,
724 text = text,
725 options = options,
726 selected_option = selected_option,
727 tooltip_text = tooltip_text,
728 }
729 EchoConsole("Option " .. name .. " added to " .. settings.name .. " cache")
730 else
731 -- ##### Insert option into queue #####################################################################
732 settings.queue[#settings.queue + 1] = {
733 name = name,
734 text = text,
735 options = options,
736 selected_option = selected_option,
737 tooltip_text = tooltip_text,
738 }
739 EchoConsole("Option " .. name .. " added to " .. settings.name .. " queue")
740 Mods.debug.object.draw(settings.queue, "settings.queue", 5)
741 end
742 else
743 EchoConsole("Option " .. name .. " already exists in " .. settings.name)
744 end
745 end,
746
747 CreateEmptyLine = function(settings)
748 if OptionsInjector.initialized then
749 settings.max_offset_y = settings.max_offset_y + 50
750 end
751 end,
752
753}
754
755-- ####################################################################################################################
756-- ##### Hook IngameUI.init ###########################################################################################
757-- ####################################################################################################################
758--[[
759 Hook to make sure the ingame ui is loaded because we need a reference
760--]]
761if not IngameUI_update then
762 IngameUI_update = IngameUI.update
763end
764IngameUI.update = function(self, dt, t, disable_ingame_ui, end_of_level_ui)
765 IngameUI_update(self, dt, t, disable_ingame_ui, end_of_level_ui)
766
767 if not OptionsInjector.initialized then
768 EchoConsole("Initializing options injector")
769
770 -- local status, err = pcall(CreateModSettings)
771 -- if err ~= nil then
772 -- EchoConsole(err)
773 -- end
774 CreateModSettings()
775
776 OptionsInjector.GameplaySettings.view = self.views.options_view.settings_lists.gameplay_settings
777 OptionsInjector.GameplaySettings.offset.value = table.clone(OptionsInjector.GameplaySettings.offset.base)
778 OptionsInjector.GameplaySettings.max_offset_y = self.views.options_view.settings_lists.gameplay_settings.max_offset_y
779 OptionsInjector.ModSettings.view = self.views.options_view.settings_lists.mod_settings
780
781 for _, settings in ipairs(OptionsInjector) do
782 if type(settings) == "table" then
783 EchoConsole("Loading " .. settings.name .. " queue")
784 for __, elem in ipairs(settings.queue) do
785 NewStepperWidget(elem.text, elem.options, elem.selected_option, elem.tooltip_text, elem.name, settings)
786 end
787 settings.queue = {}
788 for __, elem in ipairs(settings.cache) do
789 NewStepperWidget(elem.text, elem.options, elem.selected_option, elem.tooltip_text, elem.name, settings)
790 end
791 else
792 EchoConsole("No table")
793 end
794 end
795
796 OptionsInjector.initialized = true
797 end
798end
799
800-- ####################################################################################################################
801-- ##### Hook StateInGameRunning.create_ingame_ui #####################################################################
802-- ####################################################################################################################
803--[[
804 Hook to recreate options when ui is recreated
805--]]
806if not StateInGameRunning_create_ingame_ui then
807 StateInGameRunning_create_ingame_ui = StateInGameRunning.create_ingame_ui
808end
809StateInGameRunning.create_ingame_ui = function(self, ingame_ui_context)
810 StateInGameRunning_create_ingame_ui(self, ingame_ui_context)
811
812 -- ##### Create options in queue #########
813 if OptionsInjector.initialized then
814 OptionsInjector.initialized = false
815 end
816
817end