e4s-sdk/gamedata/scripts/level_weathers.script
2026-06-17 23:06:51 +03:00

240 lines
7.6 KiB
Text

local weather_manager = nil
--18.02.2008 - added dynamic weather
class "WeatherManager"
function WeatherManager:__init()
self.wfx_time = 0
self.weather_fx = nil
self.update_time = 0
self.update_level = ""
self.forced_weather_change_on_time_change = false
self.last_hour = 0
self.state={}
self.graphs={}
self.graphs_ini = ini_file("environment\\dynamic_weather_graphs.ltx")
if not self.graphs_ini then
abort("error when open weather_dynamic_graphs.ltx")
end
end
-- Âûçûâàåòñÿ ïîñëå load(). Ñîñòîÿíèå ïîãîäû óæå çàãðóæåíî.
function WeatherManager:reset()
printf("WeatherManager:WeatherManager():Reset()")
-- Çàãðóçèòü êîíäëèñò ñ ïîãîäîé.
local ini = ini_file("game.ltx")
local weather = utils.cfg_get_string(ini, level.name(), "weathers", db.actor, false, "", "[default]")
local postprocess = utils.cfg_get_string(ini, level.name(), "postprocess", db.actor, false, "")
if postprocess ~= nil then
printf("LEVEL POSTPROCESS: level: [%s], postprocess: [%s]", level.name(), postprocess)
level.add_pp_effector(postprocess, 999, true)
else
printf("LEVEL POSTPROCESS: level: [%s], postprocess: [none]", level.name())
level.remove_pp_effector(999)
end
if weather == "[default]" then
-- ñåòèì äåôîëòîâóþ ïîãîäó
self.weather_list = xr_logic.parse_condlist(db.actor, level.name(), "weather", "[default]")
else
self.weather_list = xr_logic.parse_condlist(db.actor, level.name(), "weather", weather)
end
self:select_weather(true)
self.last_hour=level.get_time_hours()
end
function WeatherManager:forced_weather_change()
self.forced_weather_change_on_time_change = true
end
-- Îáíîâëÿåì ïîãîäó ðàç â ÷àñ.
function WeatherManager:update()
if(level.is_wfx_playing()) then
self.weather_fx = level.get_weather()
else
self.weather_fx = nil
end
if not benchmark.weather then
if self.last_hour~=level.get_time_hours() then
self.last_hour=level.get_time_hours()
for lvl,st in pairs(self.state) do
st.current_state=st.next_state
st.next_state=get_next_state(st.graph,st.current_state)
end
-- Óñòàíàâëèâàåì ïîãîäó íà òåêóùåì óðîâíå
self:select_weather(false)
end
end
end
function WeatherManager:select_weather(now)
local weather = xr_logic.pick_section_from_condlist(db.actor, db.actor, self.weather_list)
local graph=self:get_graph_by_name(weather)
local weather_section_name=""
-- Ïðîâåðèì, ñîâïàäàåò ëè òåêóùèé ãðàô óðîâíÿ ñ ïîëó÷åííûì ïî êîíäëèñòó...
if graph==nil then
-- Ïåðåõîäèì íà ñòàòèêó
self.state[weather]=nil
weather_section_name=weather
else
-- Íîâàÿ ïîãîäà - äèíàìè÷åñêàÿ. Ïðîâåðèì, íóæíî ëè ìåíÿòü/óñòàíàâëèâàòü ãðàô
if self.state[weather]==nil or self.state[weather].graph_name~=weather then
-- Ãðàô èçìåíèëñÿ. Ïåðåõîäèì íà íåãî.
self.state[weather]=self:init_by_graph(graph,weather)
-- else
-- now = false
end
-- Ïîëó÷àåì íàçâàíèå ñåêöèè ïî òåêóùåìó ñîñòîÿíèþ.
local st=self.state[weather]
--weather_section_name="dw_"..st.current_state.."_"..st.next_state.."_"..level.get_time_hours()
weather_section_name="default_"..st.current_state
end
if now then
self.last_hour=level.get_time_hours()
end
if self.forced_weather_change_on_time_change then
now = true
self.forced_weather_change_on_time_change = false
end
if not(self.weather_fx) then
level.set_weather(weather_section_name,now)
else
level.start_weather_fx_from_time(self.weather_fx, self.wfx_time)
end
printf("WEATHER: '%s' now '%s'", weather_section_name, tostring(now))
-- if xrs_news then
-- xrs_news.news_call(1,1,nil,nil,weather_section_name,nil)
-- end
end
-- Âîçâðàùàåò íà÷àëüíîå ñîñòîÿíèå ïîãîäû.
function WeatherManager:init_by_graph(graph,graph_name)
local cur_state=get_next_state(graph,"")
local next_state=get_next_state(graph,cur_state)
return {current_state=cur_state,next_state=next_state,graph_name=graph_name,graph=graph}
end
-- Âîçâðàùàåò îäíî èç ñëåäóþùèõ ñîñòîÿíèé ãðàôà, ñîãëàñíî ïðîïèñàííûì âåðîÿòíîñòÿì.
function get_next_state(graph,state)
local sum=0
for st,prob in pairs(graph) do
--if state==st then prob=prob*2 end
sum=sum+prob
end
local rnd=math.random()*sum
local next_state
for st,prob in pairs(graph) do
--if state==st then prob=prob*2 end
next_state=st
rnd=rnd-prob
if (rnd<=0) then
break
end
end
return next_state
end
-- Óñòàíàâëèâàåì ñîñòîÿíèå ìåíåäæåðà, ðàñïàðñèâàÿ ñòðîêó ñîñòîÿíèÿ
function WeatherManager:set_state_as_string(ss)
self.state={}
for lvlstring in string.gmatch(ss,"[^;]+") do
local i,j,grname,curs,nexs=string.find(lvlstring,"([^=]+)=([^,]+),([^,]+)")
if not grname then
abort("WeatherManager:set_state_as_string: malformed state string. "..ss)
end
--local lvl_name=self:unpack_level(lvl)
local current_state=self:unpack_state(curs)
local next_state=self:unpack_state(nexs)
local graph_name=self:unpack_graph_name(grname)
local graph=self:get_graph_by_name(graph_name)
if graph==nil then
-- Ñòàðàÿ ñîõðàí¸íêà? Áóäåì ñ÷èòàòü ÷òî íà ýòîì óðîâíå - ñòàòè÷åñêàÿ ïîãîäà
else
self.state[graph_name]={current_state=current_state,next_state=next_state,graph_name=graph_name,graph=graph}
end
end
end
-- Ïðåîáðàçóåì òåêóùåå ñîñòîÿíèå ìåíåäæåðà â ñòðîêó
function WeatherManager:get_state_as_string()
local lvlstrings={}
for lvl_name,st in pairs(self.state) do
--local lvl=self:pack_level(lvl_name)
local curs=self:pack_state(st.current_state)
local nexs=self:pack_state(st.next_state)
local grn=self:pack_graph_name(st.graph_name)
table.insert(lvlstrings,grn.."="..curs..","..nexs)
end
return table.concat(lvlstrings,";")
end
-- Ïîëó÷èòü ãðàô (òàáëèöó ïåðåõîäîâ ñîñòîÿíèé ïîãîäû) ïî åãî íàçâàíèþ è íàçâàíèþ èãðîâîãî óðîâíÿ
function WeatherManager:get_graph_by_name(name)
if not self.graphs[name] then
self.graphs[name] = xr_s.parse_ini_section_to_array(self.graphs_ini,name)
end
return self.graphs[name]
end
-- Çàïàêîâàòü íàçâàíèå âåðøèíû ãðàôà
function WeatherManager:pack_state(state)
-- Ïîêà ïàêîâàòü íå áóäåì.
return state
end
-- Ðàñïàêîâàòü íàçâàíèå âåðøèíû ãðàôà
function WeatherManager:unpack_state(st)
-- Ïîêà ïàêîâàòü íå áóäåì
return st
end
-- Çàïàêîâàòü íàçâàíèå ãðàôà ïåðåõîäîâ ïîãîäû
function WeatherManager:pack_graph_name(graph_name)
-- Ïîêà ïàêîâàòü íå áóäåì.
return graph_name
end
-- Ðàñïàêîâàòü íàçâàíèå ãðàôà ïåðåõîäîâ ïîãîäû
function WeatherManager:unpack_graph_name(grn)
-- Ïîêà ïàêîâàòü íå áóäåì
return grn
end
function WeatherManager:load(F)
set_save_marker(F, "load", false, "WeatherManager")
printf("WEATHER LOAD")
--self.update_level = F:r_stringZ();
local state_string = F:r_stringZ();
printf("str = "..state_string)
if state_string == "" then
printf("str = empty string")
end
self:set_state_as_string(state_string)
self.update_time = F:r_u32();
local str = F:r_stringZ()
if(str~="nil") then
self.weather_fx = str
self.wfx_time = F:r_float()
end
set_save_marker(F, "load", true, "WeatherManager")
end
function WeatherManager:save(F)
set_save_marker(F, "save", false, "WeatherManager")
printf("WEATHER SAVE")
--F:w_stringZ(self.update_level);
printf("str = "..tostring(self:get_state_as_string()))
if self:get_state_as_string() == "" then
printf("str = empty string")
end
F:w_stringZ(self:get_state_as_string())
F:w_u32(self.update_time)
F:w_stringZ(tostring(self.weather_fx))
if(self.weather_fx) then
F:w_float(level.get_wfx_time())
end
set_save_marker(F, "save", true, "WeatherManager")
end
function get_weather_manager ()
if weather_manager == nil then
weather_manager = WeatherManager()
end
return weather_manager
end