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