460 lines
12 KiB
Plaintext
460 lines
12 KiB
Plaintext
--[[
|
|
|
|
Modified by Tronex
|
|
Last modification: 2018/5/23
|
|
Prevent sleeping abuse of Ironman Life Granter feature
|
|
|
|
--]]
|
|
|
|
local last_sleep, last_sleep_chk, pwr_chk
|
|
|
|
------------------------------------------------------------
|
|
-- UI
|
|
------------------------------------------------------------
|
|
GUI = nil -- instance, don't touch
|
|
|
|
class "UISleep" (CUIScriptWnd)
|
|
|
|
function UISleep:__init() super()
|
|
self:InitControls()
|
|
self:InitCallbacks()
|
|
end
|
|
|
|
function UISleep:__finalize()
|
|
GUI = nil
|
|
end
|
|
|
|
function UISleep:InitControls()
|
|
self:SetWndRect(Frect():set(0,0,1024,768))
|
|
self.wide = (device().width/device().height) > (1024/768 + 0.01)
|
|
|
|
self:SetAutoDelete(true)
|
|
|
|
local xml = CScriptXmlInit()
|
|
xml:ParseFile("ui_sleep_dialog.xml")
|
|
|
|
self.back = xml:InitStatic("background", self)
|
|
-- self.sleep_static = xml:InitSleepStatic("sleep_static", self.back)
|
|
|
|
self.sleep_static = xml:InitStatic("sleep_static", self.back)
|
|
self.sleep_static2 = xml:InitStatic("sleep_static", self.back)
|
|
self.static_cover = xml:InitStatic("static_cover", self.back)
|
|
self.st_marker = xml:InitStatic("st_marker", self.static_cover)
|
|
|
|
self.sleep_st_tbl = {}
|
|
for i = 1, 24 do
|
|
self.sleep_st_tbl[i] = xml:InitStatic("sleep_st_"..i, self.back)
|
|
end
|
|
|
|
self.time_track = xml:InitTrackBar("time_track", self.back)
|
|
self:Register(self.time_track, "time_track")
|
|
|
|
self.btn_sleep = xml:Init3tButton("btn_sleep", self.back)
|
|
self:Register(self.btn_sleep, "btn_sleep")
|
|
|
|
self.btn_cancel = xml:Init3tButton("btn_cancel", self.back)
|
|
self:Register(self.btn_cancel, "btn_cancel")
|
|
end
|
|
|
|
function UISleep:InitCallbacks()
|
|
self:AddCallback("btn_sleep", ui_events.BUTTON_CLICKED, self.OnButtonSleep, self)
|
|
self:AddCallback("btn_cancel", ui_events.BUTTON_CLICKED, self.Close, self)
|
|
end
|
|
|
|
function UISleep:Initialize()
|
|
local cur_hours = level.get_time_hours()
|
|
for i = 1, 24 do
|
|
local hours = cur_hours + i
|
|
if (hours >= 24) then
|
|
hours = hours - 24
|
|
end
|
|
self.sleep_st_tbl[i]:TextControl():SetText(hours..game.translate_string("st_sleep_hours"))
|
|
end
|
|
|
|
local delta = math.floor(591/24*cur_hours)
|
|
local r = Frect():set(delta,413,591,531)
|
|
self.sleep_static:SetTextureRect(r)
|
|
local width = 591-delta
|
|
if (self.wide) then
|
|
width = width * 0.8
|
|
end
|
|
self.sleep_static:SetWndSize(vector2():set(width, 118))
|
|
|
|
r = Frect():set(0,413,delta,531)
|
|
self.sleep_static2:SetTextureRect(r)
|
|
local width = delta
|
|
if (self.wide) then
|
|
width = width * 0.8
|
|
end
|
|
self.sleep_static2:SetWndSize(vector2():set(width, 118))
|
|
|
|
local pos = self.sleep_static2:GetWndPos()
|
|
pos.x = self.sleep_static:GetWndPos().x+self.sleep_static:GetWidth()
|
|
self.sleep_static2:SetWndPos(pos)
|
|
end
|
|
|
|
function UISleep:TestAndShow(force)
|
|
local last_sleep = actor_status_sleep.get_last_sleep()
|
|
printdbg("#Immersive Sleep | last_sleep: %s",tostring(last_sleep))
|
|
if(last_sleep < 3000) then
|
|
actor_menu.set_msg(1, game.translate_string("st_sleep_awake"),4)
|
|
disable_info("sleep_active")
|
|
return
|
|
end
|
|
|
|
if (force ~= true) then
|
|
local bleeding = db.actor.bleeding > 0
|
|
local radiation = db.actor.radiation > 0
|
|
|
|
-- Prevent sleep if bleeding and/or iradiated.
|
|
if (bleeding or radiation) then
|
|
if (bleeding and radiation) then
|
|
actor_menu.set_msg(1, game.translate_string("st_sleep_bleeding_irradiated"),5)
|
|
elseif (bleeding) then
|
|
actor_menu.set_msg(1, game.translate_string("st_sleep_bleeding"),4)
|
|
elseif (radiation) then
|
|
actor_menu.set_msg(1, game.translate_string("st_sleep_irradiated"),4)
|
|
end
|
|
disable_info("sleep_active")
|
|
return
|
|
end
|
|
|
|
-- Check if actor is inside a safe zone
|
|
local actor_hide = GetEvent("current_safe_cover") and true or false
|
|
|
|
-- Check if actor is inside a tent
|
|
if (not actor_hide) then
|
|
actor_hide = item_tent.get_nearby_tent(1.5)
|
|
end
|
|
|
|
-- If all is no, dont sleep
|
|
if (not actor_hide) then
|
|
actor_menu.set_msg(1, game.translate_string("st_cant_sleep_find_shelter_mlr"),4)
|
|
disable_info("sleep_active")
|
|
return
|
|
end
|
|
end
|
|
|
|
self:Initialize()
|
|
self:ShowDialog(true)
|
|
Register_UI("UISleep","ui_sleep_dialog")
|
|
end
|
|
|
|
function UISleep:Update()
|
|
CUIScriptWnd.Update(self)
|
|
if self:IsShown() then
|
|
local sleep_time = self.time_track:GetIValue()-1
|
|
local x = math.floor(591/24 * sleep_time)
|
|
if (x==0) then
|
|
x = 5
|
|
end
|
|
if (self.wide) then
|
|
x = x * 0.8
|
|
end
|
|
self.st_marker:SetWndPos(vector2():set(x, 0))
|
|
end
|
|
end
|
|
|
|
function UISleep:OnTrackButton()
|
|
end
|
|
|
|
function UISleep:OnButtonSleep()
|
|
if self:IsShown() then
|
|
self:HideDialog()
|
|
Unregister_UI("UISleep")
|
|
end
|
|
|
|
save_var(db.actor,"heli_enemy_flag",nil)
|
|
xr_effects.disable_ui(db.actor, nil)
|
|
level.add_cam_effector("camera_effects\\sleep.anm", 10, false, "ui_sleep_dialog.dream_callback")
|
|
level.add_pp_effector("sleep_fade.ppe", 11, false)
|
|
_G.mus_vol = get_console_cmd(2,"snd_volume_music")
|
|
_G.amb_vol = get_console_cmd(2,"snd_volume_eff")
|
|
exec_console_cmd("snd_volume_music 0")
|
|
exec_console_cmd("snd_volume_eff 0")
|
|
|
|
if self.forced then
|
|
level.add_cam_effector("camera_effects\\surge_02.anm", 10, false, "ui_sleep_dialog.dream_callback")
|
|
else
|
|
level.add_cam_effector("camera_effects\\sleep.anm", 10, false, "ui_sleep_dialog.dream_callback")
|
|
exec_console_cmd("snd_volume_music 0")
|
|
exec_console_cmd("snd_volume_eff 0")
|
|
|
|
db.actor:activate_slot(0) -- hide weapon
|
|
|
|
local flist = getFS():file_list_open_ex("$game_saves$", bit_or(FS.FS_ListFiles,FS.FS_RootOnly),"*".. ui_load_dialog.saved_game_extension)
|
|
local f_cnt = flist and flist:Size() or 0
|
|
|
|
local inc = 0
|
|
if (f_cnt > 0) then
|
|
flist:Sort(FS.FS_sort_by_modif_down)
|
|
|
|
for it=0, f_cnt-1 do
|
|
local file_name = flist:GetAt(it):NameFull():sub(0,-6):lower()
|
|
|
|
-- grab last modified quicksave increment count
|
|
local d = tonumber( string.match(file_name,"sleep_autosave(%d+)") )
|
|
if (d) then
|
|
inc = d
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
inc = (inc >= ui_options.get("other/quicksave_cnt")) and 1 or inc + 1
|
|
end
|
|
level.add_pp_effector("surge_fade.ppe", 11, false) --sleep_fade.ppe
|
|
db.actor:give_info_portion("actor_is_sleeping")
|
|
end
|
|
|
|
function UISleep:OnKeyboard(dik, keyboard_action)
|
|
local res = CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)
|
|
if (res == false) then
|
|
local bind = dik_to_bind(dik)
|
|
if keyboard_action == ui_events.WINDOW_KEY_PRESSED then
|
|
|
|
if dik == DIK_keys.DIK_ESCAPE then
|
|
self:Close()
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
return res
|
|
end
|
|
|
|
function UISleep:Close()
|
|
if (self:IsShown()) then
|
|
self:HideDialog()
|
|
end
|
|
--db.actor:give_info_portion("tutorial_sleep")
|
|
disable_info("actor_is_sleeping")
|
|
disable_info("sleep_active")
|
|
|
|
Unregister_UI("UISleep")
|
|
end
|
|
|
|
------------------------------------------------------------
|
|
-- Utilities
|
|
------------------------------------------------------------
|
|
|
|
-- Immersive Sleep By TKCrits
|
|
-- v1.2
|
|
function get_immersive_sleep_hours(hours)
|
|
|
|
local sleepiness = actor_status_sleep.get_last_sleep() or 0
|
|
|
|
local hours_fully_rested = 0
|
|
local max_sleep_percentage = 0.9 -- 90% of total hours
|
|
|
|
local comfy = 0
|
|
local comfy0_rest = 520
|
|
local comfy1_rest = 624 -- 520 +20% (104) = 624
|
|
local comfy2_rest = 676 -- 520 +30% (156) = 676
|
|
local rest_per_hour = comfy0_rest
|
|
|
|
local early_wakeup_percentage = 0 -- 0% chance of waking early (base value)
|
|
local early_wakeup_multiplier = 8.3 -- hours * 8.3 = percentage (12 * 8.3 = 100)
|
|
local early_wakeup_hour = 0.63 -- 63% of total hours
|
|
|
|
--------------------------------------------------------
|
|
|
|
-- Get Comfort
|
|
-- Comfy sleep (bedspread / sleeping bag)
|
|
-- Sleeping bag = +20% comfort
|
|
-- Sleeping bag & bedspread = +30% comfort
|
|
|
|
printdbg("#Immersive Sleep | Sleeping Bag: %s",tostring(GUI.ph_sleepbag_id))
|
|
if((GUI.ph_sleepbag_id or 0) > 0) then
|
|
comfy = 1
|
|
rest_per_hour = comfy1_rest
|
|
if(db.actor:object("beadspread")) then
|
|
printdbg("#Immersive Sleep | Bedspread and Sleeping bag available")
|
|
comfy = 2
|
|
rest_per_hour = comfy2_rest
|
|
end
|
|
end
|
|
|
|
-- Get fully rested hour
|
|
if(sleepiness > 0) then
|
|
hours_fully_rested = math.floor(sleepiness/rest_per_hour)
|
|
end
|
|
|
|
-- Dont sleep longer than fully rested
|
|
if(hours > hours_fully_rested) then
|
|
hours = hours_fully_rested
|
|
end
|
|
|
|
printdbg("#Immersive Sleep | Fully Rested: %s",tostring(hours_fully_rested))
|
|
|
|
-- On comfort 0, don't sleep longer than 90% of fully rested hours
|
|
if(comfy == 0) then
|
|
hours = math.floor(hours * max_sleep_percentage)
|
|
end
|
|
|
|
-- Calculate Wakeup Chance (12 hrs * 8.3 = 100%)
|
|
early_wakeup_percentage = early_wakeup_percentage + math.floor(hours * early_wakeup_multiplier)
|
|
|
|
-- Set Comfort Bonuses
|
|
if(comfy == 1) then
|
|
early_wakeup_percentage = early_wakeup_percentage - 20
|
|
actor_status_sleep.set_rest_per_hour(comfy1_rest)
|
|
elseif (comfy == 2) then
|
|
early_wakeup_percentage = early_wakeup_percentage - 30
|
|
actor_status_sleep.set_rest_per_hour(comfy2_rest)
|
|
else
|
|
actor_status_sleep.set_rest_per_hour(comfy0_rest)
|
|
end
|
|
|
|
printdbg("#Immersive Sleep | Early Wakeup Chance: %s",tostring(early_wakeup_percentage))
|
|
|
|
-- Random chance of waking up
|
|
local woke_early = 0
|
|
local rng = math.random(0,100)
|
|
if (rng < early_wakeup_percentage) then
|
|
woke_early = 1
|
|
local min_wakeup_hour = math.floor(hours * early_wakeup_hour)
|
|
hours = math.random(min_wakeup_hour,(hours-1))
|
|
printdbg("#Immersive Sleep | Waking up early after: %s",tostring(hours))
|
|
end
|
|
|
|
if(woke_early == 1) then
|
|
-- "Woke up early after "
|
|
actor_menu.set_msg(1, string.format(game.translate_string("st_sleep_awake_woke_early"),tostring(hours)),4)
|
|
elseif(comfy < 2) then
|
|
-- "Slept for "
|
|
actor_menu.set_msg(1, string.format(game.translate_string("st_sleep_awake_slept_for"),tostring(hours)),4)
|
|
elseif(comfy == 2) then
|
|
-- "Slept very well for "
|
|
actor_menu.set_msg(1, string.format(game.translate_string("st_sleep_awake_slept_well"),tostring(hours)),4)
|
|
end
|
|
|
|
return hours
|
|
end
|
|
|
|
function dream_callback()
|
|
if GUI.forced then
|
|
level.add_cam_effector("camera_effects\\surge_01.anm", 10, false, "ui_sleep_dialog.dream_callback2")
|
|
else
|
|
level.add_cam_effector("camera_effects\\sleep.anm", 10, false, "ui_sleep_dialog.dream_callback2")
|
|
end
|
|
|
|
local hours = GUI.forced or GUI.time_track:GetIValue() --printf("dream_callback hours=%s",hours)
|
|
|
|
hours = get_immersive_sleep_hours(hours)
|
|
|
|
level.change_game_time(0,hours,0)
|
|
|
|
db.actor.power = 1
|
|
|
|
SendScriptCallback("actor_on_sleep",hours)
|
|
end
|
|
|
|
function dream_callback2()
|
|
xr_effects.enable_ui(db.actor, nil)
|
|
exec_console_cmd("snd_volume_music "..tostring(_G.mus_vol))
|
|
exec_console_cmd("snd_volume_eff "..tostring(_G.amb_vol))
|
|
exec_console_cmd("save " .. (user_name() or "") .. " - sleep")
|
|
|
|
_G.amb_vol = 0
|
|
_G.mus_vol = 0
|
|
disable_info("tutorial_sleep")
|
|
disable_info("actor_is_sleeping")
|
|
disable_info("sleep_active")
|
|
end
|
|
|
|
function sleep(force)
|
|
if (GUI == nil) then
|
|
GUI = ui_sleep_dialog.UISleep()
|
|
end
|
|
GUI.forced = nil
|
|
GUI.time_track:SetCurrentValue()
|
|
GUI:TestAndShow(force)
|
|
end
|
|
|
|
function sleep_forced(hours)
|
|
if (GUI == nil) then
|
|
GUI = ui_sleep_dialog.UISleep()
|
|
end
|
|
GUI.forced = hours or math.random(3,9)
|
|
GUI:OnButtonSleep()
|
|
end
|
|
|
|
function sleep_bag(ph_sleepbag_id, sec)
|
|
if (GUI == nil) then
|
|
GUI = ui_sleep_dialog.UISleep()
|
|
end
|
|
GUI.forced = nil
|
|
GUI.item_section = sec
|
|
GUI.ph_sleepbag_id = ph_sleepbag_id
|
|
GUI.time_track:SetCurrentValue()
|
|
GUI:TestAndShow()
|
|
--return GUI
|
|
end
|
|
|
|
local sleep_zones = {
|
|
"actor_surge_hide_2",
|
|
"agr_army_sleep",
|
|
"agr_sr_sleep_tunnel",
|
|
"agr_sr_sleep_wagon",
|
|
"bar_actor_sleep_zone",
|
|
"cit_merc_sleep",
|
|
"ds_farmhouse_sleep",
|
|
"esc_basement_sleep_area",
|
|
"esc_secret_sleep",
|
|
"gar_angar_sleep",
|
|
"gar_dolg_sleep",
|
|
"jup_a6_sr_sleep",
|
|
"mar_a3_sr_sleep",
|
|
"mil_freedom_sleep",
|
|
"mil_smart_terran_2_4_sleep",
|
|
"pri_a16_sr_sleep",
|
|
"pri_monolith_sleep",
|
|
"pri_room27_sleep",
|
|
"rad_sleep_room",
|
|
"ros_vagon_sleep",
|
|
"val_abandoned_house_sleep",
|
|
"val_vagon_sleep",
|
|
"yan_bunker_sleep_restrictor",
|
|
"zat_a2_sr_sleep",
|
|
"pol_secret_sleep"
|
|
}
|
|
function sleep_in_zone(actor, npc)
|
|
for k,v in pairs(sleep_zones) do
|
|
if utils_obj.npc_in_zone(db.actor, v) then
|
|
give_info("sleep_active")
|
|
sleep()
|
|
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
function main()
|
|
sleep()
|
|
end
|
|
|
|
|
|
------------------------------------------------------------
|
|
-- Debug
|
|
------------------------------------------------------------
|
|
local function on_game_load()
|
|
|
|
-- Debug Commands
|
|
local CMD = debug_cmd_list.command_get_list()
|
|
|
|
function CMD.sleep(_,__,x)
|
|
sleep(true)
|
|
x:SendOutput('-Sleeping time')
|
|
end
|
|
|
|
-- Debug Launcher executions
|
|
ui_debug_launcher.inject("action", { name = "Sleep" , cmd = "sleep" , hide_ui = 2 } )
|
|
|
|
end
|
|
|
|
function on_game_start()
|
|
if DEV_DEBUG then
|
|
RegisterScriptCallback("on_game_load",on_game_load)
|
|
end
|
|
end |