Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Crosshair spread indicator code
crosshair = {}
function crosshair:set_meta(meta)
return setmetatable(self, {__index = function(self, index)
if crosshair[index] ~= nil then
return crosshair[index]
end
if meta[index] ~= nil then
return meta[index]
end
return rawget(self, index)
end})
end
function crosshair.new(meta, player)
return crosshair.set_meta({player = player}, meta)
end
local function xy(x)
return {x = x, y = x}
end
local function calculate_position(direction, spread)
return modlib.vector.add(xy(0.5), modlib.vector.multiply_scalar(direction, spread / 2))
end
function crosshair:add(spread)
spread = spread or 0
local type, indicator_type, player = self.type, self.indicator_type, self.player
if type ~= "default" then
player:hud_set_flags{crosshair = false}
self.crosshair = player:hud_add{
hud_elem_type = "image",
position = xy(0.5),
alignment = xy(0),
scale = xy(1),
text = self.texture,
name = "adv_weapons_crosshair",
z_index = 1
}
end
if indicator_type == "scale" then
self.scale = player:hud_add{
hud_elem_type = "image",
position = xy(0.5),
alignment = xy(0),
scale = xy(-100 * spread),
text = assert(self.indicator_texture),
name = "adv_weapons_crosshair_scale",
z_index = 0
}
elseif indicator_type == "axes" then
self.axes = {}
for rotation = 0, 270, 90 do
local radians = math.rad(rotation)
local direction = {x = modlib.number.round(math.cos(radians)), y = modlib.number.round(-math.sin(radians))}
self.axes[player:hud_add{
hud_elem_type = "image",
position = calculate_position(direction, spread),
-- TODO fix edge case of spread > 0.9... with indicators not on screen anymore
offset = modlib.vector.multiply_scalar(direction, (self.size or 0) / 2),
alignment = direction,
scale = xy(1),
text = assert(self.indicator_texture) .. "^[transformR" .. rotation,
name = "adv_weapons_crosshair_axis_" .. rotation,
z_index = 2
}] = direction
end
end
end
function crosshair:update(spread)
assert(spread >= 0 and spread <= 1)
local indicator_type, player = self.indicator_type, self.player
if indicator_type == "scale" then
player:hud_change(self.scale, "scale", xy(-100 * spread))
elseif indicator_type == "axes" then
for id, direction in pairs(self.axes) do
player:hud_change(id, "position", calculate_position(direction, spread))
end
end
end
function crosshair:remove()
local type, indicator_type, player = self.type, self.indicator_type, self.player
if type ~= "default" then
player:hud_remove(self.crosshair)
player:hud_set_flags{crosshair = true}
end
if indicator_type == "scale" then
player:hud_remove(self.scale)
elseif indicator_type == "axes" then
for id in pairs(self.axes) do
player:hud_remove(id)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment