706 lines
21 KiB
Plaintext
706 lines
21 KiB
Plaintext
|
|
--[[
|
|
-----------------------------------
|
|
Copyright (C) 2012 Alundaio
|
|
|
|
This program is free software; you can redistribute and/or modify
|
|
it under the terms of the Open S.T.A.L.K.E.R. Mod License version 1.0.
|
|
|
|
-----------------------------------
|
|
ponney68
|
|
|
|
-----------------------------------
|
|
Tronex
|
|
Last edit: 2019/12/17
|
|
Added Loot all button, organized script, inventory cell system, alife spawn handlers
|
|
-----------------------------------
|
|
ilrathCXV
|
|
Last edit: 2024/03/29
|
|
MCM for Loot Chances + edits for DLTX Hunting Backpacks
|
|
-----------------------------------
|
|
-]]
|
|
|
|
|
|
local ini_mutant = ini_file("items\\settings\\mutant_loot.ltx")
|
|
local get_config = zzz_cxv_mutant_loot_mcm.get_config
|
|
local mcm_defaults = zzz_cxv_mutant_loot_mcm.defaults
|
|
local mcm_check = ui_mcm and zzz_cxv_mutant_loot_mcm
|
|
|
|
is_cxv_enabled = get_config("enable_mod") or mcm_defaults["enable_mod"] or false
|
|
|
|
-- local sec_kit_hunt = "kit_hunt"
|
|
-- local sec_kit_hunt_chance = ini_sys:r_float_ex("kit_hunt","bonus_mutant_part_chance") or 0
|
|
|
|
local hunting_kits = {
|
|
"kit_hunt",
|
|
"equ_small_military_hunt_pack",
|
|
"equ_military_hunt_pack",
|
|
"equ_tourist_hunt_pack",
|
|
}
|
|
|
|
local item_prop_table = { cond_r = {30,70} , cond_ct = "part" , cond_cr = {0.5,0.75,1} }
|
|
|
|
-- Loot Mutant
|
|
local MutantLootDecayTime = ini_mutant:r_float_ex("mutant_loot_mod","decay_time") or 7200
|
|
|
|
local kind_to_section = {
|
|
["SM_KARLIK"] = "karlik",
|
|
["SM_PSYSUCKER"] = "psysucker",
|
|
["SM_LURKER"] = "lurker"
|
|
}
|
|
local clsid_to_section = {
|
|
[clsid.bloodsucker_s] = "bloodsucker",
|
|
[clsid.boar_s] = "boar",
|
|
[clsid.burer_s] = "burer",
|
|
[clsid.chimera_s] = "chimera",
|
|
[clsid.controller_s] = "controller",
|
|
[clsid.dog_s] = "dog",
|
|
[clsid.flesh_s] = "flesh",
|
|
[clsid.gigant_s] = "gigant",
|
|
[clsid.poltergeist_s] = "poltergeist",
|
|
[clsid.psy_dog_s] = "psy_dog",
|
|
[clsid.psy_dog_phantom_s] = "psy_dog",
|
|
[clsid.pseudodog_s] = "pseudodog",
|
|
[clsid.snork_s] = "snork",
|
|
[clsid.tushkano_s] = "tushkano",
|
|
[clsid.cat_s] = "cat",
|
|
[clsid.fracture_s] = "fracture",
|
|
[clsid.zombie_s] = "zombie",
|
|
[clsid.crow] = "crow",
|
|
[clsid.rat_s] = "rat"
|
|
}
|
|
local clsdbg_to_section = {
|
|
["SM_KARLIK"] = "karlik",
|
|
["SM_PSYSUCKER"] = "psysucker",
|
|
["SM_LURKER"] = "lurker"
|
|
}
|
|
|
|
local killed_mutant_tbl = { -- ponney68: This table based on "species" of mutants
|
|
|
|
-- TRX: A-Life Revamp
|
|
psysucker = {file="ui\\ui_actor_monsters_pda_3",x="393",y="0",type="small"},
|
|
lurker = {file="ui\\ui_actor_monsters_pda_3",x="0",y="0",type="small"},
|
|
karlik = {file="ui\\ui_actor_monsters_pda_3",x="0",y="200",type="small"},
|
|
|
|
snork = {file="ui\\ui_actor_monsters_pda",x="393",y="0",type="small"},
|
|
dog = {file="ui\\ui_actor_monsters_pda",x="0",y="800",type="small"},
|
|
pseudodog = {file="ui\\ui_actor_monsters_pda",x="393",y="200",type="small"},
|
|
psy_dog = {file="ui\\ui_actor_monsters_pda",x="393",y="200",type="small"},
|
|
poltergeist = {file="ui\\ui_actor_monsters_pda",x="0",y="400",type="small"},
|
|
bloodsucker = {file="ui\\ui_actor_monsters_pda",x="393",y="400",type="human"},
|
|
controller = {file="ui\\ui_actor_monsters_pda",x="393",y="800",type="human"},
|
|
chimera = {file="ui\\ui_actor_monsters_pda",x="0",y="600",type="large"},
|
|
tushkano = {file="ui\\ui_actor_monsters_pda",x="0",y="0",type="small"},
|
|
rat = {file="ui\\ui_actor_monsters_pda",x="0",y="0",type="small"},
|
|
flesh = {file="ui\\ui_actor_monsters_pda",x="393",y="600",type="large"},
|
|
tark = {file="ui\\ui_actor_monsters_pda_2",x="0",y="0",type="human"},
|
|
rotan = {file="ui\\ui_actor_monsters_pda",x="0",y="0",type="human"},
|
|
burer = {file="ui\\ui_actor_monsters_pda_1",x="0",y="0",type="large"},
|
|
boar = {file="ui\\ui_actor_monsters_pda_1",x="393",y="0",type="large"},
|
|
giant = {file="ui\\ui_actor_monsters_pda_1",x="0",y="200",type="large"},
|
|
cat = {file="ui\\ui_actor_monsters_pda_2",x="0",y="0",type="small"},
|
|
fracture = {file="ui\\ui_actor_monsters_pda_2",x="393",y="200",type="human"},
|
|
bird = {file="ui\\ui_actor_monsters_pda_2",x="393",y="0",type="small"},
|
|
zombie = {file="ui\\ui_actor_monsters_pda_2",x="0",y="200",type="human"},
|
|
bloodsucker_arena = {file="ui\\ui_actor_monsters_pda",x="393",y="400",type="human"},
|
|
burer_arena = {file="ui\\ui_actor_monsters_pda_1",x="0",y="0",type="large"},
|
|
pseudodog_arena = {file="ui\\ui_actor_monsters_pda",x="393",y="200",type="small"},
|
|
snork_arena = {file="ui\\ui_actor_monsters_pda",x="393",y="0",type="human"},
|
|
}
|
|
|
|
-- Should specific loot be guaranteed?
|
|
mutant_part_guaranteed = {
|
|
["i_mutant_part"] = get_config("always_give_parts") or mcm_defaults["always_give_parts"] or false,
|
|
["i_mutant_raw"] = get_config("always_give_meat") or mcm_defaults["always_give_meat"] or false,
|
|
["i_mutant_belt"] = get_config("always_give_pelt") or mcm_defaults["always_give_pelt"] or false,
|
|
}
|
|
|
|
|
|
-- Chance multiplier solely for mutant parts
|
|
mutant_part_chance_mult = {
|
|
["i_mutant_part"] = get_config("mutant_part_chance_mult") or mcm_defaults["mutant_part_chance_mult"] or 1,
|
|
["i_mutant_raw"] = get_config("mutant_meat_chance_mult") or mcm_defaults["mutant_meat_chance_mult"] or 1,
|
|
["i_mutant_belt"] = get_config("mutant_pelt_chance_mult") or mcm_defaults["mutant_pelt_chance_mult"] or 1,
|
|
}
|
|
|
|
mutant_other_chance_mult = get_config("mutant_other_chance_mult") or mcm_defaults["mutant_other_chance_mult"] or 1
|
|
|
|
function get_part_kind(sec)
|
|
local kind = sec and ini_sys:r_string_ex(sec,'kind') or nil
|
|
return kind
|
|
end
|
|
|
|
function loot_mutant(section, clsid, loot_table, npc, dont_create, victim) -- Prepare mutant loot
|
|
|
|
npc = npc or db.actor
|
|
local clsid = clsid or obj and obj:clsid()
|
|
local kind = section and ini_sys:r_string_ex(section,"kind") or "unknown"
|
|
if not (clsid) then
|
|
return
|
|
end
|
|
|
|
local loot, sec, count, chance
|
|
local str_explode = str_explode
|
|
local mutant = clsdbg_to_section[kind] or clsid_to_section[clsid]
|
|
local was_loot_given = false
|
|
local failsafe_loot = get_config("failsafe_loot") or mcm_defaults["failsafe_loot"] or false
|
|
|
|
if victim:section() == "gigant_jumper" then
|
|
mutant = "gigant"
|
|
end
|
|
|
|
local possible_items = utils_data.collect_section(ini_mutant, mutant)
|
|
|
|
local sim = alife()
|
|
local npc_id = npc and npc:id()
|
|
local npc_pos = npc and npc:position()
|
|
local npc_lvl_id = npc and npc:level_vertex_id()
|
|
local npc_game_id = npc and npc:game_vertex_id()
|
|
|
|
-- Spawn items on NPC if he looted the mutant
|
|
for i=1,#possible_items do
|
|
loot = str_explode(possible_items[i],",")
|
|
if (loot and loot[1] and loot[2]) then
|
|
if (not loot[3]) then
|
|
loot[3] = 1
|
|
end
|
|
|
|
sec = loot[1]
|
|
count = tonumber(loot[2])
|
|
|
|
if is_cxv_enabled then
|
|
part_kind = get_part_kind(sec)
|
|
|
|
if part_kind and mutant_part_guaranteed[part_kind] == true then
|
|
-- printf("[UI Mutant Loot] %s will be guaranteed (%s)", sec, part_kind)
|
|
chance = 1
|
|
elseif part_kind and mutant_part_chance_mult[part_kind] then
|
|
-- printf("[UI Mutant Loot] %s will have its chances increased by %sx (%s)", sec, mutant_part_chance_mult[part_kind], part_kind)
|
|
chance = (loot[3] and (loot[3] * mutant_part_chance_mult[part_kind])) or 1
|
|
else
|
|
-- printf("[UI Mutant Loot] %s will have its chances increased by %sx (%s)", sec, mutant_other_chance_mult, part_kind)
|
|
chance = (loot[3] and (loot[3] * mutant_other_chance_mult)) or 1
|
|
end
|
|
else
|
|
printf("[UI Mutant Loot] Mutant Loot MCM not enabled. Defaulting to normal drop chances...")
|
|
chance = loot[3] or 1
|
|
end
|
|
|
|
for i=1,count do
|
|
if (math.random() <= tonumber(chance)) then
|
|
was_loot_given = true
|
|
-- In case we don't want to bother with loot table
|
|
local se_obj
|
|
if (not dont_create) then
|
|
se_obj = alife_create_item(sec, npc, item_prop_table)
|
|
end
|
|
|
|
-- Fill loot table if needed
|
|
if (loot_table) then
|
|
local sec_d, uses = utils_item.get_defined_uses(sec)
|
|
if (not loot_table[sec_d]) then
|
|
loot_table[sec_d] = {}
|
|
end
|
|
local c = loot_table[sec_d].count
|
|
c = c and (c + 1) or 1
|
|
loot_table[sec_d].count = c
|
|
if se_obj then
|
|
loot_table[sec_d][c] = se_obj.id
|
|
end
|
|
--printf("loot_mutant")
|
|
|
|
--[[
|
|
if npc and npc:id() ~= AC_ID then
|
|
se_obj = alife_create_item(sec, npc, item_prop_table)
|
|
end
|
|
--]]
|
|
end
|
|
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if not was_loot_given and is_cxv_enabled and failsafe_loot then
|
|
printf("[UI Mutant Loot] No loot was given. Attempting loot failsafe...")
|
|
loot = str_explode(possible_items[math.random(1,#possible_items)],",")
|
|
if (loot and loot[1] and loot[2]) then
|
|
if (not loot[3]) then
|
|
loot[3] = 1
|
|
end
|
|
|
|
sec = loot[1]
|
|
count = tonumber(loot[2])
|
|
|
|
if (not dont_create) then
|
|
se_obj = alife_create_item(sec, npc, item_prop_table)
|
|
end
|
|
|
|
if (loot_table) then
|
|
local sec_d, uses = utils_item.get_defined_uses(sec)
|
|
if (not loot_table[sec_d]) then
|
|
loot_table[sec_d] = {}
|
|
end
|
|
local c = loot_table[sec_d].count
|
|
c = c and (c + 1) or 1
|
|
loot_table[sec_d].count = c
|
|
if se_obj then
|
|
loot_table[sec_d][c] = se_obj.id
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- Unlock relevant mutant article in guide.
|
|
if mutant and npc and (npc:id() == AC_ID) then
|
|
SendScriptCallback("actor_on_interaction", "mutants", nil, mutant)
|
|
end
|
|
|
|
SendScriptCallback("monster_on_loot_init",victim,loot_table)
|
|
end
|
|
|
|
----------------------------------------------------------------------
|
|
GUI = nil -- instance, don't touch
|
|
function start(obj, for_bug1, for_bug2)
|
|
if (not obj) then
|
|
printf("!ERROR ui_mutant_loot | no game object passed!")
|
|
return
|
|
end
|
|
|
|
if (not GUI) then
|
|
GUI = UIMutantLoot()
|
|
end
|
|
|
|
if (GUI) and (not GUI:IsShown()) then
|
|
local can_show = GUI:Reset(obj, for_bug1, for_bug2)
|
|
if can_show then
|
|
GUI:ShowDialog(true)
|
|
Register_UI("UIMutantLoot","ui_mutant_loot")
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
----------------------------------------------------------------------
|
|
-- CALLBACKS
|
|
----------------------------------------------------------------------
|
|
local function monster_on_actor_use_callback(obj,who) -- Open mutant loot UI
|
|
|
|
-- Return if mutant is already looted
|
|
local looted = se_load_var(obj:id(),obj:name(),"looted")
|
|
if (looted) then
|
|
return
|
|
end
|
|
|
|
-- This is important so NPCs don't try to loot the corpse the player is looting
|
|
if (obj:clsid() == clsid.crow) then
|
|
save_var(obj, "looted", true)
|
|
else
|
|
se_save_var(obj:id(),obj:name(),"looted",true)
|
|
end
|
|
xr_corpse_detection.set_valuable_loot(obj:id(),false)
|
|
|
|
-- if mutant corpse is lefted for long time, body is decayed
|
|
local st = db.storage[obj:id()]
|
|
if (st and st.death_time and game.get_game_time():diffSec(st.death_time) > MutantLootDecayTime) then
|
|
actor_menu.set_msg(1, game.translate_string("st_body_decayed"),4)
|
|
|
|
-- Start the Mutant Loot UI
|
|
else
|
|
start(obj, obj:id(), obj:section(), obj:clsid())
|
|
end
|
|
end
|
|
|
|
function monster_on_loot_init(obj,t)
|
|
-- t['conserva'] = {
|
|
-- count = 3
|
|
-- }
|
|
-- utils_data.print_table(t,obj and obj:name() or "no_obj")
|
|
end
|
|
|
|
function on_option_change(mcm)
|
|
if mcm then
|
|
is_cxv_enabled = get_config("enable_mod") or mcm_defaults["enable_mod"] or false
|
|
|
|
mutant_part_guaranteed = {
|
|
["i_mutant_part"] = get_config("always_give_parts") or mcm_defaults["always_give_parts"] or false,
|
|
["i_mutant_raw"] = get_config("always_give_meat") or mcm_defaults["always_give_meat"] or false,
|
|
["i_mutant_belt"] = get_config("always_give_pelt") or mcm_defaults["always_give_pelt"] or false,
|
|
}
|
|
|
|
-- Chance multiplier solely for mutant parts
|
|
mutant_part_chance_mult = {
|
|
["i_mutant_part"] = get_config("mutant_part_chance_mult") or mcm_defaults["mutant_part_chance_mult"] or 1,
|
|
["i_mutant_raw"] = get_config("mutant_meat_chance_mult") or mcm_defaults["mutant_meat_chance_mult"] or 1,
|
|
["i_mutant_belt"] = get_config("mutant_pelt_chance_mult") or mcm_defaults["mutant_pelt_chance_mult"] or 1,
|
|
}
|
|
|
|
mutant_other_chance_mult = get_config("mutant_other_chance_mult") or mcm_defaults["mutant_other_chance_mult"] or 1
|
|
end
|
|
end
|
|
|
|
function on_game_start()
|
|
RegisterScriptCallback("monster_on_actor_use_callback",monster_on_actor_use_callback)
|
|
RegisterScriptCallback("monster_on_loot_init",monster_on_loot_init)
|
|
|
|
RegisterScriptCallback("on_option_change",on_option_change)
|
|
on_option_change(mcm_check)
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------------------------------------
|
|
-- UI
|
|
----------------------------------------------------------------------
|
|
class "UIMutantLoot" (CUIScriptWnd)
|
|
|
|
function UIMutantLoot:__init() super()
|
|
self:InitControls()
|
|
self:InitCallBacks()
|
|
end
|
|
|
|
function UIMutantLoot:__finalize()
|
|
end
|
|
|
|
function UIMutantLoot:InitControls()
|
|
self:SetWndRect (Frect():set(0,0,1024,768))
|
|
self:SetAutoDelete(true)
|
|
|
|
self.xml = CScriptXmlInit()
|
|
self.xml:ParseFile ("ui_mutant_loot.xml")
|
|
local xml = self.xml
|
|
|
|
self.dialog = xml:InitStatic("mutant_loot:background",self)
|
|
|
|
-- Mutant image
|
|
self.image = self.xml:InitStatic("mutant_loot:image",self.dialog)
|
|
|
|
-- Loot
|
|
self.frame = xml:InitStatic("mutant_loot:frame",self.dialog)
|
|
self.CC = utils_ui.UICellContainer("loot", self, nil, "mutant_loot:cont_loot", self.dialog)
|
|
self.CC.showcase = true
|
|
-- self.CC.can_select = true
|
|
self.CC.disable_drag = true
|
|
self.CC.disable_stack = true
|
|
self.CC:SetGridSpecs(35, 2)
|
|
|
|
self.item_info = utils_ui.UIInfoItem(self, 1000)
|
|
|
|
-- Button Loot one
|
|
self.btn_loot_one = xml:Init3tButton("mutant_loot:btn_loot",self.dialog)
|
|
self:Register(self.btn_loot_one, "button_loot")
|
|
|
|
-- Button Loot all
|
|
self.btn_loot_all = xml:Init3tButton("mutant_loot:btn_loot_all",self.dialog)
|
|
self:Register(self.btn_loot_all, "button_loot_all")
|
|
|
|
-- Button Cancel
|
|
self.btn_cancel = xml:Init3tButton("mutant_loot:btn_cancel",self.dialog)
|
|
self:Register(self.btn_cancel, "button_cancel")
|
|
end
|
|
|
|
function UIMutantLoot:InitCallBacks()
|
|
self:AddCallback("button_loot",ui_events.BUTTON_CLICKED,self.OnButton_LootSelected,self)
|
|
self:AddCallback("button_loot_all",ui_events.BUTTON_CLICKED,self.OnButton_LootAll,self)
|
|
self:AddCallback("button_cancel",ui_events.BUTTON_CLICKED,self.Close,self)
|
|
end
|
|
|
|
function UIMutantLoot:Reset(obj, for_bug1, for_bug2)
|
|
local function is_number(var)
|
|
local function lets_try(var)
|
|
var = tonumber(var)
|
|
return (var > 0) or (var < 0) or var or -var
|
|
end
|
|
if pcall(function() lets_try(var) end) then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
if not (is_number(obj)) then
|
|
self.section = obj:section()
|
|
self.clsid = obj:clsid()
|
|
self.id = obj:id()
|
|
self.obj = obj
|
|
else
|
|
self.id = obj
|
|
self.section=for_bug1
|
|
self.clsid = for_bug2
|
|
self.obj = nil
|
|
end
|
|
|
|
self:SetMutantImage()
|
|
return self:FillList()
|
|
end
|
|
|
|
function UIMutantLoot:Update()
|
|
CUIScriptWnd.Update(self)
|
|
|
|
-- Highlight selected items
|
|
for idx,ci in pairs(self.CC.cell) do
|
|
if (not ci:IsCursorOverWindow()) then
|
|
if ci.flags.selected then
|
|
ci:Highlight(true,"green")
|
|
else
|
|
ci:Highlight(false)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Updating item info box and item cell containers
|
|
local found_cell = self.CC:Update(self.item_info)
|
|
if (not found_cell) then
|
|
self.item_info:Update()
|
|
end
|
|
end
|
|
|
|
-- Utility
|
|
function UIMutantLoot:SetMutantImage()
|
|
local mutant_id = game.translate_string(ini_sys:r_string_ex(self.section,"species") or "")
|
|
|
|
local kind = ini_sys:r_string_ex(self.section,"kind") or "unknown"
|
|
mutant_id = kind_to_section[kind] or mutant_id
|
|
|
|
--printf("-MUTANT:"..mutant_id)
|
|
|
|
local mutant_f = "ui\\ui_actor_monsters_pda_1"
|
|
local mutant_x = 0
|
|
local mutant_y = 0
|
|
|
|
mutant_f = tostring(killed_mutant_tbl[mutant_id].file)
|
|
mutant_x = tostring(killed_mutant_tbl[mutant_id].x)
|
|
mutant_y = tostring(killed_mutant_tbl[mutant_id].y)
|
|
|
|
local x1 = mutant_x
|
|
local y1 = mutant_y
|
|
local mutant_width = 393
|
|
local mutant_height = 200
|
|
|
|
local x2 = x1 + mutant_width
|
|
local y2 = y1 + mutant_height
|
|
|
|
self.image:InitTexture(tostring(mutant_f))
|
|
self.image:SetTextureRect(Frect():set(x1,y1,x2,y2))
|
|
self.image:SetStretchTexture(true)
|
|
end
|
|
|
|
function UIMutantLoot:Loot(loot_all)
|
|
local obj_mutant = level.object_by_id(self.id)
|
|
if (not obj_mutant) then
|
|
self:Close()
|
|
return
|
|
end
|
|
|
|
local is_looted
|
|
local sim = alife()
|
|
local bonus_part_chance = 0
|
|
|
|
-- Checking in case player has Hunting Backpacks Expanded
|
|
local is_huntkit
|
|
local needs_equipped_hk = ui_options.get("gameplay/general/need_equipped_hkit")
|
|
|
|
if needs_equipped_hk then
|
|
local backpack = db.actor:item_in_slot(13)
|
|
if backpack then
|
|
backpack_sec = backpack:section()
|
|
bonus_part_chance = ini_sys:r_float_ex(backpack_sec,"bonus_mutant_part_chance") or 0
|
|
if bonus_part_chance > 0 then
|
|
is_huntkit = true
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Keeping the "Hunting Kit Equipped" option functional
|
|
if not is_huntkit and not needs_equipped_hk then
|
|
|
|
-- Checking for all types of Hunting Kits
|
|
for i=1,#hunting_kits do
|
|
if db.actor:object(hunting_kits[i]) then
|
|
-- Checking in case a backpack with higher part chance is found (in case people add their own backpacks to the list)
|
|
local temp_chance = ini_sys:r_float_ex(hunting_kits[i],"bonus_mutant_part_chance") or 0
|
|
if temp_chance > bonus_part_chance then
|
|
bonus_part_chance = temp_chance
|
|
-- printf("[UI Mutant Loot] New bonus mutant part chance (%s%) from %s", bonus_part_chance, hunting_kits[i])
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
|
|
--if (needs_equipped_hk and (backpack and (backpack:section() == sec_kit_hunt))) or (not needs_equipped_hk and db.actor:object(sec_kit_hunt)) then
|
|
-- is_huntkit = true
|
|
--end
|
|
|
|
-- Spawn selected items, clean from loot table
|
|
if loot_all then
|
|
local tbl = self.loot -- temp
|
|
for sec,t in pairs(tbl) do
|
|
for i=1,t.count do
|
|
is_looted = true
|
|
item_knife.degradate()
|
|
|
|
alife_create_item(sec, db.actor, item_prop_table)
|
|
|
|
if is_huntkit and (math.random(100) < bonus_part_chance) then
|
|
alife_create_item(sec, db.actor, item_prop_table)
|
|
end
|
|
self.loot[sec].count = self.loot[sec].count - 1
|
|
if (self.loot[sec].count == 0) then
|
|
self.loot[sec] = nil
|
|
end
|
|
end
|
|
end
|
|
else
|
|
for idx,ci in pairs(self.CC.cell) do
|
|
if ci.flags.selected then
|
|
local sec = ci.section
|
|
is_looted = true
|
|
item_knife.degradate()
|
|
|
|
alife_create_item(sec, db.actor, item_prop_table)
|
|
|
|
if is_huntkit and (math.random(100) < bonus_part_chance) then
|
|
alife_create_item(sec, db.actor, item_prop_table)
|
|
end
|
|
|
|
self.loot[sec].count = self.loot[sec].count - 1
|
|
if self.loot[sec].count == 0 then
|
|
self.loot[sec] = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- If no item is looted, don't proceed
|
|
if (not is_looted) then
|
|
return
|
|
end
|
|
|
|
-- Animation boost if player has Hunter Kit or Well Dressed Achievement
|
|
if (actor_effects) then
|
|
local boost = (game_achievements.has_achievement("well_dressed") and 1 or 0) + (is_huntkit and 1 or 0)
|
|
if (boost == 2) then
|
|
actor_effects.play_item_fx("mutant_looting_boost_2")
|
|
elseif (boost == 1) then
|
|
actor_effects.play_item_fx("mutant_looting_boost_1")
|
|
else
|
|
actor_effects.play_item_fx("mutant_looting")
|
|
end
|
|
end
|
|
xr_sound.set_sound_play(AC_ID,"inv_mutant_loot_animal")
|
|
|
|
-- Increat field dressings stat
|
|
game_statistics.increment_statistic("field_dressings")
|
|
|
|
-- Mutant post-state
|
|
save_var(obj_mutant,"loot",self.loot)
|
|
local is_more_loot = not is_empty(self.loot)
|
|
|
|
-- Refill loot list if there's loot left
|
|
if ((not actor_effects.is_animations_on()) and is_more_loot) then
|
|
self:FillList()
|
|
else
|
|
self:Close()
|
|
end
|
|
end
|
|
|
|
function UIMutantLoot:FillList()
|
|
|
|
--developed by Dimeyne, copied by Wafel
|
|
self.loot = load_var(self.obj,"loot",nil)
|
|
if not self.loot then
|
|
self.loot = {}
|
|
loot_mutant(self.section, self.clsid, self.loot, nil, true, self.obj)
|
|
save_var(self.obj,"loot",self.loot)
|
|
end
|
|
|
|
local is_there_loot
|
|
local inv = {}
|
|
for sec,t in pairs(self.loot) do
|
|
for i=1,t.count do
|
|
inv[#inv + 1] = sec
|
|
end
|
|
is_there_loot = true
|
|
end
|
|
if (self.obj:clsid() ~= clsid.crow) and load_var(self.obj,"looted",nil) then
|
|
is_there_loot = false
|
|
end
|
|
|
|
if is_there_loot then
|
|
self:ShowDialog(true)
|
|
self.CC:Reinit(inv)
|
|
return true
|
|
else
|
|
actor_menu.set_msg(1, "st_body_useless",3)
|
|
end
|
|
end
|
|
|
|
function UIMutantLoot:SetMutantState(is_more_loot, obj_mutant)
|
|
|
|
obj_mutant = obj_mutant or level.object_by_id(self.id)
|
|
if (is_more_loot == nil) then
|
|
is_more_loot = not is_empty(self.loot)
|
|
end
|
|
|
|
-- We set mutant state to looted or not if there's loot left, so other NPCs can decide what to do with the corpse
|
|
if obj_mutant then
|
|
if is_more_loot then
|
|
--save_var(obj_mutant,"looted",false)
|
|
se_save_var(obj_mutant:id(),obj_mutant:name(),"looted",false)
|
|
xr_corpse_detection.set_valuable_loot(self.id,true)
|
|
else
|
|
--save_var(obj_mutant,"looted",true)
|
|
se_save_var(obj_mutant:id(),obj_mutant:name(),"looted",true)
|
|
xr_corpse_detection.set_valuable_loot(self.id,false)
|
|
end
|
|
else
|
|
printe("!ERROR ui_mutant_loot | can't retrieve online object of mutant [%s](%s)", self.section, self.id)
|
|
end
|
|
end
|
|
|
|
-- Callbacks
|
|
function UIMutantLoot:On_CC_Mouse1(cont, idx)
|
|
local ci = self.CC.cell[idx]
|
|
if (not ci) then
|
|
return
|
|
end
|
|
|
|
if (not ci.flags.selected) then
|
|
ci.flags.selected = true
|
|
else
|
|
ci.flags.selected = nil
|
|
end
|
|
end
|
|
|
|
function UIMutantLoot:OnButton_LootSelected()
|
|
self:Loot(false)
|
|
end
|
|
|
|
function UIMutantLoot:OnButton_LootAll()
|
|
self:Loot(true)
|
|
end
|
|
|
|
function UIMutantLoot:Close()
|
|
self:SetMutantState()
|
|
self:HideDialog()
|
|
Unregister_UI("UIMutantLoot")
|
|
end
|
|
|
|
function UIMutantLoot:OnKeyboard(dik, keyboard_action)
|
|
local res = CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)
|
|
if (res == false) then
|
|
self.CC:OnKeyboard(dik, keyboard_action)
|
|
|
|
if (dik == DIK_keys.DIK_RETURN) then
|
|
self:OnButton_LootAll()
|
|
|
|
elseif (dik == DIK_keys.DIK_ESCAPE) then
|
|
self:Close()
|
|
end
|
|
end
|
|
return res
|
|
end
|