add game&rawdata

This commit is contained in:
Vasily Petrov 2026-06-17 23:06:51 +03:00
parent 0133cd976c
commit 49b34b5546
45731 changed files with 709831 additions and 0 deletions

View file

@ -0,0 +1,249 @@
--[[------------------------------------------------------------------------------------------------------------------
Óïðàâëåíèå äèàëîãàìè ãðóïï ñòàëêåðîâ
×óãàé Ñàøà
Ñäåëàòü:
Îïèñàíèå:
×òîá â êàêîé-òî ìîìåíò íà÷àëñÿ äèàëîã, íóæíî, ÷òîá ó ÂÑÅÕ ÷ëåíîâ êîìàíäû áûë âûçâàí enable. Îäèí åäèíñòâåííûé âûçîâ
disable è äèàëîã íå íà÷í¸òñÿ. Äëÿ íà÷àëà äèàëîãà âûáèðàåòñÿ ëþáîé ÷ëåí êîìàíäû, åñëè íåòó íèêîãî ðÿäîì ñ íèì, òî äèàëîã
íå íà÷í¸òñÿ. Äëÿ ïîâòîðíûõ ðåïëèê âûáèðàåòñÿ ëþáîé ÷ëåí êîìàíäû (êðîìå òîëüêî ÷òî ãîâîðèâøåãî) èç ÷èñëà òåõ, êòî íàõî-
äèòñÿ ðÿäîì ñ ïîñëåäíèì ãîâîðèâøèì; åñëè òàêèõ íåòó, òî äèàëîã ïðåðûâàåòñÿ.
--------------------------------------------------------------------------------------------------------------------]]
local teams = {} -- ãðóïïû ñòàëêåðîâ, ñãðóïïèðîâàííûõ äëÿ äèàëîãà
local snd = { themes = {} }
local idle_min, idle_max = 20, 60 -- ïðåäåëû ïåðèîäà ìîë÷àíêè ìåæäó äèàëîãàìè â ñåêóíäàõ
local pause_min, pause_max = 1, 2 -- ïðåäåëû âåëè÷èíû ïàóçû ìåæäó ôðàçàèì â ñåêóíäàõ
local dist_max = 100 -- êâàäðàò ìàêñèìàëüíîãî ðàññòîÿíèÿ ìåæäó ñîáåñåäíèêàìè
local avail = {}
----------------------------------------------------------------------------------------------------------------------
-- äåðåâüÿ äèàëîãîâ
----------------------------------------------------------------------------------------------------------------------
local dialogs = {
place = {
[1] = { snd = "place1", next = 2 },
[2] = { snd = "place2" }
},
}
----------------------------------------------------------------------------------------------------------------------
-- êëàññ óïðàâëåíèÿ äèàëîãàìè (òîëüêî çâóêàìè)
----------------------------------------------------------------------------------------------------------------------
class "dialog_mgr"
function dialog_mgr:__init()
end
function dialog_mgr:reset( npc, team )
self.object = npc
if self.team ~= team then
-- åñëè ñòàëêåð â êîìàíäå
if self.team then
-- óáðàòü èç òåêóùåé êîìàíäû
self:finalize()
end
self.team = team
if team then
if not teams[team] then
teams[team] = { npcs = {}, npcs_num = 0, idle_end = 0 }
end
self.a = teams[team]
-- self.a.npcs[npc:id()] = npc
table.insert( self.a.npcs, npc )
-- printf( "[dialogs] adding %s to dlgteam %s", npc:name(), team )
end
end
end
function dialog_mgr:finalize()
if self.team then
-- óáðàòü ñòàëêåðà èç ñïèñêà
for i, v in pairs(self.a.npcs) do
if v:id() == self.object:id() then
table.remove( self.a.npcs, i )
break
end
end
self.team = nil
-- åñëè íèêîãî íå îñòàëîñü, ñáðîñèòü äèàëîã
if #self.a.npcs == 0 then
self:reset_dialog()
end
end
end
-- âêëþ÷èòü âîçìîæíîñòü íà÷àëà äèàëîãà
function dialog_mgr:enable( dlgs )
if self.team then
self.a.dlgs = dlgs
end
end
-- âûêëþ÷èòü âîçìîæíîñòü íà÷àëà äèàëîãà
function dialog_mgr:disable()
if self.team then
self.a.dlgs = nil
end
end
-- òåêóùèé àêòèâíûé äèàëîã
function dialog_mgr:active()
return self.team and self.a.cur_dlg
end
-- íà÷àëî íîâîãî äèàëîãà
function dialog_mgr:new_dialog()
-- âûáîð íîâîãî äèàëîãà
if #self.a.dlgs > 1 then
local r = math.random( 1, #self.a.dlgs - 1 )
if self.a.dlgs[r] == self.a.last_dlg then
r = r + 1
end
self.a.cur_dlg = self.a.dlgs[r]
else
self.a.cur_dlg = self.a.dlgs[1]
end
self.a.last_dlg = self.a.cur_dlg
-- printf( "!!!!! NEW_DIALOG="..self.a.cur_dlg )
-- ïîïðîáîâàòü âûáðàòü ïåðâóþ ôðàçó
if not self:new_phrase() then
-- åñëè íå ñìîãëè, òî äèàëîã íà÷àòüñÿ íå ìîæåò
self:reset_dialog()
-- ñëåäóþùóþ ïðîâåðêó âîçìîæíîñòè íà÷àëà äèàëîãà îòëîæèòü íà íåáîëüøîå âðåìÿ
self.a.idle_end = time_global() + 5000
end
end
-- ñáðîñèòü äèàëîã
function dialog_mgr:reset_dialog()
self.a.dlgs = nil
self.a.cur_dlg = nil
self.a.cur_phrase = nil
self.a.cur_npc = nil
-- ñëåäóþùèé äèàëîã ìîæåò íà÷àòüñÿ ëèøü ïî èñòå÷åíèþ ïåðèîäà ìîë÷àíêè
self.a.idle_end = time_global() + math.random( idle_min, idle_max ) * 1000
-- printf( "reset dialog" )
end
-- îòìåíèòü òåêóùèé ïåðèîä ìîë÷àíêè ìåæäó äèàëîãàìè
function dialog_mgr:reset_idle()
if self.team then
self.a.idle_end = 0
end
end
-- ïîäãîòîâêà íîâîé ôðàçû
function dialog_mgr:new_phrase()
clear_table( avail )
-- åñëè äèàëîã óæå áûë íà÷àò (ò.å. åñòü òåêóùèé ãîâîðÿùèé)
if self.a.cur_npc then
-- âûáðàòü òîãî, êòî îòâåòèò. îí äîëæåí áûòü íåäàëåêî îò ïðåäûäóùåãî ãîâîðÿùåãî
for i, v in pairs(self.a.npcs) do
if v:id() ~= self.a.cur_npc:id() and self.a.cur_npc:position():distance_to_sqr( v:position() ) <= dist_max then
table.insert( avail, v )
end
end
if #avail == 0 then
-- åñëè îòâå÷àòü íåêîìó, òî ôðàçà íå âûáðàíà
return false
end
-- âûáîð íîâîãî ãîâîðÿùåãî
self.a.cur_npc = avail[math.random( 1, #avail )]
else
-- ïîïûòêà âûáîðà íîâîãî ãîâîðÿùåãî
self.a.cur_npc = self.a.npcs[math.random( 1, #self.a.npcs )]
-- ïîñìîòðåòü, ìîæåò ëè êòî-òî ïîòåíöèàëüíî ïðîäîëæèòü äèàëîã
local flg
for i, v in pairs(self.a.npcs) do
if v:id() ~= self.a.cur_npc:id() and self.a.cur_npc:position():distance_to_sqr( v:position() ) <= dist_max then
flg = true
break
end
end
if not flg then
-- åñëè íåò, òî äàæå è íå íà÷èíàòü äèàëîã
return false
end
end
-- âûáîð íîâîé ôðàçû
if not self.a.cur_phrase then
printf( self.a.cur_dlg )
self.a.cur_phrase = dialogs[self.a.cur_dlg][1]
else
local p = self.a.cur_phrase.next
if not p then
-- ñëåäóþùåé ôðàçû íåòó
return false
end
if type( p ) == "table" then
p = p[math.random( 1, #p )]
end
self.a.cur_phrase = dialogs[self.a.cur_dlg][p]
end
-- óñòàíîâèòü çàäåðæêó ïåðåä íîâîé ôðàçîé
self.a.phrase_delay_end = time_global() + math.random( pause_min, pause_max ) * 1000
self.a.phrase_playing = false
-- printf( "phrase selected" )
return true
end
-- îáíîâëåíèå
function dialog_mgr:update()
-- åñëè ñòàëêåð íå ñîñòîèò â êîìàíäå äëÿ äèàëîãîâ
if not self.team then
return
end
if self.a.cur_dlg then -- àêòèâåí ëè äèàëîã?
if self.object:id() == self.a.cur_npc:id() then -- îáíîâëåíèå òåêóùåãî ãîâîðÿùåãî?
if self.a.phrase_delay_end < time_global() then -- îêîí÷èëàñü ëè íåîáõîäèìàÿ çàäåðæêà ïåðåä ôðàçîé?
if self.a.phrase_playing then -- íà÷àëè ëè óæå èãðàòü çâóê?
if self.a.cur_npc:active_sound_count() == 0 then -- çâóê çàêîí÷èëñÿ?
if not self:new_phrase() then
-- åñëè íîâàÿ ôðàçà íå âûáðàíà, òî íàñòóïèë êîíåö äèàëîãà
self:reset_dialog()
end
end
else
-- ïðîèçíåñòè ôðàçó
snd.themes[1] = self.a.cur_phrase.snd
xr_sound.sound_update( self.a.cur_npc, snd, true )
self.a.phrase_playing = true
-- printf( "SNDSNDNSNDND = " .. snd.themes[1] )
end
end
end
else
-- åñëè ìîæíî, íà÷àòü äèàëîã è ó íàñ íå îäèí ãîâîðÿùèé
if self.a.dlgs and self.a.idle_end < time_global() and #self.a.npcs > 1 then
self:new_dialog()
end
end
end