994 lines
38 KiB
Plaintext
994 lines
38 KiB
Plaintext
|
xml = nil
|
||
|
script_table = {}
|
||
|
local gc = game.translate_string
|
||
|
local parse_keys = utils_data.parse_string_keys
|
||
|
|
||
|
local debug = false
|
||
|
local function pr(...)
|
||
|
if debug then
|
||
|
printf(...)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
faction_encyption = {
|
||
|
["army"] = 30 ,
|
||
|
["bandit"] = 0 ,
|
||
|
["csky"] = 20 ,
|
||
|
["dolg"] = 40 ,
|
||
|
["ecolog"] = 30 ,
|
||
|
["freedom"] = 20 ,
|
||
|
["killer"] = 40 ,
|
||
|
["stalker"] = 10 ,
|
||
|
["monolith"] = 50 ,
|
||
|
-- factions below this are commented out in vanilla
|
||
|
["renegade"] = 10 ,
|
||
|
["greh"] = 30 ,
|
||
|
["isg"] = 50,
|
||
|
}
|
||
|
|
||
|
colors_str = {
|
||
|
["decrypt"] = "%c[255, 123, 217, 76]",
|
||
|
["cmdup"] = "%c[255, 63, 192, 255]",
|
||
|
["rescan"] = "%c[255, 54, 217, 136]",
|
||
|
["nuke"] = "%c[255, 255, 255, 255]",
|
||
|
["bruteforce"] = "%c[255, 255, 255, 63]",
|
||
|
["skey"] = "%c[255, 0, 0, 0]",
|
||
|
["extract"] = "%c[255, 255, 184, 28]",
|
||
|
["terminal"] = "%c[255, 150, 150, 150]",
|
||
|
["failed"] = "%c[255, 238, 28, 36]",
|
||
|
}
|
||
|
|
||
|
colors_argb = {
|
||
|
["decrypt"] = GetARGB(255, 123, 217, 76),
|
||
|
["cmdup"] = GetARGB(255, 63, 192, 255),
|
||
|
["rescan"] = GetARGB(255, 54, 217, 136),
|
||
|
["nuke"] = GetARGB(255, 255, 255, 255),
|
||
|
["bruteforce"] = GetARGB(255, 255, 255, 63),
|
||
|
["skey"] = GetARGB(255, 0, 0, 0),
|
||
|
["extract"] = GetARGB(255, 255, 184, 28),
|
||
|
["failed"] = GetARGB(255, 238, 28, 36),
|
||
|
}
|
||
|
|
||
|
pda_rarity_encryption_mult = {
|
||
|
["itm_pda_common"] = 1 , ["itm_pda_uncommon"] = 1.5, ["itm_pda_rare"] = 2,
|
||
|
["itm_pda_encrypted_common"] = 1 , ["itm_pda_encrypted_uncommon"] = 1.5, ["itm_pda_encrypted_rare"] = 2, -- Compatibility with "Better Encryption Overhaul"
|
||
|
}
|
||
|
|
||
|
base_init = ui_pda_npc_tab.pda_npc_tab.InitControls
|
||
|
function ui_pda_npc_tab.pda_npc_tab:InitControls()
|
||
|
base_init(self)
|
||
|
xml = CScriptXmlInit()
|
||
|
xml:ParseFile("ui_pda_hacking.xml")
|
||
|
end
|
||
|
|
||
|
base_reset = ui_pda_npc_tab.pda_npc_tab.Reset
|
||
|
function ui_pda_npc_tab.pda_npc_tab:Reset(info)
|
||
|
self.form_text:Show(false)
|
||
|
|
||
|
base_reset(self, info)
|
||
|
|
||
|
if self.form_hack then
|
||
|
self.form_hack:Show(false)
|
||
|
end
|
||
|
if self.hack_button then
|
||
|
self.hack_button:Show(false)
|
||
|
end
|
||
|
if self.dark_overlay then
|
||
|
self.dark_overlay:Show(false)
|
||
|
end
|
||
|
|
||
|
RemoveTimeEvent("pdahack", "setfail")
|
||
|
RemoveTimeEvent("pdahack", "set_decrypt_bar")
|
||
|
RemoveTimeEvent("pdahack", "unlockpda")
|
||
|
|
||
|
if self.snd_skey and self.snd_skey:playing() then
|
||
|
self.snd_skey:stop()
|
||
|
end
|
||
|
|
||
|
local pda_sec = db.actor:active_item() and db.actor:active_item():section()
|
||
|
if not pda_sec then return end
|
||
|
|
||
|
if not (self.state == "encrypted") then return end
|
||
|
|
||
|
self.pda_info = info
|
||
|
|
||
|
if self.pda_info.attempted_hack then
|
||
|
self.form_text:SetText(gc("ui_st_npc_pda_access_denied") .. "\\n\\n" .. gc("ui_st_pdahacking_failed"))
|
||
|
return
|
||
|
end
|
||
|
self.form_text:SetText(gc("ui_st_npc_pda_access_denied"))
|
||
|
|
||
|
local best_hack_device = { ["section"] = nil, ["commands"] = 0, ["scripts"] = 0, ["extracts"] = 0}
|
||
|
db.actor:iterate_inventory(function(npc, item)
|
||
|
local sec = item:section()
|
||
|
local cmd_points = SYS_GetParam(2, sec, "command_points", 0)
|
||
|
if cmd_points > best_hack_device.commands then
|
||
|
best_hack_device.section = sec
|
||
|
best_hack_device.commands = cmd_points
|
||
|
best_hack_device.scripts = SYS_GetParam(2, sec, "initial_scripts", 0)
|
||
|
best_hack_device.extracts = SYS_GetParam(2, sec, "currency_extracts", 0)
|
||
|
end
|
||
|
end)
|
||
|
if best_hack_device.commands == 0 then return end
|
||
|
|
||
|
self.snd_unlock = xr_sound.get_safe_sound_object( "pda_hacking\\unlocked" )
|
||
|
self.snd_failed = xr_sound.get_safe_sound_object( "pda_hacking\\failed" )
|
||
|
self.snd_skey = xr_sound.get_safe_sound_object( "pda_hacking\\normal_hacking_sound" )
|
||
|
|
||
|
self.hack_button = self.hack_button or xml:Init3tButton("form:hack_button", self)
|
||
|
self:Register(self.hack_button, "hack_button")
|
||
|
self:AddCallback("hack_button", ui_events.BUTTON_CLICKED, self.Start_Hack, self)
|
||
|
self.hack_button:Show(true)
|
||
|
|
||
|
self.cmds_remaining = best_hack_device.commands --20 + (faction_encyption[info.contact.comm] / 5)
|
||
|
local encryption = faction_encyption[self.pda_info.contact.comm]
|
||
|
local rarity_mult = pda_rarity_encryption_mult[pda_sec] or 1
|
||
|
self.encryption_strength_base = clamp(round_idp(encryption * rarity_mult, 1), 0, 100)
|
||
|
self.encryption_strength = self.encryption_strength_base
|
||
|
self.encryption_strength_visual = self.encryption_strength_base
|
||
|
self.data_decrypted = 0
|
||
|
self.data_decrypted_target = 0
|
||
|
self.scripts_to_add = 0
|
||
|
self.extracts_remaining = best_hack_device.extracts - (self.pda_info.extracts_used or 0)
|
||
|
self.skey_unlock = false
|
||
|
|
||
|
self.form_hack = self.form_hack or xml:InitStatic("form", self)
|
||
|
self.form_hack.border = self.form_hack.border or xml:InitFrame("form:border", self.form_hack)
|
||
|
|
||
|
self.cmd_wnd = self.cmd_wnd or xml:InitStatic("form:cmd_wnd", self.form_hack)
|
||
|
self.cmd_wnd.title = self.cmd_wnd.title or xml:InitTextWnd("form:cmd_wnd:title", self.cmd_wnd)
|
||
|
self.cmd_wnd.title:SetFont(get_font("large"))
|
||
|
self.cmd_wnd.icon = self.cmd_wnd.icon or xml:InitStatic("form:cmd_wnd:icon", self.cmd_wnd)
|
||
|
self.cmd_wnd.number = self.cmd_wnd.number or xml:InitTextWnd("form:cmd_wnd:number", self.cmd_wnd)
|
||
|
self.cmd_wnd.number:SetText(self.cmds_remaining)
|
||
|
self.cmd_wnd.number:SetFont(get_font("huge"))
|
||
|
|
||
|
self.cmd_wnd.cost_line = self.cmd_wnd.cost_line or xml:InitStatic("form:cmd_wnd:cost_line", self.cmd_wnd)
|
||
|
self.cmd_wnd.cost_line.cost_text = self.cmd_wnd.cost_line.cost_text or xml:InitStatic("form:cmd_wnd:cost_line:cost_text", self.cmd_wnd.cost_line)
|
||
|
self.cmd_wnd.cost_line.icon = self.cmd_wnd.cost_line.icon or xml:InitStatic("form:cmd_wnd:cost_line:icon", self.cmd_wnd.cost_line)
|
||
|
self.cmd_wnd.cost_line.cost = self.cmd_wnd.cost_line.cost or xml:InitStatic("form:cmd_wnd:cost_line:cost", self.cmd_wnd.cost_line)
|
||
|
self.cmd_wnd.cost_line.cost_text:TextControl():SetFont(get_font("large"))
|
||
|
self.cmd_wnd.cost_line.cost:TextControl():SetFont(get_font("large"))
|
||
|
|
||
|
self.script_wnd = self.script_wnd or xml:InitStatic("form:script_wnd", self.form_hack)
|
||
|
self.script_wnd.title = self.script_wnd.title or xml:InitStatic("form:script_wnd:title", self.script_wnd)
|
||
|
self.script_wnd.title:TextControl():SetFont(get_font("large"))
|
||
|
self.script_wnd.scriptname = self.script_wnd.scriptname or xml:InitTextWnd("form:script_wnd:scriptname", self.script_wnd)
|
||
|
self.script_wnd.scriptname:SetFont(get_font("large"))
|
||
|
self.script_wnd.powertxt = self.script_wnd.powertxt or xml:InitStatic("form:script_wnd:powertxt", self.script_wnd)
|
||
|
self.script_wnd.powertxt:TextControl():SetFont(get_font("large"))
|
||
|
self.script_wnd.powernumber = self.script_wnd.powernumber or xml:InitStatic("form:script_wnd:powernumber", self.script_wnd)
|
||
|
self.script_wnd.powernumber:TextControl():SetFont(get_font("large"))
|
||
|
self.script_wnd:Show(false)
|
||
|
|
||
|
self.script_list_wnd = self.script_list_wnd or xml:InitStatic("form:script_list_wnd", self.form_hack)
|
||
|
self.script_list_wnd.title = self.script_list_wnd.title or xml:InitStatic("form:script_list_wnd:title", self.script_list_wnd)
|
||
|
self.script_list_wnd.title:TextControl():SetFont(get_font("large"))
|
||
|
self.hack_script_list = self.hack_script_list or xml:InitListBox("form:script_list_wnd:list", self.script_list_wnd)
|
||
|
self:Register(self.hack_script_list, "hack_script_list")
|
||
|
self:AddCallback("hack_script_list",ui_events.LIST_ITEM_CLICKED,self.OnSelectScript,self)
|
||
|
self.hack_script_list:RemoveAll()
|
||
|
|
||
|
self.cmd_list_wnd = self.cmd_list_wnd or xml:InitStatic("form:cmd_list_wnd", self.form_hack)
|
||
|
self.cmd_list_wnd.title = self.cmd_list_wnd.title or xml:InitStatic("form:cmd_list_wnd:title", self.cmd_list_wnd)
|
||
|
self.cmd_list_wnd.title:TextControl():SetFont(get_font("large"))
|
||
|
self.command_list = self.command_list or xml:InitListBox("form:cmd_list_wnd:list", self.cmd_list_wnd)
|
||
|
self:Register(self.command_list, "command_list")
|
||
|
self:AddCallback("command_list",ui_events.LIST_ITEM_CLICKED,self.OnSelectCommand,self)
|
||
|
self.command_list:RemoveAll()
|
||
|
self.cmd_list_wnd:Show(false)
|
||
|
|
||
|
self.terminal_form = self.terminal_form or xml:InitStatic("form:terminal_wnd", self.form_hack)
|
||
|
self.terminal = self.terminal or xml:InitStatic("form:terminal_wnd:terminal", self.terminal_form)
|
||
|
self.terminal.prompt_wnd = self.terminal.prompt_wnd or xml:InitTextWnd("form:terminal_wnd:terminal:prompt_wnd", self.terminal)
|
||
|
self.terminal.prompt_wnd:SetFont(get_font("medium"))
|
||
|
self.terminal.prompt_wnd:SetEllipsis(true)
|
||
|
|
||
|
self.terminal.text_wnd = self.terminal.text_wnd or xml:InitTextWnd("form:terminal_wnd:terminal:text_wnd", nil)
|
||
|
self.terminal.text_wnd:SetFont(get_font("medium"))
|
||
|
self.terminal.text_wnd:SetText(gc("ui_st_pdahacking_welcome"))
|
||
|
if not self.terminal_scroll then
|
||
|
self.terminal_scroll = xml:InitScrollView("form:terminal_wnd:terminal:terminal_scroll", self.terminal)
|
||
|
self.terminal_scroll:AddWindow(self.terminal.text_wnd, true)
|
||
|
self.terminal.text_wnd:SetAutoDelete(false)
|
||
|
end
|
||
|
|
||
|
self.decrypt_wnd = self.decrypt_wnd or xml:InitStatic("form:decrypt_wnd", self.form_hack)
|
||
|
self.decrypt_wnd.bg = self.decrypt_wnd.bg or xml:InitStatic("form:decrypt_wnd:prog_back", self.decrypt_wnd)
|
||
|
self.decrypt_wnd.bar = self.decrypt_wnd.bar or xml:InitProgressBar("form:decrypt_wnd:decrypt_bar", self.decrypt_wnd)
|
||
|
self.decrypt_wnd.bar:SetProgressPos( 0 )
|
||
|
|
||
|
self.decrypt_wnd.title = self.decrypt_wnd.title or xml:InitStatic("form:decrypt_wnd:title", self.decrypt_wnd)
|
||
|
self.decrypt_wnd.title:TextControl():SetFont(get_font("large"))
|
||
|
self.decrypt_wnd.encr_str = self.decrypt_wnd.encr_str or xml:InitStatic("form:decrypt_wnd:encr_str", self.decrypt_wnd)
|
||
|
self.decrypt_wnd.encr_str.icon = self.decrypt_wnd.encr_str.icon or xml:InitStatic("form:decrypt_wnd:encr_str:icon", self.decrypt_wnd.encr_str)
|
||
|
self.decrypt_wnd.encr_str.pct = self.decrypt_wnd.encr_str.pct or xml:InitTextWnd("form:decrypt_wnd:encr_str:str_pct", self.decrypt_wnd.encr_str)
|
||
|
self.decrypt_wnd.encr_str.pct:SetText( self.encryption_strength .. "%")
|
||
|
self.decrypt_wnd.encr_str.pct:SetFont(get_font("large"))
|
||
|
|
||
|
self.decrypt_wnd.rarity_title = self.decrypt_wnd.rarity_title or xml:InitStatic("form:decrypt_wnd:rarity_title", self.decrypt_wnd)
|
||
|
self.decrypt_wnd.rarity_title:TextControl():SetFont(get_font("large"))
|
||
|
self.decrypt_wnd.rarity_title:TextControl():SetText( gc("actor_" .. self.pda_info.contact.comm) .. ", " .. gc("st_pdahacking_rarity_" .. pda_sec) .. " " .. gc("st_pda_name"))
|
||
|
|
||
|
self.decrypt_wnd.decrypted = self.decrypt_wnd.decrypted or xml:InitStatic("form:decrypt_wnd:decrypted", self.decrypt_wnd)
|
||
|
self.decrypt_wnd.decrypted.title = self.decrypt_wnd.decrypted.title or xml:InitStatic("form:decrypt_wnd:decrypted:title", self.decrypt_wnd.decrypted)
|
||
|
self.decrypt_wnd.decrypted.title:TextControl():SetFont(get_font("large"))
|
||
|
self.decrypt_wnd.decrypted.pct_bg = self.decrypt_wnd.decrypted.pct_bg or xml:InitStatic("form:decrypt_wnd:decrypted:pct_bg", self.decrypt_wnd.decrypted)
|
||
|
self.decrypt_wnd.decrypted.pct_bg:TextControl():SetFont(get_font("huge"))
|
||
|
self.decrypt_wnd.decrypted.pct_bg:TextControl():SetText( round_idp(self.data_decrypted, 1) .. "%")
|
||
|
|
||
|
self.dark_overlay = self.dark_overlay or xml:InitStatic("dark_overlay", self)
|
||
|
self.dark_overlay.status_title = self.dark_overlay.status_title or xml:InitStatic("dark_overlay:status_title", self.dark_overlay)
|
||
|
self.dark_overlay.status_title:TextControl():SetFont(get_font("huge"))
|
||
|
self.dark_overlay:Show(false)
|
||
|
|
||
|
self.form_hack:Show(false)
|
||
|
|
||
|
-- Build table of scripts from Anomaly install. Includes both vanilla and mod scripts
|
||
|
script_table = {}
|
||
|
local temp_script_t = {} -- keep track of duplicates
|
||
|
for k, v in pairs(_G) do
|
||
|
if type(_G[k]) == "table" then
|
||
|
local script_name = k:gsub("_mcm", "")
|
||
|
script_name = script_name:gsub("^(z+_)+", "")
|
||
|
--script_name = script_name:gsub("^z+_", "")
|
||
|
|
||
|
if not temp_script_t[script_name] and script_name:len() >= 3 then
|
||
|
temp_script_t[script_name] = true
|
||
|
script_table[#script_table+1] = script_name
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
self:Generate_Scripts(best_hack_device.scripts)
|
||
|
end
|
||
|
|
||
|
base_update = ui_pda_npc_tab.pda_npc_tab.Update
|
||
|
function ui_pda_npc_tab.pda_npc_tab:Update()
|
||
|
base_update(self)
|
||
|
|
||
|
if not (self.form_hack and self.form_hack:IsShown()) then return end
|
||
|
|
||
|
if self.skey_unlock and self.dark_overlay.status_title:IsShown() then
|
||
|
local time = get_time_elapsed()
|
||
|
if round(time * 3) % 3 == 0 then
|
||
|
if round(time * 50) % 5 == 0 then
|
||
|
local scrambled_title = scramble_string(self.skey_title)
|
||
|
self.dark_overlay.status_title:TextControl():SetText(scrambled_title)
|
||
|
--self.dark_overlay.status_title:TextControl():SetTextColor(GetARGB(255, 0, 0, 0))
|
||
|
end
|
||
|
else
|
||
|
self.dark_overlay.status_title:TextControl():SetText(self.skey_title)
|
||
|
--self.dark_overlay.status_title:TextControl():SetTextColor(GetARGB(255, 55, 55, 55))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local prompt_set = false
|
||
|
if self.command_list then
|
||
|
for i = 0, self.command_list:GetSize() do
|
||
|
local item = self.command_list:GetItemByIndex(i)
|
||
|
if item and item.name == "SkeletonKey" and round(get_time_elapsed() * 55) % 5 == 0 then
|
||
|
item.str_title:SetText(scramble_string(gc("ui_st_pdahacking_skey") .. "#&$"))
|
||
|
end
|
||
|
if item and item:IsCursorOverWindow() then
|
||
|
if item.name == "SkeletonKey" then
|
||
|
if round(get_time_elapsed() * 50) % 5 == 0 then
|
||
|
self.terminal.prompt_wnd:SetText(gc("ui_st_pdahacking_preprompt") .. parse_keys(gc("ui_st_pdahacking_run"),{ ["name"] = scramble_string(gc("ui_st_pdahacking_skey"))}))
|
||
|
end
|
||
|
prompt_set = true
|
||
|
else
|
||
|
self.terminal.prompt_wnd:SetText(gc("ui_st_pdahacking_preprompt") .. parse_keys(gc("ui_st_pdahacking_run"),{ ["name"] = gc("ui_st_pdahacking_" .. name_key[item.name])}))
|
||
|
prompt_set = true
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if self.terminal and self.terminal.prompt_wnd and not prompt_set then
|
||
|
local mod = round(get_time_elapsed() * 4) % 4
|
||
|
if mod == 0 or mod == 2 then
|
||
|
self.terminal.prompt_wnd:SetText(gc("ui_st_pdahacking_preprompt"))
|
||
|
else
|
||
|
self.terminal.prompt_wnd:SetText(gc("ui_st_pdahacking_preprompt_us"))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if self.hack_script_list then
|
||
|
for i = 0, self.hack_script_list:GetSize() do
|
||
|
local item = self.hack_script_list:GetItemByIndex(i)
|
||
|
if item and item:IsCursorOverWindow() then
|
||
|
self.terminal.prompt_wnd:SetText(gc("ui_st_pdahacking_preprompt") .. parse_keys(gc("ui_st_pdahacking_load"),{ ["script"] = item.name}))
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
ui_pda_npc_tab.pda_npc_tab.OnSelectScript = function(self)
|
||
|
if self.data_decrypted_target >= 100 then return end
|
||
|
if self.scripts_to_add > 0 then return end
|
||
|
if self.loaded_script and self.loaded_script.name == self.hack_script_list:GetSelectedItem().name then return end
|
||
|
if self.cmds_remaining <= 0 then return end
|
||
|
|
||
|
self.command_list:RemoveAll()
|
||
|
|
||
|
if self.loaded_script then
|
||
|
self.loaded_script.str_title:SetTextColor(GetARGB(255, 255, 255, 255))
|
||
|
end
|
||
|
self.loaded_script = self.hack_script_list:GetSelectedItem()
|
||
|
self.loaded_script.str_title:SetTextColor(colors_argb.rescan)
|
||
|
|
||
|
self.script_wnd.scriptname:SetText(self.loaded_script.name .. ".script")
|
||
|
self.script_wnd.powernumber:TextControl():SetText(self.loaded_script.power)
|
||
|
self.script_wnd:Show(true)
|
||
|
|
||
|
local total_power = self.loaded_script.power
|
||
|
|
||
|
math.randomseed( self.loaded_script.seed )
|
||
|
|
||
|
if math.random() <= 0.40 then
|
||
|
self.command_list:AddExistingItem(command_entry("CommandUp", total_power))
|
||
|
end
|
||
|
if math.random() <= 0.40 then
|
||
|
self.command_list:AddExistingItem(command_entry("Re-Scan", total_power))
|
||
|
end
|
||
|
if math.random() <= 0.40 then
|
||
|
self.command_list:AddExistingItem(command_entry("BruteForce", total_power))
|
||
|
end
|
||
|
if math.random() <= 0.40 and self.encryption_strength > 0 then
|
||
|
self.command_list:AddExistingItem(command_entry("Nuke", total_power, self.encryption_strength))
|
||
|
end
|
||
|
if math.random() <= 0.01 then -- 0.01
|
||
|
self.command_list:AddExistingItem(command_entry("SkeletonKey", total_power))
|
||
|
end
|
||
|
if math.random() <= 0.40 or self.command_list:GetSize() == 0 then
|
||
|
self.command_list:AddExistingItem(command_entry("Decrypt", total_power, self.encryption_strength))
|
||
|
end
|
||
|
if math.random() <= 0.10 and self.extracts_remaining > 0 and settings.extract_reward_mult > 0 then
|
||
|
self.command_list:AddExistingItem(command_entry("Extract", total_power, self.encryption_strength, self.encryption_strength_base))
|
||
|
end
|
||
|
|
||
|
self.cmd_list_wnd:Show(true)
|
||
|
|
||
|
self:Change_Commands(-1)
|
||
|
|
||
|
local text = parse_keys(gc("ui_st_pdahacking_loaded"), {["script"] = self.loaded_script.name})
|
||
|
self:Write_Terminal(text)
|
||
|
end
|
||
|
|
||
|
ui_pda_npc_tab.pda_npc_tab.OnSelectCommand = function(self)
|
||
|
if self.data_decrypted_target >= 100 then return end
|
||
|
local item = self.command_list:GetSelectedItem()
|
||
|
if item.name ~= "CommandUp" and self.cmds_remaining <= 0 then return end
|
||
|
|
||
|
if item.name == "Nuke" then
|
||
|
local nuke_effect = get_nuke_effect(item.power, self.encryption_strength)
|
||
|
self:Change_Encryption(nuke_effect)
|
||
|
self.hack_script_list:RemoveItem(self.loaded_script)
|
||
|
|
||
|
local effect_str = "%" .. colors_str.nuke .. "-" .. round_idp(nuke_effect, 1) .. "%%%" .. colors_str.terminal
|
||
|
self:Write_Terminal(parse_keys(gc("ui_st_pdahacking_running"), {["name"] = gc("ui_st_pdahacking_" .. name_key[item.name]), ["effect"] = effect_str}))
|
||
|
elseif item.name == "Decrypt" then
|
||
|
local decrypt_effect = get_decrypt_effect(item.power, self.encryption_strength)
|
||
|
if decrypt_effect <= 0 then return end
|
||
|
self:Set_Data_Decrypted(self.data_decrypted + decrypt_effect)
|
||
|
self.hack_script_list:RemoveItem(self.loaded_script)
|
||
|
|
||
|
local effect_str = "%" .. colors_str.decrypt .. "+" .. round_idp(decrypt_effect, 1) .. "%%%" .. colors_str.terminal
|
||
|
self:Write_Terminal(parse_keys(gc("ui_st_pdahacking_running"), {["name"] = gc("ui_st_pdahacking_" .. name_key[item.name]), ["effect"] = effect_str}))
|
||
|
elseif item.name == "Re-Scan" then
|
||
|
self.hack_script_list:RemoveItem(self.loaded_script)
|
||
|
local gen_count = get_rescan_count(item.power)
|
||
|
self:Generate_Scripts(gen_count)
|
||
|
self.hack_script_list:Show(true)
|
||
|
|
||
|
local effect_str = "%" .. colors_str.rescan .. "+" .. gen_count .. "%" .. colors_str.terminal
|
||
|
self:Write_Terminal(parse_keys(gc("ui_st_pdahacking_running"), {["name"] = gc("ui_st_pdahacking_" .. name_key[item.name]), ["effect"] = effect_str}))
|
||
|
elseif item.name == "CommandUp" then
|
||
|
local cmd_bonus = get_command_up(item.power)
|
||
|
self:Change_Commands(cmd_bonus)
|
||
|
self.hack_script_list:RemoveItem(self.loaded_script)
|
||
|
|
||
|
local effect_str = "%" .. colors_str.cmdup .. "+" .. cmd_bonus .. "%" .. colors_str.terminal
|
||
|
self:Write_Terminal(parse_keys(gc("ui_st_pdahacking_running"), {["name"] = gc("ui_st_pdahacking_" .. name_key[item.name]), ["effect"] = effect_str}))
|
||
|
elseif item.name =="BruteForce" then
|
||
|
local chance = get_brute_chance(item.power)
|
||
|
|
||
|
local effect_str = "%" .. colors_str.bruteforce .. round_idp(chance, 1) .. "%%%" .. colors_str.terminal
|
||
|
local text = parse_keys(gc("ui_st_pdahacking_running"), {["name"] = gc("ui_st_pdahacking_" .. name_key[item.name]), ["effect"] = effect_str})
|
||
|
|
||
|
if chance > (math.random() * 100) then
|
||
|
self:Set_Data_Decrypted(100)
|
||
|
text = text .. "... " .. colors_str.decrypt .. gc("ui_st_pdahacking_bruteforce_success")
|
||
|
else
|
||
|
text = text .. "... " .. colors_str.failed .. gc("ui_st_pdahacking_bruteforce_fail")
|
||
|
end
|
||
|
self:Write_Terminal(text)
|
||
|
self.hack_script_list:RemoveItem(self.loaded_script)
|
||
|
elseif item.name == "Extract" then
|
||
|
local extracted_ru = get_extract_money(item.power, self.encryption_strength_base)
|
||
|
db.actor:give_money(extracted_ru)
|
||
|
local header = gc("ui_st_pdahacking_extract_header")
|
||
|
local msg = parse_keys(gc("ui_st_pdahacking_extract_msg"), { ["income"] = extracted_ru })
|
||
|
xr_sound.set_sound_play(AC_ID, "pda_tips")
|
||
|
db.actor:give_game_news(header, msg, "ui_inGame2_PD_Sostoyatelniy_klient", 0, 5000)
|
||
|
|
||
|
self.extracts_remaining = self.extracts_remaining - 1
|
||
|
self.pda_info.extracts_used = self.pda_info.extracts_used and (self.pda_info.extracts_used + 1) or 1
|
||
|
self.hack_script_list:RemoveItem(self.loaded_script)
|
||
|
|
||
|
local effect_str = "%" .. colors_str.extract .. "+" .. gc("ui_st_pdahacking_ruble") .. extracted_ru .. "%" .. colors_str.terminal
|
||
|
self:Write_Terminal(parse_keys(gc("ui_st_pdahacking_running"), {["name"] = gc("ui_st_pdahacking_" .. name_key[item.name]), ["effect"] = effect_str}))
|
||
|
elseif item.name == "SkeletonKey" then
|
||
|
self:Set_Data_Decrypted(100)
|
||
|
self.skey_unlock = true
|
||
|
|
||
|
if self.snd_skey and settings.soundfx_volume > 0 then
|
||
|
self.snd_skey.volume = 1 * settings.soundfx_volume
|
||
|
self.snd_skey:play(db.actor, 0, sound_object.s2d)
|
||
|
end
|
||
|
|
||
|
self.dark_overlay:Show(true)
|
||
|
self.dark_overlay.status_title:Show(false)
|
||
|
local skey_used_before = load_var(db.actor, "pdahack_skeys_used", 0)
|
||
|
local str_index = skey_used_before
|
||
|
if str_index >= 7 then
|
||
|
str_index = str_index % 7
|
||
|
end
|
||
|
self.skey_title = gc("ui_st_pdahacking_skey_" .. str_index)
|
||
|
save_var(db.actor, "pdahack_skeys_used", skey_used_before + 1)
|
||
|
|
||
|
CreateTimeEvent("pdahack", "show_skey_status", 1, function()
|
||
|
local h = hit()
|
||
|
h.type = hit.telepatic
|
||
|
h.power = 0.2
|
||
|
h.impulse = 1
|
||
|
h.direction = VEC_Z
|
||
|
h.draftsman = db.actor
|
||
|
db.actor:hit(h)
|
||
|
|
||
|
self.dark_overlay.status_title:TextControl():SetTextColor(GetARGB(255, 0, 0, 0))
|
||
|
--self.dark_overlay.status_title:TextControl():SetTextColor(GetARGB(255, 55, 55, 55))
|
||
|
self.dark_overlay.status_title:TextControl():SetText(self.skey_title)
|
||
|
self.dark_overlay.status_title:Show(true)
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
self.loaded_script = nil
|
||
|
self.command_list:RemoveAll()
|
||
|
if not (item.name == "CommandUp") then
|
||
|
self:Change_Commands(-1)
|
||
|
end
|
||
|
self.cmd_list_wnd:Show(false)
|
||
|
self.script_wnd:Show(false)
|
||
|
|
||
|
--[[ pr("scroll pos " .. self.hack_script_list:GetCurrentScrollPos())
|
||
|
if self.hack_script_list:GetSize() * 27 > self.hack_script_list:GetCurrentScrollPos() then
|
||
|
self.hack_script_list:ScrollToEnd()
|
||
|
end ]]
|
||
|
|
||
|
if self.hack_script_list:GetSize() == 0 and self.data_decrypted_target < 100 and self.scripts_to_add <= 0 then
|
||
|
self:HackFailed()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function ui_pda_npc_tab.pda_npc_tab:Start_Hack()
|
||
|
self.form_text:Show(false)
|
||
|
self.hack_button:Show(false)
|
||
|
self.form_hack:Show(true)
|
||
|
self.hack_script_list:Show(true)
|
||
|
self.pda_info.attempted_hack = true
|
||
|
end
|
||
|
|
||
|
function ui_pda_npc_tab.pda_npc_tab:Change_Commands(change)
|
||
|
if change < 0 then
|
||
|
self.cmd_wnd.number:SetText(self.cmds_remaining .. " -1")
|
||
|
self.cmds_remaining = self.cmds_remaining + change
|
||
|
CreateTimeEvent("pdahack", "set_cmd_text", 0.4, function()
|
||
|
self.cmd_wnd.number:SetText(self.cmds_remaining)
|
||
|
return true
|
||
|
end)
|
||
|
|
||
|
local cmd_up_in_list = false
|
||
|
for i = 0, self.command_list:GetSize() do
|
||
|
local cmd_item = self.command_list:GetItemByIndex(i)
|
||
|
if cmd_item and cmd_item.name == "CommandUp" then
|
||
|
cmd_up_in_list = true
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
if self.cmds_remaining <= 0 and self.data_decrypted_target < 100 and not cmd_up_in_list then
|
||
|
self:HackFailed()
|
||
|
end
|
||
|
elseif change > 0 then
|
||
|
self.cmd_wnd.number:SetText(self.cmds_remaining .. " +" .. change)
|
||
|
self.cmds_remaining = self.cmds_remaining + change
|
||
|
CreateTimeEvent("pdahack", "set_cmd_text", 0.4, function()
|
||
|
self.cmd_wnd.number:SetText(self.cmds_remaining)
|
||
|
return true
|
||
|
end)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function ui_pda_npc_tab.pda_npc_tab:HackFailed()
|
||
|
self.script_wnd:Show(false)
|
||
|
self.hack_script_list:Show(false)
|
||
|
self.cmd_list_wnd:Show(false)
|
||
|
self.hack_button:Show(false)
|
||
|
self.form_text:SetText(gc("ui_st_npc_pda_access_denied") .. "\\n\\n" .. gc("ui_st_pdahacking_failed"))
|
||
|
|
||
|
CreateTimeEvent("pdahack", "darkoverlay", 1, function()
|
||
|
if self.snd_failed and settings.soundfx_volume > 0 then
|
||
|
self.snd_failed.volume = 0.8 * settings.soundfx_volume
|
||
|
self.snd_failed:play(db.actor, 0, sound_object.s2d)
|
||
|
end
|
||
|
|
||
|
self.dark_overlay:Show(true)
|
||
|
self.dark_overlay.status_title:TextControl():SetTextColor(colors_argb.failed)
|
||
|
if self.cmds_remaining <= 0 then
|
||
|
self.dark_overlay.status_title:TextControl():SetText(gc("ui_st_pdahacking_outof_cmd"))
|
||
|
else
|
||
|
self.dark_overlay.status_title:TextControl():SetText(gc("ui_st_pdahacking_outof_scripts"))
|
||
|
end
|
||
|
return true
|
||
|
end)
|
||
|
|
||
|
CreateTimeEvent("pdahack", "setfail", 4, function()
|
||
|
self:Reset(self.pda_info)
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
function ui_pda_npc_tab.pda_npc_tab:Write_Terminal(text)
|
||
|
self.terminal_scroll:RemoveWindow(self.terminal.text_wnd)
|
||
|
self.terminal_scroll:Clear()
|
||
|
|
||
|
local console_text = self.terminal.text_wnd:GetText()
|
||
|
console_text = console_text .. "\\n" .. colors_str.terminal .. text
|
||
|
self.terminal.text_wnd:SetText(console_text)
|
||
|
|
||
|
local scroll_height = self.terminal_scroll:GetHeight()
|
||
|
self.terminal.text_wnd:AdjustHeightToText()
|
||
|
local term_text_height = self.terminal.text_wnd:GetHeight()
|
||
|
|
||
|
if term_text_height < scroll_height then
|
||
|
local width = self.terminal.text_wnd:GetWidth()
|
||
|
self.terminal.text_wnd:SetWndSize(vector2():set(width, scroll_height))
|
||
|
end
|
||
|
|
||
|
self.terminal_scroll:AddWindow(self.terminal.text_wnd, true)
|
||
|
self.terminal.text_wnd:SetAutoDelete(false)
|
||
|
self.terminal_scroll:ScrollToEnd()
|
||
|
end
|
||
|
|
||
|
function lerpup(start, target, step)
|
||
|
return start + step >= target and target or start + step
|
||
|
end
|
||
|
|
||
|
function ui_pda_npc_tab.pda_npc_tab:Set_Data_Decrypted(data)
|
||
|
self.data_decrypted_target = clamp(data, self.data_decrypted_target, 100)
|
||
|
if self.data_decrypted_target == 100 then
|
||
|
self.script_wnd:Show(false)
|
||
|
self.hack_script_list:Show(false)
|
||
|
self.pda_info.state = "default"
|
||
|
end
|
||
|
|
||
|
CreateTimeEvent("pdahack", "set_decrypt_bar", 0, function()
|
||
|
self.data_decrypted = lerpup(self.data_decrypted, self.data_decrypted_target, 0.75)
|
||
|
self.decrypt_wnd.bar:SetProgressPos( self.data_decrypted )
|
||
|
self.decrypt_wnd.decrypted.pct_bg:TextControl():SetText( round_idp(self.data_decrypted, 1) .. "%")
|
||
|
|
||
|
if self.data_decrypted >= 100 then
|
||
|
if not self.skey_unlock then
|
||
|
self.dark_overlay:Show(true)
|
||
|
self.dark_overlay.status_title:TextControl():SetText(gc("ui_st_pdahacking_unlocked"))
|
||
|
self.dark_overlay.status_title:TextControl():SetTextColor(colors_argb.decrypt)
|
||
|
|
||
|
if self.snd_unlock and settings.soundfx_volume > 0 then
|
||
|
self.snd_unlock.volume = 1 * settings.soundfx_volume
|
||
|
self.snd_unlock:play(db.actor, 0, sound_object.s2d)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local unlock_delay = self.skey_unlock and 5 or 3
|
||
|
|
||
|
CreateTimeEvent("pdahack", "unlockpda", unlock_delay, function()
|
||
|
self:Reset(self.pda_info)
|
||
|
end)
|
||
|
return true
|
||
|
elseif self.data_decrypted >= self.data_decrypted_target then
|
||
|
return true
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
function lerpdown(start, target, step)
|
||
|
return start - step <= target and target or start - step
|
||
|
end
|
||
|
|
||
|
function ui_pda_npc_tab.pda_npc_tab:Change_Encryption(change)
|
||
|
self.encryption_strength = self.encryption_strength - change
|
||
|
|
||
|
CreateTimeEvent("pdahack", "set_encrypt", 0, function()
|
||
|
self.encryption_strength_visual = lerpdown(self.encryption_strength_visual, self.encryption_strength, 0.1)
|
||
|
self.decrypt_wnd.encr_str.pct:SetText( round_idp(self.encryption_strength_visual, 1) .. "%")
|
||
|
if self.encryption_strength_visual <= self.encryption_strength then
|
||
|
return true
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
function ui_pda_npc_tab.pda_npc_tab:Generate_Scripts(count)
|
||
|
self.scripts_to_add = self.scripts_to_add + count
|
||
|
CreateTimeEvent("pdahack", "genscript", 0.1, function()
|
||
|
local index = math.random(#script_table)
|
||
|
|
||
|
local script_name = script_table[index]
|
||
|
table.remove(script_table, index)
|
||
|
|
||
|
local seed = get_seed_from_string(script_name)
|
||
|
math.randomseed( seed )
|
||
|
local rnd = math.random()
|
||
|
local min_power = settings.script_power_min --25
|
||
|
local max_power = clamp(settings.script_power_max, min_power, settings.script_power_max) --100
|
||
|
local power = (rnd * (max_power - min_power)) + min_power
|
||
|
power = round(power)
|
||
|
|
||
|
local item = script_message_entry(script_name, power, seed)
|
||
|
self.hack_script_list:AddExistingItem(item)
|
||
|
|
||
|
self.scripts_to_add = self.scripts_to_add - 1
|
||
|
if self.scripts_to_add <= 0 then return true end
|
||
|
ResetTimeEvent("pdahack", "genscript", 0.1)
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
function get_time_elapsed()
|
||
|
return (game.get_game_time():diffSec(level.get_start_time()) /level.get_time_factor())
|
||
|
end
|
||
|
|
||
|
function get_seed_from_string(string)
|
||
|
local seed = 0
|
||
|
for i = 1, string:len() do
|
||
|
seed = seed + string.byte(string, i)
|
||
|
end
|
||
|
return seed
|
||
|
end
|
||
|
|
||
|
function scramble_string(str)
|
||
|
local letters = {}
|
||
|
for letter in str:gmatch'.[\128-\191]*' do
|
||
|
table.insert(letters, {letter = letter, rnd = math.random()})
|
||
|
end
|
||
|
table.sort(letters, function(a, b) return a.rnd < b.rnd end)
|
||
|
for i, v in ipairs(letters) do letters[i] = v.letter end
|
||
|
return table.concat(letters)
|
||
|
end
|
||
|
|
||
|
-- HACK FORMULAS
|
||
|
function get_nuke_effect(power, encryption_strength)
|
||
|
return encryption_strength * (power * 0.2 / 100)
|
||
|
end
|
||
|
|
||
|
function get_decrypt_effect(power, encryption_strength)
|
||
|
return power * 0.30 * (1 - (encryption_strength / 100))
|
||
|
end
|
||
|
|
||
|
function get_brute_chance(power)
|
||
|
return (power / 8)
|
||
|
end
|
||
|
|
||
|
function get_command_up(power)
|
||
|
return math.floor(power / 12) + 1
|
||
|
end
|
||
|
|
||
|
function get_rescan_count(power)
|
||
|
return math.floor(power / 20) + 1
|
||
|
end
|
||
|
|
||
|
function get_extract_money(power, base_encryption_strength)
|
||
|
return math.ceil(power * 0.2 * clamp(base_encryption_strength, 20, 100)) * settings.extract_reward_mult
|
||
|
end
|
||
|
|
||
|
-- GUI
|
||
|
class "script_message_entry" (CUIListBoxItem)
|
||
|
|
||
|
function script_message_entry:__init(name, power, seed) super(name, power, seed)
|
||
|
self:GetTextItem():SetText("")
|
||
|
|
||
|
self.name = name
|
||
|
self.power = power
|
||
|
self.seed = seed
|
||
|
math.randomseed( seed + 1 )
|
||
|
self.hidden_power = math.random(0, 75)
|
||
|
|
||
|
local total_w = 155
|
||
|
local padding_h = 3
|
||
|
local padding_w = padding_h * 0.75
|
||
|
local target_h = 30 - padding_h
|
||
|
|
||
|
local icon_h = target_h - (padding_h * 2)
|
||
|
local icon_w = icon_h --[[ * 0.75 ]]
|
||
|
|
||
|
self.background = self:AddIconField(1)
|
||
|
self.background:InitTexture("ui_pdahack_bg_list")
|
||
|
self.background:SetStretchTexture(true)
|
||
|
self.background:SetTextureColor(GetARGB(60, 255, 255, 255))
|
||
|
self.background:SetWndPos(vector2():set(0, padding_h))
|
||
|
self.background:SetWndSize(vector2():set(total_w, target_h))
|
||
|
|
||
|
self.icon = self:AddIconField(1)
|
||
|
self.icon:InitTexture("ui_pdahack_icon_script")
|
||
|
self.icon:SetStretchTexture(true)
|
||
|
self.icon:SetTextureColor(colors_argb.rescan)
|
||
|
self.icon:SetWndPos(vector2():set(padding_w, padding_h * 2))
|
||
|
self.icon:SetWndSize(vector2():set(icon_w, icon_h))
|
||
|
|
||
|
self.str_title = self:AddTextField("",1)
|
||
|
self.str_title:SetWndPos(vector2():set(icon_w + padding_w * 2, padding_h))
|
||
|
self.str_title:SetWndSize(vector2():set(total_w - (padding_w * 2) - icon_w, target_h))
|
||
|
self.str_title:SetTextColor(GetARGB(255, 255, 255, 255))
|
||
|
self.str_title:SetFont(get_font("large"))
|
||
|
self.str_title:SetEllipsis(true)
|
||
|
self.str_title:SetTextAlignment(0)
|
||
|
self.str_title:SetVTextAlignment(2)
|
||
|
self.str_title:SetText(self.name .. ".script")
|
||
|
|
||
|
self.power_nr_bg = self:AddIconField(1)
|
||
|
self.power_nr_bg:InitTexture("ui_pdahack_bg_list")
|
||
|
self.power_nr_bg:SetStretchTexture(true)
|
||
|
self.power_nr_bg:SetTextureColor(GetARGB(120, 0, 0, 0))
|
||
|
self.power_nr_bg:SetWndPos(vector2():set(total_w + padding_w, padding_h))
|
||
|
self.power_nr_bg:SetWndSize(vector2():set(25 - padding_w, target_h))
|
||
|
|
||
|
self.power_nr = self:AddTextField("",1)
|
||
|
self.power_nr:SetWndPos(vector2():set(total_w, padding_h + 1))
|
||
|
self.power_nr:SetWndSize(vector2():set(25, target_h))
|
||
|
self.power_nr:SetTextColor(colors_argb.decrypt)
|
||
|
self.power_nr:SetFont(get_font("large"))
|
||
|
self.power_nr:SetTextAlignment(2)
|
||
|
self.power_nr:SetVTextAlignment(2)
|
||
|
self.power_nr:SetText(self.power)
|
||
|
end
|
||
|
|
||
|
class "command_entry" (CUIListBoxItem)
|
||
|
|
||
|
function command_entry:__init(name, power, encrypt_strength, base_encr_str) super(name, power, encrypt_strength, base_encr_str)
|
||
|
self:GetTextItem():SetText("")
|
||
|
|
||
|
self.name = name
|
||
|
self.power = power
|
||
|
|
||
|
local total_w = 154
|
||
|
local padding_h = 3
|
||
|
local padding_w = padding_h * 0.75
|
||
|
local target_h = 30 - padding_h
|
||
|
|
||
|
local icon_h = target_h - (padding_h * 2)
|
||
|
local icon_w = icon_h --[[ * 0.75 ]]
|
||
|
|
||
|
self.background = self:AddIconField(1)
|
||
|
self.background:InitTexture("ui_pdahack_bg_list")
|
||
|
self.background:SetStretchTexture(true)
|
||
|
self.background:SetTextureColor(GetARGB(60, 255, 255, 255))
|
||
|
self.background:SetWndSize(vector2():set(total_w, target_h))
|
||
|
self.background:SetWndPos(vector2():set(0, padding_h))
|
||
|
|
||
|
self.icon_hack = self:AddIconField(1)
|
||
|
self.icon_hack:InitTexture("ui_pdahack_icon_hack")
|
||
|
self.icon_hack:SetStretchTexture(true)
|
||
|
self.icon_hack:SetTextureColor(GetARGB(255, 191, 191, 191))
|
||
|
self.icon_hack:SetWndSize(vector2():set(icon_w, icon_h))
|
||
|
self.icon_hack:SetWndPos(vector2():set(padding_w, padding_h * 2))
|
||
|
|
||
|
self.str_title = self:AddTextField("",1)
|
||
|
self.str_title:SetWndRect(Frect():set(icon_w + padding_w * 2, padding_h, total_w - padding_w * 2 - icon_w, target_h))
|
||
|
self.str_title:SetTextColor(GetARGB(255, 255, 255, 255))
|
||
|
self.str_title:SetFont(get_font("large"))
|
||
|
self.str_title:SetWndSize(vector2():set(total_w - padding_w * 2 - icon_w, target_h))
|
||
|
self.str_title:SetEllipsis(true)
|
||
|
self.str_title:SetTextAlignment(0)
|
||
|
self.str_title:SetVTextAlignment(2)
|
||
|
self.str_title:SetText( gc("ui_st_pdahacking_" .. name_key[name]) )
|
||
|
|
||
|
self.bonus_text = self:AddTextField("",1)
|
||
|
self.bonus_text:SetWndPos(vector2():set(total_w * 0.65 + target_h * 0.5 * 0.75, padding_h))
|
||
|
self.bonus_text:SetWndSize(vector2():set(total_w * 0.35 - target_h * 0.5 * 0.75, target_h))
|
||
|
self.bonus_text:SetFont(get_font("large"))
|
||
|
self.bonus_text:SetTextAlignment(2)
|
||
|
self.bonus_text:SetVTextAlignment(2)
|
||
|
|
||
|
self.bonus_icon = self:AddIconField(1)
|
||
|
self.bonus_icon:SetStretchTexture(true)
|
||
|
self.bonus_icon:SetWndPos(vector2():set(total_w * 0.65, target_h * 0.25 + padding_h))
|
||
|
self.bonus_icon:SetWndSize(vector2():set(target_h * 0.5 * 0.75, target_h * 0.5))
|
||
|
|
||
|
if name == "Nuke" then
|
||
|
self.bonus_text:SetText("-" .. round_idp(get_nuke_effect(power, encrypt_strength), 1) .. "%" )
|
||
|
self.bonus_icon:InitTexture("ui_pdahack_icon_shield")
|
||
|
self.bonus_text:SetTextColor(colors_argb.nuke)
|
||
|
self.bonus_icon:SetTextureColor(colors_argb.nuke)
|
||
|
elseif name == "Decrypt" then
|
||
|
self.bonus_icon:Show(false)
|
||
|
self.bonus_text:SetWndPos(vector2():set(total_w * 0.65, padding_h))
|
||
|
self.bonus_text:SetWndSize(vector2():set(total_w * 0.35, target_h))
|
||
|
self.bonus_text:SetTextAlignment(2)
|
||
|
self.bonus_text:SetText("+" .. round_idp(get_decrypt_effect(power, encrypt_strength), 1) .. "%" )
|
||
|
self.bonus_text:SetTextColor(colors_argb.decrypt)
|
||
|
elseif name == "Re-Scan" then
|
||
|
self.bonus_text:SetText("+" .. get_rescan_count(power) )
|
||
|
self.bonus_icon:InitTexture("ui_pdahack_icon_script")
|
||
|
self.bonus_icon:SetWndPos(vector2():set(total_w * 0.65 - (target_h / 16), target_h * 0.25 + padding_h))
|
||
|
self.bonus_icon:SetWndSize(vector2():set(target_h * 0.5, target_h * 0.5))
|
||
|
self.bonus_icon:SetTextureColor(colors_argb.rescan)
|
||
|
self.bonus_text:SetTextColor(colors_argb.rescan)
|
||
|
elseif name == "CommandUp" then
|
||
|
self.bonus_text:SetText("+" .. get_command_up(power) )
|
||
|
self.bonus_icon:InitTexture("ui_pdahack_icon_cmd")
|
||
|
self.bonus_text:SetTextColor(colors_argb.cmdup)
|
||
|
self.bonus_icon:SetTextureColor(colors_argb.cmdup)
|
||
|
elseif name == "BruteForce" then
|
||
|
self.bonus_text:SetText( round_idp(get_brute_chance(power), 1) .. "%" )
|
||
|
self.bonus_icon:InitTexture("ui_pdahack_icon_dice")
|
||
|
self.bonus_text:SetTextColor(colors_argb.bruteforce)
|
||
|
self.bonus_icon:SetTextureColor(colors_argb.bruteforce)
|
||
|
elseif name == "SkeletonKey" then
|
||
|
self.bonus_text:Show(false)
|
||
|
self.str_title:SetText(scramble_string(gc("ui_st_pdahacking_skey") .. "#&$"))
|
||
|
self.str_title:SetTextColor(colors_argb.skey)
|
||
|
self.icon_hack:SetTextureColor(colors_argb.skey)
|
||
|
elseif name == "Extract" then
|
||
|
self.bonus_text:SetFont(get_font("medium"))
|
||
|
self.bonus_text:SetText("+" .. gc("ui_st_pdahacking_ruble") .. get_extract_money(power, base_encr_str) )
|
||
|
self.bonus_icon:InitTexture("ui_pdahack_icon_money")
|
||
|
self.bonus_text:SetTextColor(colors_argb.extract)
|
||
|
self.bonus_icon:SetTextureColor(colors_argb.extract)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
fonts = {
|
||
|
["high_res"] = {
|
||
|
["medium"] = GetFontGraffiti22Russian(),
|
||
|
["large"] = GetFontLetterica25(),
|
||
|
["huge"] = GetFontGraffiti50Russian();
|
||
|
},
|
||
|
["normal_res"] = {
|
||
|
["medium"] = GetFontLetterica18Russian(),
|
||
|
["large"] = GetFontGraffiti22Russian(),
|
||
|
["huge"] = GetFontLetterica25(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
name_key = {
|
||
|
["CommandUp"] = "cmdup",
|
||
|
["Decrypt"] = "decrypt",
|
||
|
["Re-Scan"] = "rescan",
|
||
|
["Nuke"] = "nuke",
|
||
|
["BruteForce"] = "bruteforce",
|
||
|
["SkeletonKey"] = "skey",
|
||
|
["Extract"] = "extract",
|
||
|
}
|
||
|
|
||
|
function get_font(font)
|
||
|
pr( device().width .. "x" .. device().height)
|
||
|
if device().height > 1080 and device().width > 1920 then
|
||
|
return fonts["high_res"][font]
|
||
|
else
|
||
|
return fonts["normal_res"][font]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Hack Device spawning
|
||
|
drop_table = {
|
||
|
["pda_hack_usb_1"] = {
|
||
|
["novice"] = 0.00,
|
||
|
["trainee"] = 0.005,
|
||
|
["experienced"] = 0.01,
|
||
|
["professional"] = 0.01,
|
||
|
["veteran"] = 0.005,
|
||
|
["expert"] = 0.00,
|
||
|
["master"] = 0.00,
|
||
|
["legend"] = 0.00,
|
||
|
},
|
||
|
["pda_hack_usb_2"] = {
|
||
|
["novice"] = 0.00,
|
||
|
["trainee"] = 0.00,
|
||
|
["experienced"] = 0.00,
|
||
|
["professional"] = 0.005,
|
||
|
["veteran"] = 0.01,
|
||
|
["expert"] = 0.01,
|
||
|
["master"] = 0.005,
|
||
|
["legend"] = 0.00,
|
||
|
},
|
||
|
["pda_hack_usb_3"] = {
|
||
|
["novice"] = 0.00,
|
||
|
["trainee"] = 0.00,
|
||
|
["experienced"] = 0.00,
|
||
|
["professional"] = 0.00,
|
||
|
["veteran"] = 0.00,
|
||
|
["expert"] = 0.005,
|
||
|
["master"] = 0.01,
|
||
|
["legend"] = 0.02,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
function npc_drop_hack_device(npc, npc_rank, npc_comm)
|
||
|
for sec, rank_table in pairs(drop_table) do
|
||
|
local chance = rank_table[npc_rank] * settings.hack_device_drop_mult
|
||
|
--[[ if debug and table[npc_rank] > 0 then
|
||
|
chance = 1
|
||
|
end ]]
|
||
|
if (math.random() < chance) then
|
||
|
alife_create_item(sec, npc, nil)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
SpawnCosmetics = death_manager.spawn_cosmetics
|
||
|
function death_manager.spawn_cosmetics(npc, npc_id, npc_comm, npc_rank, visual, rand_condition)
|
||
|
SpawnCosmetics(npc, npc_id, npc_comm, npc_rank, visual, rand_condition)
|
||
|
npc_drop_hack_device(npc, npc_rank, npc_comm)
|
||
|
end
|
||
|
|
||
|
-- Lower hack device sell price
|
||
|
function on_get_item_cost(kind, obj, profile, calculated_cost, ret)
|
||
|
if profile.mode == 1 and drop_table[obj:section()] then -- when selling
|
||
|
ret.new_cost = math.floor((ret.new_cost or calculated_cost) * 0.25)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- MCM multipliers
|
||
|
if ui_pda_npc_tab.faction_encyption and ui_pda_npc_tab.stash_factor_per_pda then
|
||
|
base_register_pda = ui_pda_npc_tab.register_pda
|
||
|
function ui_pda_npc_tab.register_pda(npc, pda_sec, pda_id)
|
||
|
local temp_encr_tbl = dup_table(ui_pda_npc_tab.faction_encyption)
|
||
|
if settings.locked_chance_mult ~= 1 then
|
||
|
for comm, encr in pairs(ui_pda_npc_tab.faction_encyption) do
|
||
|
ui_pda_npc_tab.faction_encyption[comm] = encr * settings.locked_chance_mult
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local temp_stash_factor_tbl = dup_table(ui_pda_npc_tab.stash_factor_per_pda)
|
||
|
if settings.stash_chance_mult ~= 1 then
|
||
|
for sec, factor in pairs(ui_pda_npc_tab.stash_factor_per_pda) do
|
||
|
ui_pda_npc_tab.stash_factor_per_pda[sec] = factor * settings.stash_chance_mult
|
||
|
end
|
||
|
end
|
||
|
|
||
|
base_register_pda(npc, pda_sec, pda_id)
|
||
|
ui_pda_npc_tab.faction_encyption = dup_table(temp_encr_tbl)
|
||
|
ui_pda_npc_tab.stash_factor_per_pda = dup_table(temp_stash_factor_tbl)
|
||
|
end
|
||
|
else
|
||
|
printf("-PDA Hacking mod: Error modifying locked PDA/stash chance. Please update your Modded Exes")
|
||
|
end
|
||
|
|
||
|
-- MCM
|
||
|
function load_defaults()
|
||
|
local t = {}
|
||
|
local op = pda_hacking_mcm.op
|
||
|
for i, v in ipairs(op.gr) do
|
||
|
if v.def ~= nil then
|
||
|
t[v.id] = v.def
|
||
|
end
|
||
|
end
|
||
|
return t
|
||
|
end
|
||
|
|
||
|
settings = load_defaults()
|
||
|
|
||
|
function load_settings()
|
||
|
settings = load_defaults()
|
||
|
if ui_mcm then
|
||
|
for k, v in pairs(settings) do
|
||
|
settings[k] = ui_mcm.get("pda_hacking/" .. k)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
return settings
|
||
|
end
|
||
|
|
||
|
function on_game_start()
|
||
|
RegisterScriptCallback("actor_on_first_update", load_settings)
|
||
|
RegisterScriptCallback("on_option_change", load_settings)
|
||
|
RegisterScriptCallback("on_get_item_cost", on_get_item_cost)
|
||
|
end
|