Divergent/mods/Anomaly Ballistics Overhaul/gamedata/scripts/ammo_maker.script

204 lines
6.5 KiB
Plaintext
Raw Normal View History

2024-03-17 20:18:03 -04:00
local part_lookup
local d_flag = false
local d_key = "DIK_LSHIFT" -- Saftey key hold (Left Alt)
get_config = ammo_maker_mcm.get_config
-- break ammo down, returning an appropriate amount of items
function breakdown(ammo, tool, batch)
local sec = ammo and ammo:section() or nil
local name = ui_item.get_sec_name(sec)
local delay = actor_effects.is_animations_on() and 3 or 0
local npc = db.actor--ammo:parent()
if (not npc) then
printf("~ breakdown | no owner found for [%s]", ammo:name())
return
end
if not sec then return end
local to_breakdown = {}
if batch then
db.actor:iterate_ruck(function(temp, item)
if item:section() == sec then
table.insert(to_breakdown, item)
end
end)
else
to_breakdown[1] = ammo
end
local tbl = do_breakdown(to_breakdown, tool)
-- Increase Statistic
game_statistics.increment_statistic("items_disassembled")
-- Animation
actor_effects.play_item_fx("disassemble_metal_fast")
CreateTimeEvent("ammo_maker","delay_disassembly" .. ammo:id(), delay, timer_disassembly_item, npc:id(), tbl, name)
end
function do_breakdown(ammo_list, tool)
if is_empty(ammo_list) then return {} end
local tbl = {}
local sec = ammo_list[1]:section()
local salvage_type = part_lookup:r_string_ex(sec, "salvage") or "old"
local salvage_coef = (get_config(salvage_type .. "_salvage")/100) or 0.4
local parts = part_lookup:r_value(sec, "parts")
local parts_map = str_explode(parts, ",")
local degrade = tonumber(part_lookup:r_value(sec, "degrade")) or 0.0001
local name = ui_item.get_sec_name(sec)
local tbl = {}
for k,v in pairs(ammo_list) do
-- short circuit if tool gets depleted
if not tool then return tbl end
local box_size = v:ammo_get_count()
local parts = part_lookup:r_value(sec, "parts")
for i=1,#parts_map,2 do
local new_box_size = 0
local box_to_make = parts_map[i]
local box_type = SYS_GetParam(0, box_to_make, "type") or "bullet"
local box_chance = get_config(box_type)/100 or 1
local base_amt = tonumber(parts_map[i+1])
-- new 1 by 1 formula for consistency
for i=1,box_size do
if math.random() < (salvage_coef * box_chance) then
new_box_size = new_box_size + base_amt
end
end
if new_box_size > 0 then
if tbl[box_to_make] then
tbl[box_to_make] = tbl[box_to_make] + new_box_size
else
tbl[box_to_make] = new_box_size
end
end
end
utils_item.discharge(v)
utils_item.degrade(tool, degrade)
-- Add extra part on achievement
if (game_achievements.has_achievement("recycler")) and not is_empty(tbl) and (math.random(1,100) <= 33) then
local random_key = random_key_table(tbl)
tbl[random_key] = tbl[random_key] + math.random(1, 3)
end
end
return tbl
end
function timer_disassembly_item(npc_id, table, name)
-- Who is item owner? we must give them the parts
local npc = npc_id and get_object_by_id(npc_id)
if (not npc) then
printf("~ breakdown timer | no owner found")
return
end
for k,v in pairs(table) do
create_ammo(k, npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id(), v)
end
local parts_text = create_disassemble_list(table)
actor_menu.set_item_news("success", "weapon_ammo", "st_dis_text_11", name, game.translate_string("st_dis_text_9"), parts_text)
return true
end
function create_disassemble_list(t)
local str = ""
for k,v in pairs(t) do
str = str .. "\\n- " .. v .. " " .. ui_item.get_sec_name(k)
end
return str
end
Disassemble = item_parts.disassembly_item
function wrap_disassemble(obj, obj_d, batch)
obj_d = obj_d or item_parts.get_suitable_dtool(obj)
if (not item_parts.is_suitable_dtool(obj, obj_d)) then
if IsWeapon(obj) then
actor_menu.set_item_news('fail', 'weapon', "st_dis_text_3", " ")
else
news_manager.send_tip(db.actor, game.translate_string("st_news_dis_items"), nil, "swiss_knife", 6000)
end
return
end
if part_lookup:section_exist(obj:section()) then
breakdown(obj, obj_d, batch)
else
item_parts.disassembly_item(obj, obj_d)
end
end
function item_parts.disassembly_item(obj, obj_d)
obj_d = obj_d or item_parts.get_suitable_dtool(obj)
if (not item_parts.is_suitable_dtool(obj, obj_d)) then
if IsWeapon(obj) then
actor_menu.set_item_news('fail', 'weapon', "st_dis_text_3", " ")
else
news_manager.send_tip(db.actor, game.translate_string("st_news_dis_items"), nil, "swiss_knife", 6000)
end
return
end
if part_lookup:section_exist(obj:section()) then
breakdown(obj, obj_d, false)
else
Disassemble(obj, obj_d)
end
end
function check_batch(obj)
local sec = obj:section()
if IsAmmo(obj) and part_lookup:section_exist(sec) then
return 'st_batch_breakdown'
end
end
NameCustom = ui_inventory.UIInventory.Name_Custom
function ui_inventory.UIInventory:Name_Custom(obj, bag, temp, i)
obj = self:CheckItem(obj,"Name_Custom " .. i)
if i == 4 and IsAmmo(obj) then -- check unjam
return check_batch(obj)
else
return NameCustom(self, obj, bag, temp, i)
end
end
ActionCustom = ui_inventory.UIInventory.Action_Custom
function ui_inventory.UIInventory:Action_Custom(obj, bag, temp, i)
obj = self:CheckItem(obj,"Action_Custom " .. i)
if i == 4 and IsAmmo(obj) then -- check unjam
wrap_disassemble(obj, nil, true)
else
ActionCustom(self, obj, bag, temp, i)
end
end
function on_game_start()
part_lookup = ini_file_ex("parts\\importer.ltx")
local ini_ammo = ini_file("items\\ammo\\importer.ltx")
ini_ammo:section_for_each(function(ammo)
local count = ini_ammo:line_count(ammo) or 0
for i=0,count-1 do
local result, id, value = ini_ammo:r_line(ammo , i , "", "")
-- anomaly balls specific stuff
if string.find(id, "_bad") then
id = id:sub(1, -3)
workshop_autoinject.add_new_recipe(6, id, value)
elseif SYS_GetParam(0, id, "type") then
workshop_autoinject.add_new_recipe(6, id, value)
else
workshop_autoinject.add_override_recipe(id, value, 6)
end
end
end)
workshop_autoinject.remove_existing_recipes("ammo_vog-25")
workshop_autoinject.remove_existing_recipes("ammo_m209")
end