<|start_filename|>Hooks/Menu/PlayerProfileGUI.lua<|end_filename|>
if not Holo:ShouldModify("Menu", "PlayerProfile") then
	return
end

Holo:Post(PlayerProfileGuiObject, "init", function(self)
    --Because whoever made this script in ovk couldn't include names best I can do is recreate it.
    for _, child in pairs(self._panel:children()) do
        child:hide()
    end

    --Avatar
    local avatar = self._panel:bitmap({
        name = "Avatar",
        texture = "guis/textures/pd2/none_icon",
        x = 4,
        y = 4,
        w = 86,
        h = 86,
    })

    local steam_id = Steam:userid()
    Steam:friend_avatar(Steam.LARGE_AVATAR, steam_id, function(texture)
        avatar:animate(function()
            wait(0.25)
            Steam:friend_avatar(Steam.LARGE_AVATAR, steam_id, function(texture)
                avatar:set_image(texture or "guis/textures/pd2/none_icon")
            end)
        end)
    end)
    local font = tweak_data.menu.pd2_large_font
    local font_size = tweak_data.menu.pd2_small_font_size
    local prev
    local function createText(name, text, belowprev, icon_data)
        local panel = self._panel:panel({
            name = name,
            x = avatar:right() + 8,
            y = prev and prev:y() or avatar:y()
        })
        local icon
        if icon_data then
            icon = panel:bitmap({
                name = "Icon",
                color = Holo:GetColor("TextColors/Menu"),
                texture = icon_data.texture,
                texture_rect = icon_data.texture_rect,
                w = icon_data.w or font_size,
                h = icon_data.h or font_size,
            })
        end
        local text = panel:text({
            name = "Text",
            text = text,
            font = font,
            font_size = font_size,
            color = Holo:GetColor("TextColors/Menu"),
            x = icon and icon:right() + 2 or 0,
        })
        WalletGuiObject.make_fine_text(text)
        if icon then
            icon:set_center_y(text:center_y())
        end
        panel:set_size(text:right(), text:h())
        if prev then
            if belowprev then
                panel:set_y(prev:bottom() + 4)
            else
                panel:set_x(prev:right() + 8)
            end
        end
        prev = panel
        return panel
    end

    --name and level
    createText("Name", tostring(managers.network.account:username() or managers.blackmarket:get_preferred_character_real_name()))
    local player_level = managers.experience:current_level()
    local player_rank = managers.experience:current_rank()
    local wallet_icon = {texture = "guis/textures/pd2/shared_level_symbol", w = font_size - 4, h = font_size - 4}

    createText("Level", (player_rank > 0 and managers.experience:rank_string(player_rank) .. "-" or "") .. tostring(player_level), true, wallet_icon)
    --coins / skill points
    local skillpoints = managers.skilltree:points()
    if skillpoints > 0 then
        wallet_icon.texture = "guis/textures/pd2/shared_skillpoint_symbol"
        createText("SkillPoints", tostring(skillpoints), nil, wallet_icon)
    end
    
    --cash
    wallet_icon.texture = "guis/textures/pd2/shared_wallet_symbol"
    createText("Cash", managers.money:total_string_no_currency(), true, wallet_icon)
    createText("OffshoreCash", managers.experience:cash_string(managers.money:offshore(), ""), nil, wallet_icon)

            
    --skills and perk
    local aspect_ratio = (22 / 31)
    local icon = {texture = "guis/textures/pd2/inv_skillcards_icons", texture_rect = {0, 0, 22, 31}, w = aspect_ratio * font_size, h = font_size}
    local mp, mns = managers.skilltree:get_tree_progress_2("mastermind")
    local ep, ens = managers.skilltree:get_tree_progress_2("enforcer")
    local tp, tns = managers.skilltree:get_tree_progress_2("technician")
    local gp, gns = managers.skilltree:get_tree_progress_2("ghost")
    local fp, fns = managers.skilltree:get_tree_progress_2("hoxton")

    local skills_prev = prev
    local mastermind = createText("Mastermind", tostring(mp), true, icon)
    icon.texture_rect[1] = 24
    createText("Enforcer", tostring(ep), nil, icon)
    icon.texture_rect[1] = 48
    createText("Technician", tostring(tp), nil, icon)
    icon.texture_rect[1] = 72
    createText("Ghost", tostring(gp), nil, icon)
    icon.texture_rect[1] = 96
    createText("Fugitive", tostring(fp), nil, icon)

    --Frame
    local box = self._panel:child("BoxGui")
    if alive(box) then
        self._panel:remove(box)		
    end
    BoxGuiObject:new(self._panel, {sides = {
        2,
        0,
        0,
        0
    }})

    self._panel:set_h(avatar:h() + 8)
    self._panel:set_bottom(self._panel:parent():h() - 50)
end)

