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

524 lines
16 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 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