Divergent/mods/HG Companion/gamedata/scripts/hg_companion.script

524 lines
16 KiB
Plaintext
Raw Permalink Normal View History

2024-03-17 20:18:03 -04:00
-- Companions by Hive Game
-- VARIABLE --
local data_companion = {} -- Массив компаньонов
local data_patrol = {} -- Массив патрулей
local active_group = 0 -- Активный отряд
local movement = 0 -- Активная формация
local light = 1 -- Фонарик
local gts = game.translate_string -- Вставка переменных в текст
local xml_hg -- Текстуры
local covers -- Безопасные зоны
local cw_cooldown = 0
local cw_commands = {}
-- KEYBINDING --
local key_assign = hg_companion_mcm.get_key("squad", "key_assign")
local key_cw = hg_companion_mcm.get_key("squad", "key_cw")
local key_group_0 = hg_companion_mcm.get_key("squad", "key_numpad0")
local key_group_1 = hg_companion_mcm.get_key("squad", "key_numpad1")
local key_group_2 = hg_companion_mcm.get_key("squad", "key_numpad2")
local key_group_3 = hg_companion_mcm.get_key("squad", "key_numpad3")
local key_move = hg_companion_mcm.get_key("move", "key_move")
local key_light = hg_companion_mcm.get_key("move", "key_light")
local key_relax = hg_companion_mcm.get_key("relax", "key_relax")
local distance = hg_companion_mcm.get_key("move", "distance")
local formation = hg_companion_mcm.get_key("move", "formation")
local hud = hg_companion_mcm.get_key("move", "hud")
-- KEY RELEASE --
function on_key_release(key)
--[[
if key == key_info then -- Вывод в консоль информации о компаньонах
printdbg("All partners: %s (%s)", data_companion.count, data_companion.move)
for i=1,data_companion.count do
local line = data_companion[i]
local k = data_companion[line]
printdbg("%s (%s): %s (%s)(%s) %s (%s)(%s)", i, line, k.name, k.group, k.action, k.number+1, k.squad, k.move)
end
end
--]]
if key == key_assign then -- Назначение в новую группу
for id,squad in pairs(axr_companions.companion_squads) do
if (squad and squad.commander_id) then
for k in squad:squad_members() do
local st = db.storage[k.id]
local npc = st and st.object
if (npc) then
local name = npc:character_name()
local group = se_load_var(npc:id(), npc:name(), "companion_hg")
local distance = get_distance(db.actor:position(), npc:position())
if (distance < 1.5) then
if (k.id - 1 == id) then
if (active_group == 0) then
actor_menu.set_msg(1, gts("ui_hg_companion_choose"),8)
elseif (active_group == group) then
actor_menu.set_msg(1,strformat("%s %s %s %s",gts("ui_hg_companion_member"),name,gts("ui_hg_companion_group_last"),group),8)
elseif (squad:npc_count() == 1) then
actor_menu.set_msg(1,strformat("%s %s %s %s",gts("ui_hg_companion_member"),name,gts("ui_hg_companion_group_new"),active_group),8)
se_save_var(k.id,k.object:name(),"companion_hg",active_group)
else
actor_menu.set_msg(1,strformat("%s %s %s %s",gts("ui_hg_companion_member"),name,gts("ui_hg_companion_group_new"),active_group),8)
for i=1,data_companion.count do
local cid = data_companion[i]
local dc = data_companion[cid]
local commander = dc.commander
if (commander:id() == k.id) then
local npc = dc.npc
se_save_var(cid,npc:name(),"companion_hg",active_group)
end
end
end
else
actor_menu.set_msg(1, gts("ui_hg_companion_subject"), 8)
end
end
end
end
end
end
end
if key == key_group_0 then -- Команда всем группам
change_group(0)
end
if key == key_group_1 then -- Команда 1 группе
change_group(1)
end
if key == key_group_2 then -- Команда 2 группе
change_group(2)
end
if key == key_group_3 then -- Команда 3 группе
change_group(3)
end
if key == key_move then -- Изменение формации
movement = movement == 3 and 0 or movement + 1
actor_menu.set_msg(1, gts("ui_hg_companion_move_"..movement), 8)
end
if key == key_light then -- Изменение фонарика
light = light == 0 and 1 or 0
change_light(light)
end
if key == key_relax then -- Отдых
change_relax()
end
if key == key_cw then -- Колесо команд
start_cw()
end
end
-- SQUAD UPDATE --
function hg_squad_update()
local leader = 0 -- Количество лидеров
local member = 0 -- Общее количество компаньонов
local move = 0 -- Общее количество компаньонов в движении
local relax = 0 -- Общее количество компаньонов на отдыхе
local actor = db.actor -- Предыдущий компаньон
for id,squad in pairs(axr_companions.companion_squads) do
if (squad and squad.commander_id) then
leader = leader + 1
local number = 0 -- Количество компаньонов в скваде
local dist = 3 -- Дистанция
local commander = actor -- Командир сквада
for k in squad:squad_members() do
local st = db.storage[k.id]
local npc = st and st.object
local action = "move" -- Действие компаньона
if (npc) then
member = member + 1
se_save_var(npc:id(), npc:name(), "member_group", member)
se_save_var(npc:id(), npc:name(), "member_all", data_companion.count)
local name = npc:character_name() -- Имя компаньона
local group = se_load_var(npc:id(), npc:name(), "companion_hg") -- Группа компаньона
if (npc:has_info("npcx_beh_relax")) then action = "relax"
elseif (npc:has_info("npcx_beh_patrol_mode")) then action = "patrol"
elseif (npc:has_info("npcx_beh_wait")) then action = "wait"
end
if (number == 0) then
if (action ~= "move") then leader = leader - 1 end
if (npc:has_info("npcx_beh_distance_far")) then dist = 6 else dist = 3 end
commander = npc
elseif (action == "patrol") then
if (npc:has_info("npcx_beh_wait")) then npc:disable_info_portion("npcx_beh_wait") end
if (not npc:has_info("npcx_beh_patrol_mode")) then npc:give_info_portion("npcx_beh_patrol_mode") end
end
if (action == "move") then move = move + 1
elseif (action == "relax") then relax = relax + 1
end
local companion = {
["move"] = move,
["relax"] = relax,
["npc"] = npc,
["name"] = name,
["number"] = number,
["squad"] = squad:npc_count(),
["group"] = group,
["actor"] = actor,
["commander"] = commander,
["action"] = action,
["dist"] = dist,
}
data_companion[k.id] = companion
data_companion[member] = k.id
if (action == "move") then
actor = npc
end
number = number + 1
end
end
end
end
data_companion.squad = leader
data_companion.count = member
data_companion.move = move
data_companion.relax = relax
end
-- CHANGE GROUP --
function change_group(group)
if (group) then active_group = group
else active_group = 0 end
actor_menu.set_msg(1, gts("ui_hg_companion_group_"..active_group), 8)
end
-- CHANGE LIGHT --
function change_light(lt)
light = lt
actor_menu.set_msg(1, gts("ui_hg_companion_light_"..light), 8)
hg_squad_update()
for i=1,data_companion.count do
local line = data_companion[i]
local k = data_companion[line]
local npc = k.npc
local group = k.group
if (active_group == 0 or active_group == group) then
if (light == 0) then
if (npc:dont_has_info("npcx_light_on")) then npc:give_info_portion("npcx_light_on") end
else
if (npc:has_info("npcx_light_on")) then npc:disable_info_portion("npcx_light_on") end
end
end
end
end
-- CHANGE RELAX --
function change_relax()
local pos = db.actor:position()
local dist = 10000
local campfire, fire
local search = false
-- Поиск костра --
for id,binder in pairs(bind_campfire.campfires_all) do
if (binder and binder.object and binder.campfire) then
if (pos:distance_to_sqr(binder.object:position()) < dist) then
campfire = binder.object
fire = binder.campfire
dist = pos:distance_to_sqr(binder.object:position())
search = true
end
end
end
-- Костер найден --
if (search == true) then
actor_menu.set_msg(1, gts("ui_hg_companion_relax"), 8)
if (fire and not fire:is_on()) then fire:turn_on() end
hg_squad_update()
for i=1,data_companion.count do
local line = data_companion[i]
local k = data_companion[line]
local npc = k.npc
local group = k.group
if (active_group == 0 or active_group == group) then
if (not npc:has_info("npcx_beh_relax")) then
npc:give_info_portion("npcx_beh_relax")
npc:give_info_portion("npcx_beh_wait")
se_save_var(npc:id(), npc:name(), "campfire_step", nil)
se_save_var(npc:id(), npc:name(), "campfire", campfire)
se_save_var(npc:id(), npc:name(), "fire", fire)
end
end
end
if (axr_companions) then axr_companions:companion_relax() end
-- Костер не найден --
else
actor_menu.set_msg(1, gts("ui_hg_companion_relax_off"), 8)
end
end
-- COMPANIONS WHEEL --
function cw_prepare()
cw_commands["group_0"] = {key= "DIK_1" ,state= 0 ,set= change_group ,on_str= "ui_hg_companion_group_0"}
cw_commands["group_1"] = {key= "DIK_2" ,state= 1 ,set= change_group ,on_str= "ui_hg_companion_group_1"}
cw_commands["group_2"] = {key= "DIK_3" ,state= 2 ,set= change_group ,on_str= "ui_hg_companion_group_2"}
cw_commands["group_3"] = {key= "DIK_4" ,state= 3 ,set= change_group ,on_str= "ui_hg_companion_group_3"}
cw_commands["light_0"] = {key= "DIK_5" ,state= 0 ,set= change_light ,on_str= "ui_hg_companion_light_0"}
cw_commands["light_1"] = {key= "DIK_6" ,state= 1 ,set= change_light ,on_str= "ui_hg_companion_light_1"}
end
GUI = nil
function start_cw()
hide_hud_inventory()
if (not GUI) then
GUI = UIWheelCompanion()
end
if (GUI) and (not GUI:IsShown()) then
GUI:ShowDialog(true)
cw_cooldown = time_global()
Register_UI("UIWheelCompanion","ui_wheel_companion")
end
end
class "UIWheelCompanion" (CUIScriptWnd)
function UIWheelCompanion:__init() super()
self.clr_on = GetARGB(255, 255, 255, 255)
self.clr_off = GetARGB(70, 255, 255, 255)
self.states = {}
if is_empty(cw_commands) then
cw_prepare()
end
self:InitControls()
self:InitCallBacks()
end
function UIWheelCompanion:__finalize()
end
function UIWheelCompanion:InitControls()
self:SetWndRect(Frect():set(0,0,1024,768))
self:SetAutoDelete(true)
self:AllowMovement(true)
self.xml = CScriptXmlInit()
local xml = self.xml
xml:ParseFile("hg_wheel.xml")
-- Main
self.dialog = xml:InitStatic("wheel", self)
xml:InitStatic("wheel:background", self.dialog)
-- Buttons
self.cmd_pic = {}
self.cmd_btn = {}
for cmd,v in pairs(cw_commands) do
self.cmd_pic[cmd] = xml:InitStatic("wheel:box_" .. cmd, self.dialog)
self.cmd_pic[cmd]:InitTexture( "ui_companion_" .. cmd )
self.cmd_pic[cmd]:SetStretchTexture(true)
--self.cmd_pic[cmd]:SetTextureColor( self.clr_off )
self.cmd_btn[cmd] = xml:Init3tButton("wheel:btn_" .. cmd, self.dialog)
self:Register(self.cmd_btn[cmd],"btn_" .. cmd)
end
-- Text
self.hint = xml:InitTextWnd("wheel:hint", self.dialog)
end
function UIWheelCompanion:InitCallBacks()
for cmd,v in pairs(cw_commands) do
local _wrapper = function(handler) -- we need wrapper in order to pass ctrl to method
self:Order(cmd)
end
self:AddCallback("btn_" .. cmd, ui_events.BUTTON_CLICKED, _wrapper, self)
end
end
function UIWheelCompanion:Update()
CUIScriptWnd.Update(self)
for cmd,element in pairs(self.cmd_btn) do
if element:IsCursorOverWindow() then
local state = self.states[cmd]
local str = state and cw_commands[cmd].off_str or cw_commands[cmd].on_str
self.hint:SetText(str and game.translate_string(str) or "")
return
end
end
self.hint:SetText("")
end
function UIWheelCompanion:Order(cmd)
local state = cw_commands[cmd].state
cw_commands[cmd].set(state)
self:Close()
end
function UIWheelCompanion:OnKeyboard(dik, keyboard_action)
local res = CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)
if (res == false) then
if keyboard_action == ui_events.WINDOW_KEY_RELEASED then
local bind = dik_to_bind(dik)
if (time_global() > cw_cooldown + 100) and (bind == key_bindings.kQUIT or bind == key_bindings.kUSE or bind == key_cw) then
self:Close()
return
end
for cmd,v in pairs(cw_commands) do
if v.key and (dik == DIK_keys[v.key]) then
self:Order(cmd)
pass = false
break
end
end
end
end
return res
end
function UIWheelCompanion:Close()
if self:IsShown() then
self:HideDialog()
self:Show(false)
Unregister_UI("UIWheelCompanion")
end
end
-- RETURN SQUAD --
function return_squad()
return data_companion
end
-- GET DISTANCE --
function get_distance(position_1, position_2)
local x = math.abs(position_1.x - position_2.x)
local z = math.abs(position_1.z - position_2.z)
local distance = math.sqrt((x * x) + (z * z))
return distance
end
-- RETURN CURRENT GROUP --
function return_group()
return active_group
end
-- RETURN CURRENT MOVEMENT --
function return_movement()
return movement
end
-- RETURN DISTANCE --
function return_distance()
return distance
end
-- RETURN FORMATION --
function return_formation()
return formation
end
-- RETURN HUD --
function return_hud()
return hud
end
-- ON OPTION CHANGE --
function on_option_change()
key_assign = hg_companion_mcm.get_key("squad", "key_assign")
key_cw = hg_companion_mcm.get_key("squad", "key_cw")
key_group_0 = hg_companion_mcm.get_key("squad", "key_numpad0")
key_group_1 = hg_companion_mcm.get_key("squad", "key_numpad1")
key_group_2 = hg_companion_mcm.get_key("squad", "key_numpad2")
key_group_3 = hg_companion_mcm.get_key("squad", "key_numpad3")
key_move = hg_companion_mcm.get_key("move", "key_move")
key_light = hg_companion_mcm.get_key("move", "key_light")
key_relax = hg_companion_mcm.get_key("rest", "key_relax")
distance = hg_companion_mcm.get_key("move", "distance")
formation = hg_companion_mcm.get_key("move", "formation")
hud = hg_companion_mcm.get_key("move", "hud")
end
-- GET HG XML --
function get_hg_xml()
if (not xml_hg) then
xml_hg = CScriptXmlInit()
xml_hg:ParseFile("hg_companion.xml")
end
return xml_hg
end
-- GET HG COVER --
function get_covers()
if (not covers) then
covers = {}
local sur_ini = ini_file("misc\\surge_manager.ltx")
local safe_covers_list = utils_data.collect_section(sur_ini,"list",true)
local sim = alife()
local is_on_the_actor_level = simulation_objects.is_on_the_actor_level
for i=1, 65534 do
local se_obj = sim:object(i)
if se_obj and safe_covers_list[se_obj:name()] and is_on_the_actor_level(se_obj) then
covers[se_obj:name()] = se_obj.id
end
end
end
return covers
end
-- ON GAME LOADING --
local function on_game_load()
end
-- ON GAME START --
function on_game_start()
RegisterScriptCallback("save_state", save_state)
RegisterScriptCallback("load_state", load_state)
RegisterScriptCallback("on_game_load",on_game_load)
RegisterScriptCallback("on_option_change", on_option_change)
RegisterScriptCallback("on_key_release", on_key_release)
--[[
RegisterScriptCallback("hg_squad_update", hg_squad_update)
RegisterScriptCallback("return_squad", return_squad)
RegisterScriptCallback("get_distance", get_distance)
RegisterScriptCallback("return_group", return_group)
RegisterScriptCallback("return_movement", return_movement)
RegisterScriptCallback("return_distance", return_distance)
RegisterScriptCallback("get_hg_xml", get_hg_xml)
RegisterScriptCallback("get_covers", get_covers)
--]]
end
-- STORAGE SAVE --
function save_state(m_data)
m_data.data_companion = data_companion
m_data.data_patrol = data_patrol
m_data.active_group = active_group
m_data.movement = movement
m_data.light = light
end
-- STORAGE LOAD --
function load_state(m_data)
data_companion = m_data.data_companion or data_companion
m_data.data_companion = nil
data_patrol = m_data.data_patrol or data_patrol
m_data.data_patrol = nil
active_group = m_data.active_group or active_group
m_data.active_group = nil
movement = m_data.movement or movement
m_data.movement = nil
light = m_data.light or light
m_data.light = nil
end