Skip to content

Instantly share code, notes, and snippets.

@sclu1034
Last active October 15, 2018 09:04
Show Gist options
  • Save sclu1034/da413f16c904cb1162103401a483cc2c to your computer and use it in GitHub Desktop.
Save sclu1034/da413f16c904cb1162103401a483cc2c to your computer and use it in GitHub Desktop.
-- The file that defines `MyModView`
dofile("scripts/mods/my_mod/view/my_mod_view")
local view_data = {
-- Any name may be chosen, but it has to be unique among all registered views
view_name = "my_mod_view",
view_settings = {
init_view_function = function (ingame_ui_context)
return MyModView:new(ingame_ui_context)
end,
active = {
inn = true,
ingame = false,
},
-- There is no check for `nil` in `mod:register_new_views`, so even if empty, these have to be defined
blocked_transitions = {
inn = {},
ingame = {},
},
-- `settings_id`/`setting_name` which defines the keybind
hotkey_name = "settings_id",
-- has to be same value as the keybind setting's `action_name`
hotkey_action_name = "open_my_mod_view",
-- Some name that has to match with the key in `view_transitions`
hotkey_transition_name = "my_mod_view",
},
view_transitions = {
my_mod_view = function (self)
-- Should match with `view_data.view_name`
self.current_view = "my_mod_view"
end,
}
}
mod:register_new_view(view_data)
-- File that defines scenegraph and widgets
local definitions = dofile("scripts/mods/my_mod/view/my_mod_view_definitions")
local scenegraph_definition = definitions.scenegraph_definition
local console_cursor_definition = definitions.console_cursor_definition
local widget_definitions = definitions.widgets
local generic_input_actions = definitions.generic_input_actions
-- The class that defines the view and it's behavior. Needs to provide pretty much the same API as other view classes
MyModView = class(MyModView)
-- Called once on game start/mod reload
function MyModView:init(ingame_ui_context)
self.ui_renderer = ingame_ui_context.ui_renderer
self.ui_top_renderer = ingame_ui_context.ui_top_renderer
self.ingame_ui = ingame_ui_context.ingame_ui
self.render_settings = { snap_pixel_positions = true }
-- Create input service
local input_manager = ingame_ui_context.input_manager
self.input_manager = input_manager
-- Input service name can be chosen freely
input_manager:create_input_service("my_mod_view", "IngameMenuKeymaps", "IngameMenuFilters")
input_manager:map_device_to_service("my_mod_view", "keyboard")
input_manager:map_device_to_service("my_mod_view", "mouse")
input_manager:map_device_to_service("my_mod_view", "gamepad")
-- Not 100% sure what this does, simply taken from "Okri's Challenges" view
self.menu_input_description = MenuInputDescriptionUI:new(
ingame_ui_context,
self.ui_top_renderer,
input_manager:get_service("my_mod_view"),
3,
100,
generic_input_actions
)
self.menu_input_description:set_input_description(nil)
self.wwise_world = Managers.world:wwise_world(ingame_ui_context.world_manager:world("level_world"))
end
-- Called when the view is opened
function MyModView:on_enter()
-- Enable mouse cursor while the view is open
ShowCursorStack.push()
local input_manager = self.input_manager
input_manager:block_device_except_service("my_mod_view", "keyboard", 1)
input_manager:block_device_except_service("my_mod_view", "mouse", 1)
input_manager:block_device_except_service("my_mod_view", "gamepad", 1)
self:create_ui_elements()
-- Nice touch. Choose any sound you like
self:play_sound("Play_gui_achivements_menu_open")
input_manager:enable_gamepad_cursor()
end
-- Called when view is closed
function MyModView:on_exit()
local input_manager = self.input_manager
input_manager:device_unblock_all_services("keyboard", 1)
input_manager:device_unblock_all_services("mouse", 1)
input_manager:device_unblock_all_services("gamepad", 1)
ShowCursorStack.pop()
end
function MyModView:create_ui_elements()
self.ui_scenegraph = UISceneGraph.init_scenegraph(scenegraph_definition)
self._console_cursor_widget = UIWidget.init(console_cursor_definition)
local widgets = {}
local widgets_by_name = {}
for name, widget_definition in pairs(widget_definitions) do
if widget_definition then
local widget = UIWidget.init(widget_definition)
widgets[#widgets + 1] = widget
widgets_by_name[name] = widget
end
end
self._widgets = widgets
self._widgets_by_name = widgets_by_name
UIRenderer.clear_scenegraph_queue(self.ui_renderer)
end
function MyModView:update(dt)
self:_update_animations(dt)
self:draw(dt, self:input_service())
self:_handle_input(dt)
end
-- Update animations, simple buttons but also complex custom animations
-- See `HeroViewStateAchievements`, which has some animations on the `summary` screen
function MyModView:_update_animations(dt)
local widgets_by_name = self._widgets_by_name
UIWidgetUtils.animate_default_button(widgets_by_name.exit_button, dt)
end
-- Draw widgets
function MyModView:draw(dt, input_service)
local ui_renderer = self.ui_renderer
local ui_top_renderer = self.ui_top_renderer
local ui_scenegraph = self.ui_scenegraph
local input_manager = self.input_manager
local render_settings = self.render_settings
UIRenderer.begin_pass(ui_renderer, ui_scenegraph, input_service, dt, nil, render_settings)
local snap_pixel_positions = render_settings.snap_pixel_positions
local alpha_multiplier = render_settings.alpha_multiplier or 1
for _, widget in ipairs(self._widgets) do
if widget.snap_pixel_positions ~= nil then
render_settings.snap_pixel_positions = widget.snap_pixel_positions
end
render_settings.alpha_multiplier = widget.alpha_multiplier or alpha_multiplier
UIRenderer.draw_widget(ui_renderer, widget)
render_settings.snap_pixel_positions = snap_pixel_positions
end
UIRenderer.end_pass(ui_renderer)
render_settings.alpha_multiplier = alpha_multiplier
-- Handle the gamepad cursor, if required
local gamepad_active = input_manager:is_device_active("gamepad")
if gamepad_active then
self.menu_input_description:draw(ui_top_renderer, dt)
UIRenderer.begin_pass(ui_top_renderer, ui_scenegraph, input_service, dt)
UIRenderer.draw_widget(ui_top_renderer, self._console_cursor_widget)
UIRenderer.end_pass(ui_top_renderer)
end
end
-- Handle button hover and presses
function MyModView:_handle_input(dt)
local input_service = self:input_service()
local gamepad_active = Managers.input:is_device_active("gamepad")
local widgets_by_name = self._widgets_by_name
local exit_button = widgets_by_name.exit_button
if input_service:get("toggle_menu") or self:_is_button_pressed(exit_button) or (gamepad_active and input_service:get("back")) then
self:close_menu()
end
if self:_is_button_hover_enter(exit_button) then
self:play_sound("play_gui_equipment_button_hover")
end
-- TODO: Add other buttons here
end
function MyModView:play_sound(event)
WwiseWorld.trigger_event(self.wwise_world, event)
end
function MyModView:close_menu()
self:play_sound("Play_hud_hover")
self.ingame_ui:handle_transition("exit_menu")
end
function MyModView:input_service()
return self.input_manager:get_service("my_mod_view")
end
function MyModView:_is_button_hover_enter(widget)
return widget.content.button_hotspot.on_hover_enter or false
end
function MyModView:_is_button_pressed(widget)
local content = widget.content
local hotspot = content.button_hotspot or content.hotspot
if hotspot.on_release then
hotspot.on_release = false
return true
end
return false
end
local window_default_settings = UISettings.game_start_windows
local window_size = window_default_settings.large_window_size
local window_top_height = 200
-- Width of the default frame's border. Used for calculations
local frame_border_width = 22
local inner_window_width = window_size[1] - (2 * frame_border_width)
local title_text_style = {
use_shadow = true,
upper_case = true,
localize = false,
font_size = 28,
horizontal_alignment = "center",
vertical_alignment = "center",
dynamic_font_size = true,
font_type = "hell_shark_header",
text_color = Colors.get_color_table_with_alpha("font_title", 255),
offset = {
0,
0,
2
}
}
local scenegraph_definition = {
root = {
is_root = true,
size = {
1920,
1080
},
position = {
0,
0,
UILayer.default
}
},
menu_root = {
vertical_alignment = "center",
parent = "root",
horizontal_alignment = "center",
size = {
1920,
1080
},
position = {
0,
0,
0
}
},
screen = {
scale = "fit",
size = {
1920,
1080
},
position = {
0,
0,
UILayer.default
}
},
console_cursor = {
vertical_alignment = "center",
parent = "screen",
horizontal_alignment = "center",
size = {
1920,
1080
},
position = {
0,
0,
0
}
},
header = {
vertical_alignment = "top",
parent = "menu_root",
horizontal_alignment = "center",
size = {
1920,
50
},
position = {
0,
-20,
100
}
},
window = {
vertical_alignment = "center",
parent = "screen",
horizontal_alignment = "center",
size = window_size,
position = {
0,
0,
1
}
},
window_background = {
vertical_alignment = "center",
parent = "window",
horizontal_alignment = "center",
size = {
window_size[1] - 5,
window_size[2] - 5
},
position = {
0,
0,
0
}
},
exit_button = {
vertical_alignment = "bottom",
parent = "window",
horizontal_alignment = "center",
size = {
380,
42
},
position = {
0,
-16,
42
}
},
title = {
vertical_alignment = "top",
parent = "window",
horizontal_alignment = "center",
size = {
658,
60
},
position = {
0,
34,
46
}
},
title_bg = {
vertical_alignment = "top",
parent = "title",
horizontal_alignment = "center",
size = {
410,
40
},
position = {
0,
-15,
-1
}
},
title_text = {
vertical_alignment = "center",
parent = "title",
horizontal_alignment = "center",
size = {
350,
50
},
position = {
0,
-3,
2
}
},
-- TODO: Add scenegraph definitions for your widgets here
}
local disable_with_gamepad = true
local widgets = {
window = UIWidgets.create_frame("window", scenegraph_definition.window.size, "menu_frame_11", 40),
window_background = UIWidgets.create_tiled_texture("window_background", "menu_frame_bg_01", {
960,
1080
}, nil, nil, {
255,
100,
100,
100
}),
-- Close button at the bottom
exit_button = UIWidgets.create_default_button(
"exit_button",
scenegraph_definition.exit_button.size,
nil,
nil,
Localize("menu_close"),
24,
nil,
"button_detail_04",
34,
disable_with_gamepad
),
-- Title at top
title = UIWidgets.create_simple_texture("frame_title_bg", "title"),
title_bg = UIWidgets.create_background("title_bg", scenegraph_definition.title_bg.size, "menu_frame_bg_02"),
-- TODO: Move to mod:localize
title_text = UIWidgets.create_simple_text("My cool", "title_text", nil, nil, title_text_style),
-- TODO: Add your widgets here
}
local generic_input_actions = {
{
input_action = "confirm",
priority = 2,
description_text = "input_description_select"
},
{
input_action = "back",
priority = 3,
description_text = "input_description_close"
}
}
return {
scenegraph_definition = scenegraph_definition,
widgets = widgets,
generic_input_actions = generic_input_actions,
console_cursor_definition = UIWidgets.create_console_cursor("console_cursor"),
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment