524 lines
16 KiB
Plaintext
524 lines
16 KiB
Plaintext
-- 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 |