mirror of
https://github.com/Refactorio/RedMew.git
synced 2024-12-14 10:13:13 +02:00
342 lines
11 KiB
Lua
342 lines
11 KiB
Lua
local RS = require 'map_gen.shared.redmew_surface'
|
|
local Debug = require 'utils.debug'
|
|
local Rendering = require 'utils.rendering'
|
|
local Vertices = require 'resources.vertices'
|
|
local insert = table.insert
|
|
|
|
local toggle_debug = false --Set to true if you wish to get spammed with debug messages from the rendering module (Requires _DEBUG = true)
|
|
|
|
local function debug_print(message, trace_levels)
|
|
if toggle_debug then
|
|
Debug.print(message, trace_levels)
|
|
end
|
|
end
|
|
|
|
local Public = {}
|
|
|
|
--At zoom level 1 a tile is 32x32 pixels
|
|
--tile size is calculated by 32 * zoom level.
|
|
|
|
local function text_height_in_tiles(scale, zoom)
|
|
-- Default (count-font) at scale 10 is 125 pixels for lower letters and 109 for capital letters
|
|
-- At scale 5 this is 64 or very close to half of the size at scale 10 (62.5)
|
|
-- Therefore size hsa been determined to be (12.5 * scale) + 1
|
|
local size = (12.5 * scale) + 1
|
|
local pixel_per_tile = zoom * 32
|
|
return size / pixel_per_tile, size
|
|
end
|
|
|
|
local function calculate_percentages(settings, player_resolution)
|
|
local original_resolution = settings.original_resolution
|
|
return {
|
|
height = player_resolution.height / original_resolution.height,
|
|
width = player_resolution.width / original_resolution.width,
|
|
tile = (settings.original_zoom * 32) / (settings.player_zoom * 32)
|
|
}
|
|
end
|
|
|
|
local function text_scale(percentage, scale)
|
|
return scale * (percentage.height + percentage.width) * 0.5
|
|
end
|
|
|
|
local function fit_to_screen(percentage, coordinates)
|
|
if not coordinates.fitted then
|
|
local height = percentage.height
|
|
local width = percentage.width
|
|
local tile = percentage.tile
|
|
for _, pos in pairs(coordinates) do
|
|
if type(pos) == 'number' then
|
|
coordinates.x = coordinates.x * width
|
|
coordinates.y = coordinates.y * height
|
|
break
|
|
else
|
|
pos.x = pos.x * width
|
|
pos.y = pos.y * height
|
|
end
|
|
end
|
|
for _, pos in pairs(coordinates) do
|
|
if type(pos) == 'number' then
|
|
coordinates.x = coordinates.x * tile
|
|
coordinates.y = coordinates.y * tile
|
|
break
|
|
else
|
|
pos.x = pos.x * tile
|
|
pos.y = pos.y * tile
|
|
end
|
|
end
|
|
coordinates.fitted = true
|
|
end
|
|
return coordinates
|
|
end
|
|
|
|
local function fit_to_screen_edges(settings, player_resolution, coordinates)
|
|
if not coordinates.fitted then
|
|
local tile = settings.original_zoom * 32
|
|
local player_tile = settings.player_zoom * 32
|
|
local display_scale = player_resolution.scale or 1
|
|
|
|
local player_height = (player_resolution.height / player_tile) * 0.5
|
|
local player_width = (player_resolution.width / player_tile) * 0.5
|
|
|
|
for _, pos in pairs(coordinates) do
|
|
if type(pos) == 'number' then
|
|
coordinates.y = -player_height + (((coordinates.y * tile) / player_tile) * display_scale)
|
|
coordinates.x = -player_width + (((coordinates.x * tile) / player_tile) * display_scale)
|
|
break
|
|
else
|
|
pos.y = -player_height + (((pos.y * tile) / player_tile) * display_scale)
|
|
pos.x = -player_width + (((pos.x * tile) / player_tile) * display_scale)
|
|
end
|
|
end
|
|
coordinates.fitted = true
|
|
end
|
|
return coordinates
|
|
end
|
|
|
|
local function create_background_params(params)
|
|
local background_params = params.background
|
|
if background_params then
|
|
for k, v in pairs(params) do
|
|
if k ~= 'background' then
|
|
if not background_params[k] then
|
|
background_params[k] = v
|
|
end
|
|
end
|
|
end
|
|
else
|
|
background_params = params
|
|
end
|
|
return background_params
|
|
end
|
|
|
|
local function text_background(settings, offset, player, percentages, size, number_text, params)
|
|
local margin = 0.01 / params.scale
|
|
local left_top = fit_to_screen(percentages, {x = -40, y = 0})
|
|
local right_bottom = fit_to_screen(percentages, {x = 40, y = 0})
|
|
left_top.y = -size * margin * 0.875
|
|
right_bottom.y = size * (1.5 + (margin * 1.125)) * number_text
|
|
local background_params = create_background_params(params)
|
|
return Public.draw_rectangle(settings, offset, left_top, right_bottom, player, background_params)
|
|
end
|
|
|
|
function Public.draw_text(settings, offset, text, player, params, draw_background, fit_to_edge)
|
|
local ids = {}
|
|
local player_resolution = player.display_resolution
|
|
player_resolution.scale = player.display_scale
|
|
local percentages = calculate_percentages(settings, player_resolution)
|
|
local scale = params.scale
|
|
|
|
if draw_background ~= -1 then
|
|
scale = text_scale(percentages, scale)
|
|
local size = text_height_in_tiles(scale, settings.player_zoom)
|
|
if fit_to_edge then
|
|
offset = fit_to_screen_edges(settings, player_resolution, offset)
|
|
else
|
|
offset = fit_to_screen(percentages, offset)
|
|
end
|
|
offset.y = offset.y - size * 0.5
|
|
end
|
|
local size = text_height_in_tiles(scale, settings.player_zoom)
|
|
|
|
if draw_background == true then
|
|
insert(ids, text_background(settings, offset, player, percentages, size, 1, params, fit_to_edge))
|
|
end
|
|
|
|
local target = {x = player.position.x + offset.x, y = player.position.y + offset.y}
|
|
|
|
local color = params.color
|
|
color = color and color or {r = 255, g = 255, b = 255}
|
|
|
|
local font = params.font
|
|
|
|
local surface = params.surface
|
|
surface = surface or RS.get_surface()
|
|
|
|
local ttl = params.time_to_live
|
|
ttl = ttl and ttl or -1
|
|
|
|
local forces = params.forces
|
|
|
|
local players = params.players
|
|
players = players or {}
|
|
|
|
table.insert(players, player)
|
|
|
|
local visible = params.visible
|
|
visible = visible or true
|
|
|
|
local dog = params.draw_on_ground
|
|
dog = dog or false
|
|
|
|
local orientation = params.orientation
|
|
orientation = orientation or 0
|
|
|
|
local alignment = params.alignment
|
|
alignment = alignment or 'center'
|
|
|
|
--local swz = params.scale_with_zoom
|
|
local swz = true
|
|
|
|
local oiam = params.only_in_alt_mode
|
|
oiam = oiam or false
|
|
|
|
local rendering_params = {
|
|
text = {'', text},
|
|
color = color,
|
|
target = target,
|
|
scale_with_zoom = swz,
|
|
surface = surface,
|
|
time_to_live = ttl,
|
|
alignment = alignment,
|
|
players = players,
|
|
scale = scale,
|
|
forces = forces,
|
|
visible = visible,
|
|
draw_on_ground = dog,
|
|
only_in_alt_mode = oiam,
|
|
orientation = orientation,
|
|
font = font
|
|
}
|
|
|
|
debug_print(rendering_params)
|
|
|
|
insert(ids, rendering.draw_text(rendering_params))
|
|
return ids
|
|
end
|
|
|
|
function Public.draw_multi_line_text(settings, offset, texts, player, params, draw_background, fit_to_edge)
|
|
local ids = {}
|
|
local player_resolution = player.display_resolution
|
|
player_resolution.scale = player.display_scale
|
|
local percentages = calculate_percentages(settings, player_resolution)
|
|
local scale = params.scale
|
|
|
|
scale = text_scale(percentages, scale)
|
|
local size = text_height_in_tiles(scale, settings.player_zoom)
|
|
|
|
if fit_to_edge then
|
|
offset = fit_to_screen_edges(settings, player_resolution, offset)
|
|
else
|
|
offset = fit_to_screen(percentages, offset)
|
|
end
|
|
|
|
offset.y = offset.y - size * 0.5
|
|
|
|
if draw_background then
|
|
insert(ids, text_background(settings, offset, player, percentages, size, #texts, params, fit_to_edge))
|
|
draw_background = -1
|
|
end
|
|
|
|
for i = 1, #texts do
|
|
insert(ids, Public.draw_text(settings, offset, texts[i], player, params, draw_background, fit_to_edge)[1])
|
|
offset.y = offset.y + (size * 1.5)
|
|
end
|
|
return ids
|
|
end
|
|
|
|
function Public.draw_rectangle(settings, offset, left_top, right_bottom, player, params, fit_to_edge)
|
|
local player_resolution = player.display_resolution
|
|
player_resolution.scale = player.display_scale
|
|
local percentages = calculate_percentages(settings, player_resolution)
|
|
if fit_to_edge then
|
|
offset = fit_to_screen_edges(settings, player_resolution, offset)
|
|
left_top = fit_to_screen_edges(settings, player_resolution, left_top)
|
|
right_bottom = fit_to_screen_edges(settings, player_resolution, right_bottom)
|
|
else
|
|
offset = fit_to_screen(percentages, offset)
|
|
left_top = fit_to_screen(percentages, left_top)
|
|
right_bottom = fit_to_screen(percentages, right_bottom)
|
|
end
|
|
|
|
local target_left = {x = player.position.x + left_top.x + offset.x, y = player.position.y + left_top.y + offset.y}
|
|
local target_right = {x = player.position.x + right_bottom.x + offset.x, y = player.position.y + right_bottom.y + offset.y}
|
|
|
|
local color = params.color
|
|
color = color and color or {}
|
|
|
|
local width = params.width
|
|
width = width and width or 0
|
|
|
|
local filled = params.filled
|
|
filled = filled and filled or true
|
|
|
|
local surface = params.surface
|
|
surface = surface or RS.get_surface()
|
|
|
|
local ttl = params.time_to_live
|
|
ttl = ttl and ttl or -1
|
|
|
|
local forces = params.forces
|
|
|
|
local players = params.players
|
|
players = players or {}
|
|
|
|
table.insert(players, player)
|
|
|
|
local visible = params.visible
|
|
visible = visible or true
|
|
|
|
local dog = params.draw_on_ground
|
|
dog = dog or false
|
|
|
|
local oiam = params.only_in_alt_mode
|
|
oiam = oiam or false
|
|
|
|
local rendering_params = {
|
|
color = color,
|
|
width = width,
|
|
filled = filled,
|
|
left_top = target_left,
|
|
right_bottom = target_right,
|
|
surface = surface,
|
|
time_to_live = ttl,
|
|
forces = forces,
|
|
players = players,
|
|
visible = visible,
|
|
draw_on_ground = dog,
|
|
only_in_alt_mode = oiam
|
|
}
|
|
|
|
debug_print(rendering_params)
|
|
|
|
return rendering.draw_rectangle(rendering_params)
|
|
end
|
|
|
|
local blackout_settings = {original_resolution = {height = 1440, width = 2560}, original_zoom = 1, player_zoom = 1}
|
|
function Public.blackout(player, zoom, ttl, color)
|
|
local left_top = {x = -40, y = -22.5}
|
|
local right_bottom = {x = 40, y = 22.5}
|
|
blackout_settings.player_zoom = zoom
|
|
return Public.draw_rectangle(blackout_settings, {x = 0, y = 0}, left_top, right_bottom, player, {color = color, time_to_live = ttl})
|
|
end
|
|
|
|
function Public.draw_arrow(settings, offset, player, params, fit_to_edge)
|
|
local player_resolution = player.display_resolution
|
|
player_resolution.scale = player.display_scale
|
|
local percentages = calculate_percentages(settings, player_resolution)
|
|
if fit_to_edge then
|
|
offset = fit_to_screen_edges(settings, player_resolution, offset)
|
|
else
|
|
offset = fit_to_screen(percentages, offset)
|
|
end
|
|
|
|
local vertices = Rendering.scale(Vertices.arrow, percentages.tile, percentages.tile)
|
|
vertices = Rendering.rotate(vertices, params.rotation)
|
|
vertices = Rendering.translate(vertices, offset.x, offset.y)
|
|
|
|
local color = params.color or {1, 1, 1, 1}
|
|
params.color = color
|
|
|
|
local players = params.players
|
|
players = players or {}
|
|
|
|
table.insert(players, player)
|
|
params.players = players
|
|
|
|
params.surface = RS.get_surface()
|
|
--Debug.print(vertices)
|
|
return Rendering.draw_polygon(vertices, params)
|
|
end
|
|
|
|
return Public
|