Divergent/mods/Classes and Talents/gamedata/scripts/talents_leveling.script

224 lines
6.1 KiB
Plaintext
Raw Normal View History

2024-03-17 20:18:03 -04:00
--[[
talents_leveling.talent_levels.offensive.points = 16 talents_leveling.talent_levels.offensive.lvl = 16
talents_leveling.talent_levels.defensive.points = 16 talents_leveling.talent_levels.defensive.lvl = 16
talents_leveling.talent_levels.endurance.points = 16 talents_leveling.talent_levels.endurance.lvl = 16
talents_leveling.talent_levels.speech.points = 16 talents_leveling.talent_levels.speech.lvl = 16
--]]
local offensive_mult = talents_mcm.get_config("offensive")
local defensive_mult = talents_mcm.get_config("defensive")
local endurance_mult = talents_mcm.get_config("endurance")
local speech_mult = talents_mcm.get_config("speech")
local gt = game.translate_string
typ_levels = {
[1] = 0, -- 0
[2] = 1000, -- 1000
[3] = 1500, -- 2500
[4] = 2000, -- 4500
[5] = 2500, -- 7000
[6] = 3000, -- 10000
[7] = 3500, -- 13500
[8] = 4000, -- 17500
[9] = 4500, -- 22000
[10] = 5000, -- 27000
[11] = 5500, -- 32500
[12] = 6000, -- 38500
[13] = 6500, -- 45000
[14] = 7000, -- 52000
[15] = 7500, -- 59500
[16] = 8000, -- 67500
}
talent_levels = {
["offensive"] = {
lvl = 1,
exp = 0,
points = 1,
spent_points = 0,
},
["defensive"] = {
lvl = 1,
exp = 0,
points = 1,
spent_points = 0,
},
["endurance"] = {
lvl = 1,
exp = 0,
points = 1,
spent_points = 0,
},
["speech"] = {
lvl = 1,
exp = 0,
points = 1,
spent_points = 0,
},
}
-- offensive
function npc_on_before_hit(npc, s_hit, bone_id, flags)
local draft = s_hit.draftsman
local draft_fits = draft and (IsStalker(draft) or IsMonster(draft))
if not (draft_fits and draft.alive and draft:alive() and draft:id() == 0) then return end
if not (npc:alive()) then return end
if s_hit.power <= 0 then return end
if s_hit.power > 99 then return end -- against wounded
add_exp("offensive", s_hit.power * 30 * offensive_mult)
end
function actor_on_weapon_fired(obj, wpn)
if not (obj and obj:id() == 0 and wpn) then return end
add_exp("offensive", 1 * offensive_mult)
end
-- defensive
function actor_on_before_hit(s_hit, bone_id, flags)
if s_hit.power <= 0 then return end
add_exp("defensive", s_hit.power * 60 * defensive_mult)
end
-- endurance
function actor_on_footstep(mat)
local weight_ratio = get_actor_weight_ratio()
add_exp("endurance", weight_ratio * 0.3 * endurance_mult)
end
function actor_on_jump()
local weight_ratio = get_actor_weight_ratio()
add_exp("endurance", weight_ratio * 3 * endurance_mult)
end
-- speech
function actor_on_item_trade(item)
local cost = item and ini_sys:r_float_ex(item:section(), "cost")
if not cost then return end
add_exp("speech", cost / 500 * speech_mult)
end
-- total experience and levels manager
function add_exp(typ, val)
if talents_functions.picked_class == "null" then return end
local cur_lvl = talent_levels[typ].lvl
if cur_lvl < #typ_levels then
-- add exp
talent_levels[typ].exp = talent_levels[typ].exp + val
-- level up
if talent_levels[typ].exp >= typ_levels[cur_lvl + 1] then
talent_levels[typ].exp = 0
talent_levels[typ].lvl = talent_levels[typ].lvl + 1
talent_levels[typ].points = talent_levels[typ].points + 1
-- send news
news_manager.send_tip(db.actor, string.format(gt("talents_levelup"), gt("tree_" .. typ), talent_levels[typ].lvl), 0, nil, 10000)
-- update UI on level up
if talents_gui and talents_gui.GUI then
talents_gui.GUI:UpdateTalentsMenu()
end
end
end
end
-------------------------------------------------------------
function save_state(m_data)
m_data.talent_levels = talent_levels
end
function load_state(m_data)
if m_data.talent_levels then
talent_levels = m_data.talent_levels
else
for k, _ in pairs(talent_levels) do
talent_levels[k] = {
lvl = 1,
exp = 0,
points = 1,
spent_points = 0,
}
end
end
end
function get_actor_weight_ratio()
local actor = db.actor
local outfit = actor:item_in_slot(7)
local backpack = actor:item_in_slot(13)
local tot_weight = actor:get_total_weight()
local max_weight = actor:get_actor_max_weight()
max_weight = max_weight + (outfit and outfit:get_additional_max_weight() or 0)
max_weight = max_weight + (backpack and backpack:get_additional_max_weight() or 0)
actor:iterate_belt( function(owner, obj)
local c_arty = obj:cast_Artefact()
max_weight = max_weight + (c_arty and c_arty:AdditionalInventoryWeight() or 0)
end)
actor:cast_Actor():conditions():BoosterForEach( function(booster_type, booster_time, booster_value)
if (booster_type == 4) then --eBoostMaxWeight
max_weight = max_weight + booster_value
end
end)
return tot_weight / max_weight
end
function ActorMenu_on_trade_started()
RegisterScriptCallback("actor_on_item_take", actor_on_item_trade)
RegisterScriptCallback("actor_on_item_drop", actor_on_item_trade)
end
function ActorMenu_on_trade_closed()
UnregisterScriptCallback("actor_on_item_take", actor_on_item_trade)
UnregisterScriptCallback("actor_on_item_drop", actor_on_item_trade)
end
function respec_levels()
for k, _ in pairs(talent_levels) do
talent_levels[k].lvl = math.ceil(talent_levels[k].lvl / 2)
talent_levels[k].exp = 0
talent_levels[k].spent_points = 0
end
for k, t in pairs(talent_levels) do
talent_levels[k].points = t.lvl
end
end
function on_option_change()
offensive_mult = talents_mcm.get_config("offensive")
defensive_mult = talents_mcm.get_config("defensive")
endurance_mult = talents_mcm.get_config("endurance")
speech_mult = talents_mcm.get_config("speech")
end
function on_game_start()
RegisterScriptCallback("save_state", save_state)
RegisterScriptCallback("load_state", load_state)
RegisterScriptCallback("npc_on_before_hit", npc_on_before_hit)
RegisterScriptCallback("monster_on_before_hit", npc_on_before_hit)
RegisterScriptCallback("actor_on_weapon_fired", actor_on_weapon_fired)
RegisterScriptCallback("actor_on_before_hit", actor_on_before_hit)
RegisterScriptCallback("actor_on_footstep", actor_on_footstep)
RegisterScriptCallback("actor_on_jump", actor_on_jump)
RegisterScriptCallback("ActorMenu_on_trade_started", ActorMenu_on_trade_started)
RegisterScriptCallback("ActorMenu_on_trade_closed", ActorMenu_on_trade_closed)
RegisterScriptCallback("on_option_change", on_option_change)
end