<|start_filename|>Hooks/Setup.lua<|end_filename|>
Holo:Pre(Setup, "_start_loading_screen", function()
	if Holo then
		local loc = managers.localization
		Holo:Pre(getmetatable(LoadingEnvironment), "start", function(self, setup, load, data)
			local difficulty = Global.game_settings and Global.game_settings.difficulty
			local level = Global.level_data and tweak_data.levels[Global.level_data.level_id]
			local diff_text = tweak_data.difficulty_name_ids[difficulty]
			if Holo:ShouldModify("Menu", "Loading") then
				data.Holo = {
					background_color = Holo:GetColor("Colors/Menu"),
					text_color = Holo:GetColor("TextColors/Menu"),
					colored_background = Holo.Options:GetValue("ColoredBackground"),
					briefing_string = loc and level and loc:text(level.briefing_id),
					difficulty_string = loc and diff_text and (loc:to_upper_text("debug_loading_level").." - "..loc:to_upper_text(diff_text)) or nil
				}
			end
		end)
	end
end)

<|start_filename|>Hooks/MenuSceneManager.lua<|end_filename|>
if not GameSetup and Holo:ShouldModify("Menu", "ColoredBackground") then
	if Holo:ShouldModify("Menu", "PlayerProfile") then
		Holo:Post(MenuSceneManager, "_set_up_templates", function(self)
			self._scene_templates.standard.character_pos = Vector3(-32, 10.66, -137)
		end)
	end

	function MenuSceneManager:HoloUpdate()
		local cam = managers.viewport:get_current_camera()
		if type(cam) == "boolean" then
			return
		end
		local w,h = 1920, 1080
		local a,b,c = cam:position() + Vector3(-1, 584, -h/2+1):rotate_with(cam:rotation()), Vector3(0, w, 0):rotate_with(cam:rotation()) , Vector3(0, 0, h):rotate_with(cam:rotation())
		if alive(self._background_ws) then
			self._background_ws:set_world(w,h,a,b,c)
			self._background_ws:panel():child("bg"):set_color(Holo:GetColor("Colors/Menu"))
			if self._shaker then
				self._shaker:stop_all()
			end
			if not Holo.Options:GetValue("MenuColorGrading") then
				managers.environment_controller:set_default_color_grading("color_off", true)
				managers.environment_controller:refresh_render_settings()
			end
		else
			self._background_ws = World:newgui():create_world_workspace(w,h,a,b,c)
			self._background_ws:panel():bitmap({
				name = "bg",
				color = Holo:GetColor("Colors/Menu"),
				layer = 20000,
				w = w,
				h = h,
			})
			self._background_ws:set_billboard(Workspace.BILLBOARD_BOTH)
		end
		World:effect_manager():set_rendering_enabled(Global.load_level)
		if managers.environment_controller._vp then
			managers.environment_controller._vp:vp():set_post_processor_effect("World", Idstring("bloom_combine_post_processor"), Idstring("bloom_combine_empty"))
		end
		local unwanted = {
			"units/menu/menu_scene/menu_cylinder",
			"units/menu/menu_scene/menu_smokecylinder1",
			"units/menu/menu_scene/menu_smokecylinder2",
			"units/menu/menu_scene/menu_smokecylinder3",
			"units/menu/menu_scene/menu_cylinder_pattern",
			"units/menu/menu_scene/menu_cylinder_pattern",
			"units/menu/menu_scene/menu_logo",
			"units/pd2_dlc_shiny/menu_showcase/menu_showcase",
			"units/payday2_cash/safe_room/cash_int_safehouse_saferoom"
		}
		for _, unit in pairs(World:find_units_quick("all")) do
			for _, unit_name in pairs(unwanted) do
				if unit:name() == unit_name:id() then
					unit:set_visible(false)
				end
			end
		end
	end
	Hooks:PostHook(MenuSceneManager, "update", "MenuBGsUpdate", function(self)
		if not MenuBackgrounds then
			self:HoloUpdate()
		end
	end)
end

<|start_filename|>Classes/Definitions.lua<|end_filename|>
Holo.Updaters = {}
Holo.TextSizesStrings = {
	"Holo/Small",
	"Holo/Normal",
	"Holo/Big"
}
Holo.FrameStyles = {
	"Holo/Normal",
	"Holo/BottomLine",
	"Holo/LeftLine",
	"Holo/RightLine",
	"Holo/TopLine",
	"Holo/FullFrame",
	"Holo/None",
}
Holo.Positions = {
	"Holo/TopLeft",
	"Holo/TopCenter",
	"Holo/TopRight",
	"Holo/CenterLeft",
	"Holo/Center",
	"Holo/CenterRight",
	"Holo/BottomLeft",
	"Holo/BottomCenter",
	"Holo/BottomRight",
}
Holo.TMPositions = {
	"left",
	"center",
	"right",
	"left_top",
	"center_top",
	"right_top",
}
Holo.MenuMainTMPositions = {
	"Holo/Left",
	"Holo/Center",
	"Holo/Right",
}
Holo.MenuTMPositions = {
	"Holo/Left",
	"Holo/Center",
	"Holo/Right",
	"Holo/LeftToTop",
	"Holo/CenterToTop",
	"Holo/RightToTop",
}
Holo.ContrastOverride = {
	["TextColors/Tab"] = "Colors/Menu"
}
Holo.NonContrastable = {
	["TextColors/Health"] = true,
	["TextColors/Armor"] = true,
	["TextColors/Interaction"] = true,
}

<|start_filename|>Hooks/Menu/PlayerInventoryGUI.lua<|end_filename|>
if not Holo:ShouldModify("Menu", "Inventory") then
	return
end

Holo:Post(PlayerInventoryGui, "init", function(self)
	Holo.Utils:FixBackButton(self)
	Holo.Utils:SetBlendMode(self._panel, "detection")
end)

Holo:Post(PlayerInventoryGui, "mouse_moved", function(self, o, x, y)
	for _, button in pairs(self._text_buttons) do
		if alive(button.panel) and button.panel:visible() then
			if button.panel:inside(x, y) then
				if not button._highlighted then
					button._highlighted = true
					button.highlighted = true
					managers.menu_component:post_event("highlight")
					if alive(button.text) then
						button.text:set_color(Holo:GetColor("Colors/Marker"))
					end
				end
				used, pointer = true, "link"
			elseif button._highlighted then
				button._highlighted = false
				button.highlighted = false
				button.text:set_color(Holo:GetColor("TextColors/Menu"))
			end
		end
	end
end)

Holo:Post(PlayerInventoryGui, "setup_player_stats", function(self, panel, data)
	if self._player_stats_titles and alive(self._player_stats_titles.skill) then
		self._player_stats_titles.skill:set_color(Holo:GetColor("Colors/Marker"))
	end
	if self._player_stats_texts then
		for i, stat in pairs(self._player_stats_shown) do
			if self._player_stats_texts[stat.name] and alive(self._player_stats_texts[stat.name].skill) then
				self._player_stats_texts[stat.name].skill:set_blend_mode("normal")
				self._player_stats_texts[stat.name].skill:set_color(Holo:GetColor("Colors/Marker"))
			end
		end
	end
end)

Holo:Post(PlayerInventoryGui, "set_skilltree_stats", function(self, panel, data)
	if self._stats_titles and alive(self._stats_titles.aced) then
		self._stats_titles.aced:set_color(Holo:GetColor("Colors/Marker"))
	end
	if self._stats_texts then
		for i, stat in pairs(data) do
			if self._stats_texts[stat.name] and alive(self._stats_texts[stat.name].aced) then
				self._stats_texts[stat.name].aced:set_blend_mode("normal")
				self._stats_texts[stat.name].aced:set_color(Holo:GetColor("Colors/Marker"))
			end
		end
	end
end)

Holo:Post(PlayerInventoryGui, "set_weapon_stats", function(self, panel, data)
	if self._stats_titles and alive(self._stats_titles.skill) then
		self._stats_titles.skill:set_color(Holo:GetColor("Colors/Marker"))
	end
	if self._stats_texts then
		for i, stat in pairs(data) do
			if self._stats_texts[stat.name] and alive(self._stats_texts[stat.name].skill) then
				self._stats_texts[stat.name].skill:set_blend_mode("normal")
				self._stats_texts[stat.name].skill:set_color(Holo:GetColor("Colors/Marker"))
			end
		end
	end
end)

Holo:Post(PlayerInventoryGui, "set_melee_stats", function(self, panel, data)
	if self._stats_titles and alive(self._stats_titles.skill) then
		self._stats_titles.skill:set_color(Holo:GetColor("Colors/Marker"))
	end
	if self._stats_texts then
		for i, stat in pairs(data) do
			if self._stats_texts[stat.name] and alive(self._stats_texts[stat.name].skill) then
				self._stats_texts[stat.name].skill:set_blend_mode("normal")
				self._stats_texts[stat.name].skill:set_color(Holo:GetColor("Colors/Marker"))
			end
		end
	end
end)

Holo:Post(PlayerInventoryGui, "create_text_button", function(self, params)
	for _, button in pairs(self._text_buttons) do
		button.text:configure({
			color = Holo:GetColor("TextColors/Menu"),
			blend_mode = "normal"
		})
	end
end)

--Weirdly a prehook makes it break
Holo:Replace(PlayerInventoryGui, "create_box", function(self, orig, params, ...)
	params.text_selected_color = Holo:GetColor("TextColors/Menu")
	params.text_unselected_color = Holo:GetColor("TextColors/Menu")
	params.box_selected_sides = {0, 0, 0, 2}
	params.box_unselected_sides = {0, 0, 0, 0}
	if params.name == "infamy_card_number" then
		params.text_selected_color = Color.black
		params.text_unselected_color = Color.black
	end
	return orig(self, params, ...)
end)

<|start_filename|>Base.lua<|end_filename|>
function Holo:Init()
	self.RefusedScripts = {}
	self.set_position_clbks = {}
	self:CheckOtherMods()
	self:UpdateSettings()
	World:effect_manager():set_rendering_enabled(true)
	self:LoadTextures()
end

function Holo:AddUpdateFunc(func)
    table.insert(self.Updaters, func)
end

function Holo:LoadTextures()
	local ids_strings = {}
	local function LoadTextures(path)
		for _, file in pairs(FileIO:GetFiles(path)) do
			local file_path = BeardLib.Utils.Path:Combine(path, file)
			local in_path = file_path:gsub("%.png", ""):gsub("%.texture", ""):gsub(self.ModPath, ""):gsub("Assets/", "")
			table.insert(ids_strings, Idstring(in_path))
			DB:create_entry(Idstring("texture"), Idstring(in_path), file_path)
		end
		for _, dir in pairs(FileIO:GetFolders(path)) do
			LoadTextures(BeardLib.Utils.Path:Combine(path, dir))
		end
	end
	LoadTextures(BeardLib.Utils.Path:Combine(self.ModPath, "Assets"))
	Application:reload_textures(ids_strings)
	self.Options:Save()
	self:log("Loaded Textures")
end

function Holo:UpdateSettings()
	for _, func in pairs(self.Updaters) do
		func()
	end
end

function Holo:GetFrameColor(setting, can_return_null)
	return self.Options:GetValue("FrameColors/Enable") and self:GetColor("FrameColors/" .. setting, nil, can_return_null) or not can_return_null and self:GetColor("Colors/Frame") or nil
end

function Holo:GetFrameStyle(setting)
	return self.Options:GetValue("FrameStyles/Enable") and self.Options:GetValue("FrameStyles/" .. setting) or self.Options:GetValue("FrameStyle")
end

function Holo:GetAlpha(setting)
	return self.Options:GetValue("HUDAlpha")
end

function Holo:GetColor(setting, vec, can_return_null)
	local color = self.Options:GetValue(setting) or not can_return_null and Color.white or nil
	if setting:match("TextColors") then
		local bgname = Holo.ContrastOverride[setting] or setting:gsub("TextColors", "Colors")
		if self.Options:GetValue("TextColors/AutomaticTextColors") and self.Options:GetValue(bgname) and not Holo.NonContrastable[setting] then
			color = self:GetColor(bgname):contrast()
		end
	end
	return vec and Vector3(color:unpack()) or color
end

function Holo:AddSetPositionClbk(clbk)
	table.insert(self.set_position_clbks, clbk)
end

function Holo:CheckOtherMods()
	if pdth_hud and pdth_hud.Options then
		if self.Options:GetValue("Assault") then
			pdth_hud.Options:SetValue("HUD/Assault", false)
		end
	end
	if restoration and restoration.Options then
		if self.Options:GetValue("Teammate") then
			restoration.Options:SetValue("HUD/Teammate", false)  
		end		
		if self.Options:GetValue("Menu") then
			restoration.Options:SetValue("HUD/Loadouts", false)
		end
	end
end

function Holo:ShouldModify(c, o)
	local function inform(a)
		self:log(string.format("[Info]Cannot modify %s because %s uses it", o, a))
		self.RefusedScripts[RequiredScript] = true
	end
	if c and not self.Options:GetValue("" .. c) then
		return false
	end 
	if (CompactHUD or Fallout4hud or SAOHUD) and o == "Teammate" then
		return false
	end
	if NepgearsyMM and o == "PlayerProfile" then
		inform("Nepgearsy Main Menu")
		return false
	end

	if pdth_hud and pdth_hud.Options then
		if pdth_hud.Options:GetValue("HUD/MainHud") and o == "Teammate" then
			inform("PDTH Hud")	
			return false
		end
		if pdth_hud.Options:GetValue("HUD/Objectives") and o == "Presenter" then
			inform("PDTH Hud")
			return false
		end
		if pdth_hud.Options:GetValue("HUD/Interaction") and o == "Interaction" then
			inform("PDTH Hud")
			return false
		end
	end	
	if restoration and restoration.Options then
		local hud = restoration.Options:GetValue("HUD/MainHUD")
		local assault = restoration.Options:GetValue("HUD/AssaultPanel") and o == "Assault"
		local presenter = restoration.Options:GetValue("HUD/Presenter") and o == "Presenter"
		local objective = restoration.Options:GetValue("HUD/ObjectivesPanel") and o == "Objective"
		local hint = restoration.Options:GetValue("HUD/Hint") and o == "Hint"
		local carry = restoration.Options:GetValue("HUD/Carry") and o == "Carrying"
		local down = restoration.Options:GetValue("HUD/Down") and o == "PlayerDowned"
		if hud and (assault or presenter or objective or hint or carry or down) then
			inform("Resotration")
			return false
		end
	end
	local WolfHUD = WolfHUD or VHUDPlus
	if WolfHUD then
		if o == "Teammate" and WolfHUD:getSetting({"CustomHUD", "ENABLED"}) then
			inform("WolfHUD")
			return false			
		end
		if o == "Chat" and HUDChat and HUDChat.WIDTH then --No actual option to disable it! GREAT
			inform("WolfHUD")
			return false
		end
	end
	if o == "Teammate" and HUDTeammateCustom then
		inform("CustomHUD")
		return false
	end
	local res = true
	if o then
		res = self.Options:GetValue(o) 
	end
	if not res then
		self.RefusedScripts[RequiredScript] = true
	end
	return res
end

function Holo:Post(clss, func, after_orig)
	Hooks:PostHook(clss, func, "HoloUI"..func, after_orig)
end

function Holo:Pre(clss, func, before_orig)
	Hooks:PreHook(clss, func, "HoloUIPre"..func, before_orig)
end

function Holo:Replace(clss, func, new_func)
	clss["holo_orig_"..func] = clss["holo_orig_"..func] or clss[func]
	clss[func] = function(this, ...)
		return new_func(this, clss["holo_orig_"..func], ...)
	end
end

Hooks:Add("MenuManagerPopulateCustomMenus", "HoloMenuInit", function(self, nodes)
	--Called more than once for some reason....
	function MenuCallbackHandler:OpenHoloMenu() Holo.Menu._menu:Enable() end		
	Holo.Menu:Init()
	MenuHelperPlus:AddButton({
		id = "HoloOptions",
		title = "Holo/OptionsTitle",
		desc = "Holo/OptionsDesc",
		callback = "OpenHoloMenu",
		node = nodes.blt_options,
	})
end)
 
Hooks:Add("GameSetupUpdate", "HoloUpdate", function(t, dt)
	if not Holo._hooked_to_poco then
		if PocoHud3Class and PocoHud3Class.TPocoHud3 then
			Holo:Post(PocoHud3Class.TPocoHud3, "_updatePlayers", function(self, t)
				local just_updated_holo
				for i=1,4 do
					local cdata = managers.criminals:character_data_by_peer_id(i)
					if cdata and self['pnl_'..i] then
						local me = i==self.pid
						local tm = managers.hud._teammate_panels[me and HUDManager.PLAYER_PANEL or cdata.panel_id]
						if tm then
							local x,y = managers.gui_data:scaled_to_full(managers.hud._saferect, tm._player_panel:world_x(), 0) --Can't get this shit to convert properly
							self['pnl_'..i]:set_world_x(x - 150)
							if not self._updated_holo then
								tm:UpdateHolo()
								just_updated_holo = true
							end
						end
					else
						self._updated_holo = false
					end
				end
				if just_updated_holo and not self._updated_holo then
					self._updated_holo = true
				end
			end)
		end
		Holo._hooked_to_poco = true
	end
end)


<|start_filename|>Hooks/Menu/MissionBriefing.lua<|end_filename|>
if not Holo:ShouldModify("Menu", "Lobby") then
	return
end

Holo:Post(HUDMissionBriefing, "init", function(self)	    
	if not alive(self._job_schedule_panel) then
		return 
	end
	local text_font_size = tweak_data.menu.pd2_small_font_size - (BigLobbyGlobals and 3 or 0)
	local num_player_slots = BigLobbyGlobals and BigLobbyGlobals:num_player_slots() or 4

	self._ready_slot_panel:set_h((text_font_size + 16) * num_player_slots + 24)	    
	if not BigLobbyGlobals then
		self._ready_slot_panel:set_right(self._foreground_layer_one:w())
		self._ready_slot_panel:set_bottom(self._foreground_layer_one:h() - 12)
	else
		self._ready_slot_panel:set_x(0)
		self._ready_slot_panel:set_bottom(self._foreground_layer_one:h() - 32)
	end
	if self._ready_slot_panel:child("BoxGui") then
		self._ready_slot_panel:remove(self._ready_slot_panel:child("BoxGui"))
	end
	for i = 1, 7 do
		self._job_schedule_panel:child("day_" .. tostring(i)):hide()
		self._job_schedule_panel:child("ghost_" .. tostring(i)):hide()
	end

	local tex1 = Idstring("guis/dlcs/rvd/textures/pd2/mission_briefing/day1")
	local tex2 = Idstring("guis/dlcs/rvd/textures/pd2/mission_briefing/day2")
	for _, child in pairs(self._job_schedule_panel:children()) do
		if child.texture_name then
			log(tostring(child:texture_name()))
		end
		if child.texture_name and (child:texture_name() == tex1 or child:texture_name() == tex2) then
			child:hide()
		end
	end
	for i = 1, managers.job:current_stage() or 0 do
		self._job_schedule_panel:child("stage_done_" .. tostring(i)):hide()
	end
	if Holo.Options:GetValue("DisableLobbyVideo") and alive(self._background_layer_two:child("panel")) then
		self._background_layer_two:child("panel"):hide()
	end
	local num_stages = self._current_job_chain and #self._current_job_chain or 0
	local ghost = managers.job:is_job_stage_ghostable(managers.job:current_real_job_id(), managers.job:current_stage()) and managers.localization:get_default_macro("BTN_GHOST") or ""
	self._foreground_layer_one:child("job_overview_text"):set_text(managers.localization:to_upper_text("menu_day_short", {day = managers.job:current_stage() .. "/" .. num_stages .. " " .. ghost}))
	self._job_schedule_panel:child("payday_stamp"):hide()
	self._foreground_layer_one:child("pg_text"):set_text(managers.localization:to_upper_text(tweak_data.difficulty_name_ids[Global.game_settings.difficulty]))
	managers.hud:make_fine_text(self._foreground_layer_one:child("pg_text"))		
	self._foreground_layer_one:child("pg_text"):set_right(self._paygrade_panel:right())
	self._paygrade_panel:hide()
	if not self._singleplayer then
		local prev
		for i = 1, num_player_slots do
			local slot = self._ready_slot_panel:child("slot_" .. tostring(i))
			slot:set_h(text_font_size + 16)
			if prev then
				slot:set_y(prev:bottom() + 1)
			else
				slot:set_y(0)
			end
			prev = slot
			slot:rect({
				name = "bg",
				alpha = 0.4,
				color = Color(0, 0, 0),
				layer = -2,
			})
			local avatar = slot:bitmap({
				name = "avatar",
				texture = "guis/textures/pd2/none_icon",
				x = 2,
				w = slot:h() - 4,
				h = slot:h() - 4,
				layer = 1,
			})
			local center_y = slot:h() / 2
			local criminal = slot:child("criminal")
			local name = slot:child("name")
			local status = slot:child("status")
			local detection = slot:child("detection")
			local detection_value = slot:child("detection_value")
			local infamy = slot:child("infamy")
			local voice = slot:child("voice")
			avatar:set_center_y(center_y)
			criminal:set_blend_mode("normal")
			criminal:set_x(avatar:right() + 8)
			criminal:set_center_y(center_y)
			voice:set_center_y(center_y)
			voice:set_x(criminal:right() + 20)
			infamy:set_center_y(center_y - 1)
			infamy:set_x(voice:right() + 2)
			name:set_blend_mode("normal")
			name:set_center_y(center_y)
			name:set_x(infamy:right())
			status:set_blend_mode("normal")
			status:set_w(128)
			status:set_center_y(center_y)
			status:set_right(slot:w() - 8)
			detection:set_x(status:left() - 4)
			detection:set_center_y(center_y)
			detection:child("detection_left_bg"):set_blend_mode("normal")				
			detection:child("detection_left"):set_blend_mode("normal")
			detection:child("detection_right_bg"):set_blend_mode("normal")
			detection:child("detection_right"):set_blend_mode("normal")
			detection_value:set_blend_mode("normal")
			detection_value:set_center_y(center_y)
			detection_value:set_x(detection:right() + 4)
		end
		self._ready_slot_panel:rect({
			name = "line",
			color = Holo:GetColor("Colors/Tab"),
			x = prev:x(),
			w = prev:w(),
			h = 2,
			layer = -1,
		}):set_y(prev:bottom())	
	end
end)

Holo:Post(HUDMissionBriefing, "set_player_slot", function(self, nr, params)
	local slot = self._ready_slot_panel:child("slot_" .. tostring(nr))
	if not slot or not alive(slot) then
		return
	end
	local peer = managers.network:session():peer(nr) or nil
	local steam_id = peer and peer:user_id() or nr == 1 and Steam:userid() or nil
	if steam_id then
		--Make sure we have the texture loaded, lets choose large so it's loaded in cache
		local avatar = slot:child("avatar")
		Steam:friend_avatar(Steam.LARGE_AVATAR, steam_id, function(texture) --ovk pls fix, it returns question mark avatar without waiting
			avatar:animate(function()
				wait(1)
				Steam:friend_avatar(Steam.LARGE_AVATAR, steam_id, function(texture)
					avatar:set_image(texture or "guis/textures/pd2/none_icon")
				end)
			end)
		end)
	end
end)

Holo:Post(HUDMissionBriefing, "set_slot_ready", function(self, peer, peer_id)
	local slot = self._ready_slot_panel:child("slot_" .. tostring(peer_id))
	if alive(slot) then
		slot:child("status"):set_blend_mode("normal")	
	end 
end)

<|start_filename|>Hooks/Menu/LevelLoadingScreenGUI.lua<|end_filename|>
local oinit = LevelLoadingScreenGuiScript.init
function LevelLoadingScreenGuiScript:init(scene_gui, res, progress, base_layer)
	if arg.Holo then
		local data = arg.Holo
		self._scene_gui = scene_gui
		self._res = res
		self._base_layer = base_layer
		self._level_tweak_data = arg.load_level_data.level_tweak_data
		self._gui_tweak_data = arg.load_level_data.gui_tweak_data
		self._menu_tweak_data = arg.load_level_data.menu_tweak_data
		self._scale_tweak_data = arg.load_level_data.scale_tweak_data
		self._coords = arg.load_level_data.controller_coords or false
		self._gui_data = arg.load_level_data.gui_data
		self._workspace_size = self._gui_data.workspace_size
		self._saferect_size = self._gui_data.saferect_size
		local challenges = arg.load_level_data.challenges
		local safe_rect_pixels = self._gui_data.safe_rect_pixels
		local safe_rect = self._gui_data.safe_rect
		local aspect_ratio = self._gui_data.aspect_ratio
		self._safe_rect_pixels = safe_rect_pixels
		self._safe_rect = safe_rect
		self._gui_data_manager = GuiDataManager:new(self._scene_gui, res, safe_rect_pixels, safe_rect, aspect_ratio)
		self._back_drop_gui = MenuBackdropGUI:new(nil, self._gui_data_manager, true)
		local base_panel = self._back_drop_gui:get_new_base_layer()		
		base_panel:bitmap({
			texture = not data.colored_background and self._gui_data.bg_texture,
			color = data.colored_background and data.background_color or nil,
			w = base_panel:w(),
			h = base_panel:h(),
			layer = 0,
		})
		self._back_drop_gui:enable_light(false)
		self._back_drop_gui._panel:child("base_layer"):child("bd_base_layer"):hide()
		self._back_drop_gui._panel:child("particles_layer"):hide()
		local panel = self._back_drop_gui:get_new_background_layer()
		self._back_drop_gui:set_panel_to_saferect(panel)
		if arg.load_level_data.tip then
			self._loading_hint = self:_make_loading_hint(panel, arg.load_level_data.tip)
		end
		self._indicator = panel:bitmap({
			name = "indicator",
			color = data.text_color,
			texture = "guis/textures/pd2/skilltree/drillgui_icon_restarter",
			w = 32,
			h = 32,
		})		
		self._level_title_text = panel:text({
			font = "fonts/font_large_mf",
			font_size = 0,
			visible = false,
			halign = "left",
			vertical = "bottom",
		})
		self._level_name_text = panel:text({
			text = string.upper(self._level_tweak_data.name or ""),
			font = "fonts/font_large_mf",
			color = data.text_color,
			font_size = 42,
	        halign="grow",
	        valign="bottom",
		})			
		local difficulty_text = panel:text({
			text = data.difficulty_string,
			font = "fonts/font_large_mf",
			color = data.text_color,
			font_size = 24,
	        halign="grow",
	        valign="bottom",
			h = 24
		})		
		local brief_text = panel:text({
			text = data.briefing_string,
			font = "fonts/font_large_mf",
			color = data.text_color,
			font_size = 16,
			align = "right",
	        halign="grow",
	        valign="bottom",
	        wrap = true,
			w = 500
		})
		local make_text = function(text)
			local _,_,w,h = text:text_rect()
			text:set_size(w,h)
		end
		make_text(brief_text)
		brief_text:set_righttop(panel:right() - 50, panel:top() - 20)	
		make_text(self._level_name_text)
		make_text(difficulty_text)
		difficulty_text:set_top(self._level_name_text:bottom())
		self._indicator:set_leftbottom(self._level_name_text:rightbottom())
		self._indicator:move(0, -6)
	else
		oinit(self, scene_gui, res, progress, base_layer)
	end
end

local o_make_loading_hint = LevelLoadingScreenGuiScript._make_loading_hint
function LevelLoadingScreenGuiScript:color_all(panel)
	if arg.Holo then
		local text_color = arg.Holo.text_color
		for _, child in pairs(panel:children()) do
			if child.set_color and child:w() ~= 192 then
				child:set_color(text_color)
			elseif child.children then
				self:color_all(child)
			end
		end
	end
end

function LevelLoadingScreenGuiScript:_make_loading_hint(parent, tip)
	local this = o_make_loading_hint(self, parent, tip)
	local panel = parent:child(0)
	if alive(panel) and panel.children then
		self:color_all(panel)
	end
	return this
end