Divergent/mods/Western Goods/gamedata/scripts/western_goods_dialogs_manag...

273 lines
13 KiB
Plaintext

---==================================================================================================================---
--- ---
--- Original Author(s) : NLTP_ASHES ---
--- Edited : N/A ---
--- Date : 17/04/2023 ---
--- License : Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) ---
--- ---
--- This script is used to manage the script-side of dialogs in the addon. ---
--- ---
--- It essentially is composed of two things : ---
--- - The addon's own dialog system (also referred as auto-rolling dialogs - using the game's news manager); ---
--- - The functions used to generate start dialogs for NPCs. ---
--- ---
---==================================================================================================================---
-- ---------------------------------------------------------------------------------------------------------------------
-- Constants, global variables and imported functions
-- ---------------------------------------------------------------------------------------------------------------------
-- Dialog constants
local CONST_DISPLAY_TIME = 15
local CONST_DELAY_MSG = 7000
local CONST_DELAY_QUICK_MSG = 1000
local CONST_DELAY_LOAD = 15000
local CONST_MSG_HEADER = western_goods_utils.get_translation("st_wg_dm_message_header")
local CONST_DEFAULT_NAME = western_goods_utils.get_translation("st_wg_dm_default_name")
local CONST_DEFAULT_ICON = "ui_inGame2_no_data"
-- Dialog variables
DIALOGS_TABLE = {}
local sound = true
local last_sender = nil
-- Imported functions
local dbg_printf = western_goods_utils.dbg_printf
-- ---------------------------------------------------------------------------------------------------------------------
-- Dialog Manager
-- ---------------------------------------------------------------------------------------------------------------------
--- Function called every frame to update the Dialog Manager and check if some messages should be fired.
--- When dialogs are waiting to be played, the Dialog Manager will disable dynamic random news.
--- @return nil
function update_dialogs()
-- Turn off dynamic news
if size_table(DIALOGS_TABLE) > 0 and dynamic_news_manager.enable_news then
dynamic_news_manager.enable_news = false
dbg_printf("[WG] Dialogs Manager | Disabled dynamic news (now:%s)", dynamic_news_manager.enable_news)
end
-- Process dialogs
for index,dialog in pairs(DIALOGS_TABLE) do
if dialog.timer < time_global() then
-- Send the line of dialog
dynamic_news_helper.send_tip(dialog.message, CONST_MSG_HEADER .. " " .. dialog.sender, nil, CONST_DISPLAY_TIME, dialog.icon, dialog.sound, "npc")
DIALOGS_TABLE[index] = nil
dbg_printf("[WG] Dialogs Manager | Pushed dialog (from:%s) (left:%s)", dialog.sender, size_table(DIALOGS_TABLE))
end
end
-- Re-enable dynamic news if we're done sending dialogs
if size_table(DIALOGS_TABLE) < 1 and not dynamic_news_manager.enable_news then
dynamic_news_manager.enable_news = true
dbg_printf("[WG] Dialogs Manager | Re-enabled dynamic news (now:%s)", dynamic_news_manager.enable_news)
end
end
--- Function used to register multiple dialog lines to the Dialog Manager.
--- For each line of dialog, default values exist 'sender' and 'icon'; 'message' is required.
--- @param dialog_table table
--- @param quick_delay boolean
--- @return nil
function send_dialog(dialog_table, quick_delay)
dbg_printf("[WG] Dialogs Manager | Preparing dialog (length:%s)", size_table(dialog_table))
for index,dialog in pairs(dialog_table) do
-- Default values
dialog.sender = dialog.sender or CONST_DEFAULT_NAME
dialog.icon = dialog.icon or CONST_DEFAULT_ICON
dialog.timer = (quick_delay and CONST_DELAY_QUICK_MSG or CONST_DELAY_MSG) * (size_table(DIALOGS_TABLE) + 1) + time_global()
dialog.sound = sound and "beep_1" or "beep_2"
-- Invert sound effect if from different sender
if not last_sender or (last_sender ~= dialog.sender) then
sound = not sound
last_sender = dialog.sender
end
this.send_message(dialog.message, dialog.sender, dialog.icon, dialog.timer, dialog.sound)
end
dbg_printf("[WG] Dialogs Manager | Dialog ready (waiting queue: %s(+%s))", size_table(DIALOGS_TABLE), size_table(dialog_table))
end
--- Function used to register a single dialog line to the Dialog Manager.
--- Default values exist 'sender', 'icon', 'timer' and 'sound'; 'message' is required.
--- @param message string
--- @param sender string
--- @param icon string
--- @param timer number
--- @param sound string
--- @return nil
function send_message(message, sender, icon, timer, sfx)
-- Default values
sender = sender or CONST_DEFAULT_NAME
icon = icon or CONST_DEFAULT_ICON
timer = timer or (CONST_DELAY_QUICK_MSG + time_global())
sfx = sfx or "beep_1"
table.insert(DIALOGS_TABLE, { message=message, sender=sender, icon=icon, timer=timer, sound=sfx })
dbg_printf("[WG] Dialogs Manager | Registered dialog (from:%s)", sender)
end
-- ---------------------------------------------------------------------------------------------------------------------
-- Scripted Text Dialogs
-- ---------------------------------------------------------------------------------------------------------------------
--- Function called to determine the start dialog's text of the crew member.
--- @return string
function st_crew_member_start_dialog()
if not (western_goods_utils.has_info("western_goods_act_1_task_3_active") or western_goods_utils.has_info("western_goods_act_1_task_3_finished")) then
return western_goods_utils.get_translation("st_stalker_crew_member_start_0")
elseif not western_goods_utils.has_info("western_goods_crew_member_rescue_over") then
return western_goods_utils.get_translation("st_stalker_crew_member_start_1")
elseif not western_goods_tasks_act_1.TASK_3_CACHE.stage_1_dialog_1_sent then
return western_goods_utils.get_translation("st_stalker_crew_member_start_2")
elseif not western_goods_tasks_act_1.TASK_3_CACHE.stage_1_dialog_2_sent then
return western_goods_utils.get_translation("st_stalker_crew_member_start_3")
elseif not western_goods_utils.has_info("western_goods_act_1_task_3_crew_member_extracted") then
return western_goods_utils.get_translation("st_stalker_crew_member_start_4")
elseif not western_goods_utils.has_info("western_goods_act_1_task_3_finished") then
return western_goods_utils.get_translation("st_stalker_crew_member_start_5")
else return western_goods_utils.get_translation("st_stalker_crew_member_start_6") end
end
--- Function called to determine the start dialog's text of yellow crewmate.
--- @return string
function st_yellow_ecolog_start_dialog()
if western_goods_utils.has_info("western_goods_act_2_task_2_controller_spawned") and not western_goods_utils.has_info("western_goods_act_2_task_2_controller_killed") then
return western_goods_utils.get_translation("st_wg_yellow_ecolog_start_0")
else return western_goods_utils.get_translation("st_wg_yellow_ecolog_start_1") end
end
--- Function called to determine the start dialog's text of Dunn Lynn.
--- @return string
function st_dunn_lynn_start_dialog()
if western_goods_utils.has_info("western_goods_act_2_task_2_active") and not western_goods_utils.has_info("western_goods_act_2_task_2_finished") then
return western_goods_utils.get_translation("st_wg_dunn_lynn_first_start")
elseif math.random() < 0.0001 then
return western_goods_utils.get_translation("st_wg_dunn_lynn_start_x")
else return western_goods_utils.get_translation("st_wg_dunn_lynn_start_" .. math.random(0,5)) end
end
--- Function called to determine the second phrase of Oleksandr Chernenko start dialog.
--- @return string
function st_oleksandr_chernenko_meet_1()
if get_actor_true_community() == "army" then
return western_goods_utils.get_translation("western_goods_oleksandr_chernenko_meet_1_army")
else
return western_goods_utils.get_translation("western_goods_oleksandr_chernenko_meet_1")
end
end
--- Function called to determine the third phrase of Oleksandr Chernenko start dialog.
--- @return string
function st_oleksandr_chernenko_meet_2()
if get_actor_true_community() == "army" then
return western_goods_utils.get_translation("western_goods_oleksandr_chernenko_meet_2_army")
else
return western_goods_utils.get_translation("western_goods_oleksandr_chernenko_meet_2")
end
end
--- Function called to determine the fourth phrase of Oleksandr Chernenko start dialog.
--- @return string
function st_oleksandr_chernenko_meet_3()
if get_actor_true_community() == "army" then
return western_goods_utils.get_translation("western_goods_oleksandr_chernenko_meet_3_army")
else
return western_goods_utils.get_translation("western_goods_oleksandr_chernenko_meet_3")
end
end
--- Function called to determine the start dialog's text of Danylo Chernenko.
--- @return string
function st_danylo_chernenko_start_dialog()
if not western_goods_utils.has_info("western_goods_act_3_task_1_finished") then
return western_goods_utils.get_translation("st_wg_danylo_chernenko_first_start")
else
return western_goods_utils.get_translation("st_wg_danylo_chernenko_start_" .. math.random(0,5))
end
end
--- Function called to determine the final line of dialog for the interrogation with the SSU prisoner.
--- @return string
function st_interrogation_end()
local score = western_goods_tasks_act_3.TASK_2_CACHE.interrogation_points
dbg_printf("[WG] Tasks Act 3 | Task 2 - Interrogation finished with score %s", score)
if score >= 35 then
return western_goods_utils.get_translation("st_wg_act_3_task_2_interrogation_end_nice")
elseif score >= 0 then
return western_goods_utils.get_translation("st_wg_act_3_task_2_interrogation_end_normal")
else
return western_goods_utils.get_translation("st_wg_act_3_task_2_interrogation_end_mean")
end
end
-- ---------------------------------------------------------------------------------------------------------------------
-- Callbacks registration
-- ---------------------------------------------------------------------------------------------------------------------
--- Function used to register callbacks.
--- @return nil
function on_game_start()
RegisterScriptCallback("save_state", save_state)
RegisterScriptCallback("load_state", load_state)
RegisterScriptCallback("actor_on_update", update_dialogs)
end
-- ---------------------------------------------------------------------------------------------------------------------
-- Data persistence
-- ---------------------------------------------------------------------------------------------------------------------
--- Function used to store information in the save file.
--- @param m_data table
--- @return nil
function save_state(m_data)
-- Prepare save table
local DIALOGS_SAVE = {}
-- Make copies of dialog table
copy_table(DIALOGS_SAVE, DIALOGS_TABLE)
-- Pre-process timers
for _,dialog in pairs(DIALOGS_SAVE) do
dialog.timer = dialog.timer - time_global()
end
-- Save dialog table
m_data.wg_dialogs_table = DIALOGS_SAVE
-- Debug print
dbg_printf("[WG] Dialogs Manager | Saved dialog table...\n%s",utils_data.print_table(DIALOGS_SAVE, false, true))
end
--- Function used to load information stored in the save file.
--- @param m_data table
--- @return nil
function load_state(m_data)
local DIALOGS_SAVE = m_data.wg_dialogs_table or {}
-- Post-process timers
for _,dialog in pairs(DIALOGS_SAVE) do
dialog.timer = dialog.timer + time_global() + CONST_DELAY_LOAD
end
copy_table(DIALOGS_TABLE, DIALOGS_SAVE)
-- Debug print
dbg_printf("[WG] Dialogs Manager | Loaded dialog table...\n%s",utils_data.print_table(DIALOGS_TABLE, false, true))
end