Skip to content

Instantly share code, notes, and snippets.

@quad-damage
Last active January 10, 2023 21:27
Show Gist options
  • Save quad-damage/129ca37e0d20c357a8cb9c0beac98182 to your computer and use it in GitHub Desktop.
Save quad-damage/129ca37e0d20c357a8cb9c0beac98182 to your computer and use it in GitHub Desktop.
Animated hitlogs for Rifk7.
--------------------------------
-- Animated Hitlogs for Rifk7 --
-- By: Quadruple --
--------------------------------
--------------------------------------------------
-- IF YOU ENCOUNTER A LOT OF UNKNOWN MISSES --
-- THAT ACTUALLY LAND, INCREASE THE VALUE BELOW --
--------------------------------------------------
local ABANDON_LOG_UNKOWN_TIMEOUT = 0.3
--------------------------------------------------
local function map(x, in_min, in_max, out_min, out_max)
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
end
local function clamp(x, min, max)
if(x < min) then return min end
if(x > max) then return max end
return x
end
local hitbox_strings = {
[hitbox.head] = "head",
[hitbox.lower_neck] = "neck",
[hitbox.pelvis] = "pelvis",
[hitbox.stomach] = "stomach",
[hitbox.lower_chest] = "lower chest",
[hitbox.chest] = "chest",
[hitbox.upper_chest] = "upper chest",
[hitbox.left_thigh] = "left thigh",
[hitbox.right_thigh] = "right thigh",
[hitbox.left_calf] = "left calf",
[hitbox.right_calf] = "right calf",
[hitbox.left_foot] = "left foot",
[hitbox.right_foot] = "right foot",
[hitbox.left_hand] = "left hand",
[hitbox.right_hand] = "right hand",
[hitbox.left_upper_arm] = "left arm",
[hitbox.left_forearm] = "left arm",
[hitbox.right_upper_arm] = "right arm",
[hitbox.right_forearm] = "right arm",
[hitbox.max] = "generic"
}
local hitgroup_strings = {
[0] = "generic",
[1] = "head",
[2] = "chest",
[3] = "stomach",
[4] = "left arm",
[5] = "right arm",
[6] = "left leg",
[7] = "right leg",
[8] = "generic/gear"
}
-- HACK: Since we need to use log_renderer in menu_items
-- AND menu_items in log_renderer, predefine menu_items
-- to nil, and then define it later.
local menu_items = nil
local log_renderer = {
log_list = { },
add_log = function(self, text, color)
local l = {
text = text,
display_text = "",
spawn_time = global_vars.get_real_time(),
color = color
}
if(menu.get(menu_items.index_log_selection):get_multiselection_item(1) == true) then
general.log_to_console_colored(string.format("[rifk7.com] %s", text), color:r(), color:g(), color:b(), 255)
end
table.insert(self.log_list, l)
end,
render_individual_log = function(self, log, index)
local delta = global_vars.get_real_time() - log.spawn_time
local alpha_modifier = 255
local fade_in_timing = menu.get(menu_items.index_fade_in_timer):get_float()
local idle_timing = menu.get(menu_items.index_idle_timer):get_float()
local fade_out_timing = menu.get(menu_items.index_fade_out_timer):get_float()
-- Fade-in random numbers animation.
if(delta <= fade_in_timing) then
local text_reveal_index = math.floor(map(delta, 0, fade_in_timing, 0, #log.text))
log.display_text = log.text:sub(1, text_reveal_index)
for i = text_reveal_index, #log.text - 1, 1 do
log.display_text = log.display_text .. string.char(math.random(48,57))
end
else
log.display_text = log.text
end
if(delta >= fade_in_timing + idle_timing) then
alpha_modifier = map(delta, fade_in_timing + idle_timing, fade_in_timing + idle_timing + fade_out_timing, 255, 0)
end
if(delta >= fade_in_timing + idle_timing + fade_out_timing) then
self.log_list[index] = nil
end
renderer.draw_text(renderer.get_center().x, renderer.get_center().y + (16 * index), log.display_text, renderer.get_font(fonts.profont_15), log.color:r(), log.color:g(), log.color:b(), alpha_modifier, bit.bor(font_flags.centered_x, font_flags.drop_shadow))
end,
render_logs = function(self)
for _, log in pairs(self.log_list) do
self:render_individual_log(log, _)
end
end,
}
local function example_hit_log()
log_renderer:add_log("Hit player in the hitbox(hitbox) for damage(damage) [0 health remaining]", menu.get(menu_items.index_hit_color):get_color())
end
local function example_miss_log()
log_renderer:add_log("Missed player's hitbox due to earth's curvature.", menu.get(menu_items.index_miss_color):get_color())
end
menu_items = {
index_log_selection = menu.add_multiselection("Log selection", "Hit logs\0Miss logs\0Log to console\0"),
index_separator_1 = menu.add_separator("1"),
index_fade_in_timer = menu.add_slider("Hitlog fade-in timing (seconds)", 2.5, 0.1, 5),
index_idle_timer = menu.add_slider("Hitlog idle timing (seconds)", 3, 0.1, 5),
index_fade_out_timer = menu.add_slider("Hitlog fade-out timing (seconds)", 0.5, 0.1, 5),
index_separator_2 = menu.add_separator("2"),
index_spawn_hit_log = menu.add_button_callback("Spawn example hit log", example_hit_log),
index_spawn_miss_log = menu.add_button_callback("Spawn example miss log", example_miss_log),
index_separator_3 = menu.add_separator("3"),
index_hit_color = menu.add_colorpicker("Hit log color#1", 160, 220, 160, 255, false),
index_hit_label = menu.add_text("Hit log color"),
index_miss_color = menu.add_colorpicker("Miss log color#1", 220, 160, 160, 255, false),
index_miss_label = menu.add_text("Miss log color"),
}
-- Ragebot Tracking Class
-- PURPOSE: The only ragebot related callback is for when the
-- ragebot shots, not when it misses or hits. This class
-- does it's own tracking of misses and hits, and notifies
-- the log renderer.
local ragebot_tracker = {
player_data = { },
unclaimed_shots = { },
initialize = function(self)
for i = 1, 64, 1 do
self.player_data[i] = {
resolver_misses = 0,
spread_misses = 0
}
end
end,
notify_player_miss_unknown = function(self, shot_info)
if(menu.get(menu_items.index_log_selection):get_multiselection_item(1) == false) then return end
log_renderer:add_log(string.format("Missed %s's %s due to unknown", engine.get_player_info(shot_info.player_index).name, hitbox_strings[shot_info.hitbox]), menu.get(menu_items.index_miss_color):get_color())
end,
notify_player_miss_resolver = function(self, shot_info)
if(menu.get(menu_items.index_log_selection):get_multiselection_item(1) == false) then return end
log_renderer:add_log(string.format("Missed %s's %s due to resolver", engine.get_player_info(shot_info.player_index).name, hitbox_strings[shot_info.hitbox]), menu.get(menu_items.index_miss_color):get_color())
end,
notify_player_miss_spread = function(self, shot_info)
if(menu.get(menu_items.index_log_selection):get_multiselection_item(1) == false) then return end
log_renderer:add_log(string.format("Missed %s's %s due to spread", engine.get_player_info(shot_info.player_index).name, hitbox_strings[shot_info.hitbox]), menu.get(menu_items.index_miss_color):get_color())
end,
notify_player_hit = function(self, shot_info, event)
if(menu.get(menu_items.index_log_selection):get_multiselection_item(0) == false) then return end
log_renderer:add_log(string.format("Hit %s in %s(%s) for %d(%d) [%d health remaining]", engine.get_player_info(shot_info.player_index).name, hitgroup_strings[event:get_int("hitgroup")], hitbox_strings[shot_info.hitbox], event:get_int("dmg_health"), shot_info.damage, clamp(shot_info.player:get_netvar_int("m_iHealth") - event:get_int("dmg_health"), 0, 100)), menu.get(menu_items.index_hit_color):get_color())
end,
run_miss_tracker = function(self)
for _, unclaimed_shot in pairs(self.unclaimed_shots) do
local player_index = unclaimed_shot.player_index
-- Shot timeout, assume unknown
if(global_vars.get_real_time() - unclaimed_shot.creation_time >= ABANDON_LOG_UNKOWN_TIMEOUT) then
self:notify_player_miss_unknown(unclaimed_shot)
self.unclaimed_shots[_] = nil
goto finish_run_miss_tracker
end
local resolver_misses = ragebot.get_missed_shots_resolver(player_index)
local spread_misses = ragebot.get_missed_shots_spread(player_index)
if(self.player_data[player_index].resolver_misses < resolver_misses) then
self:notify_player_miss_resolver(unclaimed_shot)
self.player_data[player_index].resolver_misses = resolver_misses
self.unclaimed_shots[_] = nil
goto finish_run_miss_tracker
end
if(self.player_data[player_index].spread_misses < spread_misses) then
self:notify_player_miss_spread(unclaimed_shot)
self.player_data[player_index].spread_misses = spread_misses
self.unclaimed_shots[_] = nil
goto finish_run_miss_tracker
end
::finish_run_miss_tracker::
-- Found the reason we missed the shot, exit early.
end
end,
run_hit_tracker = function(self, player_index, event)
for _, unclaimed_shot in pairs(self.unclaimed_shots) do
if(player_index == unclaimed_shot.player_index) then
self:notify_player_hit(unclaimed_shot, event)
self.unclaimed_shots[_] = nil
goto finish_run_hit_tracker
end
end
::finish_run_hit_tracker::
-- Confirmed we hit the guy, exit early.
end,
add_unclaimed_shot = function(self, player_index, shot_info)
local us = {
player_index = player_index,
player = shot_info.get_target,
damage = shot_info.get_damage,
damage_override = shot_info.get_damage_override,
backtrack = shot_info.get_backtrack,
hitbox = shot_info.get_hitbox,
creation_time = global_vars.get_real_time(),
}
table.insert(self.unclaimed_shots, us)
end,
}
hooks.add_callback("on_shot_info", function(shot_info)
ragebot_tracker:add_unclaimed_shot(shot_info.get_target:get_index(), shot_info)
end)
hooks.add_callback("on_event", function(event)
if(event:get_name() == "player_hurt") then
local attacker_uid = event:get_int("attacker")
local attacker_index = engine.get_player_for_uid(attacker_uid)
local localplayer = engine.get_local_player()
local localplayer_index = localplayer:get_index()
local victim_uid = event:get_int("userid")
local victim_index = engine.get_player_for_uid(victim_uid)
if(attacker_index == localplayer_index) then
ragebot_tracker:run_hit_tracker(victim_index, event)
end
end
end)
hooks.add_callback("on_draw", function()
ragebot_tracker:run_miss_tracker()
log_renderer:render_logs()
end)
ragebot_tracker:initialize()
log_renderer:add_log(string.format("--== BEGIN RIFK7 HITLOGS ==--"), menu.get(menu_items.index_hit_color):get_color())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment