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,400 @@
local npc_role = {noone=0, listener=1, director=2}
CAMP_SECTION = "camp"
--------------------------------------------------------------------------------
-- Precondition functions
--------------------------------------------------------------------------------
function sr_camp_idle_precondition(camp)
return true
end
function sr_camp_harmonica_precondition(camp)
--printf("camp harmonica precondition")
if(#camp.harmonica_table>0) then
local n = 0
for k,v in pairs(camp.npc) do
n = n + 1
end
if(n>1) then
for k,v in pairs(camp.npc) do
local scheme = db.storage[k] and db.storage[k].active_scheme and db.storage[k][db.storage[k].active_scheme]
local npc = db.storage[k] and db.storage[k].object
--printf(" is director %s", tostring(v.harmonica==npc_role.director))
--printf(" base_action %s", tostring(scheme.base_action) )
--printf(" description %s", tostring(scheme.description) )
if(v.harmonica==npc_role.director) and (scheme ~= nil and scheme.base_action == scheme.description) and npc ~= nil and not xr_meet.is_meet(npc) then
--if(v.harmonica==npc_role.director) then
--printf(" return true [%s]", k)
return true
end
end
end
end
--printf(" return false")
return false
end
function sr_camp_guitar_precondition(camp)
--printf("camp guitar precondition")
if(#camp.guitar_table>0) then
local n = 0
for k,v in pairs(camp.npc) do
n = n + 1
end
if(n>1) then
for k,v in pairs(camp.npc) do
local scheme = db.storage[k] and db.storage[k].active_scheme and db.storage[k][db.storage[k].active_scheme]
local npc = db.storage[k] and db.storage[k].object
--printf(" is director %s", tostring(v.guitar==npc_role.director))
--printf(" base_action %s", tostring(scheme.base_action) )
--printf(" description %s", tostring(scheme.description) )
if(v.guitar==npc_role.director) and (scheme ~= nil and scheme.base_action == scheme.description) and npc ~= nil and not xr_meet.is_meet(npc) then
--if(v.guitar==npc_role.director) then
--printf(" return true [%s]", k)
return true
end
end
end
end
--printf(" return false")
return false
end
function sr_camp_story_precondition(camp)
if(#camp.story_table>0) then
local n = 0
for k,v in pairs(camp.npc) do
local npc = db.storage[k] and db.storage[k].object
if npc ~= nil and not xr_meet.is_meet(npc) then
n = n + 1
end
end
if(n>1) then
return true
end
end
return false
end
--------------------------------------------------------------------------------
-- Êëàññ CCampManager
--------------------------------------------------------------------------------
-- Êåìï ñîäåðæèò ñâîè äåéñòâèÿ â òåðìèíàõ ñîñòîÿíèÿ êåìïà (ðàññêàç èñòîðèè, ìóçûêà, îæèäàíèå), à íå â òåðìèíàõ àíèìàöèé ïåðñîíàæåé
-- Êåìï âîçâðàùàåò ñâîå ñîñòîÿíèå, à ðåøåíèå êàêóþ èìåííî àíèìàöèþ èãðàòü ïðèíèìàåò ôèíàëüíàÿ ñõåìà, íàïðèìåð xr_animpoint
class "CCampManager"
function CCampManager:__init(object, ini)
self.object = object
self.ini = ini
local stories = utils.cfg_get_string(ini, CAMP_SECTION, "stories", nil, false, "", "test_story")
self.story_table = parse_names(stories)
local guitars = utils.cfg_get_string(ini, CAMP_SECTION, "guitar_themes", nil, false, "", "test_guitar")
self.guitar_table = parse_names(guitars)
local harmonicas = utils.cfg_get_string(ini, CAMP_SECTION, "harmonica_themes", nil, false, "", "test_harmonica")
self.harmonica_table = parse_names(harmonicas)
self.npc = {}
self.schemes = {}
-- Õðàíèëèùå äëÿ ðåæèññåðà ëàãåðÿ. Ðåæèññåðåì ÿâëÿåòñÿ ñòàëêåð, çàòåÿâøèé íåîáû÷íîå ïîâåäåíèå
self.director = nil
-- Òåêóùåå ñîñòîÿíèå
self.active_state = "idle"
--' Äëÿ òåñòà ñîçäàåì îáúåêò èñòîðèè
self.sound_manager = sound_manager.get_sound_manager(CAMP_SECTION..self.object:id())
self.sound_manager_started = true
-- Ñîñòîÿíèÿ êåìïà
self.states = {
idle = {
director_state = nil,
general_state = "idle",
min_time = 30000,
max_time = 40000,
timeout = 0,
transitions = {harmonica = 30, guitar = 30, story = 40},
precondition = sr_camp_idle_precondition
},
harmonica = {
director_state = "play_harmonica",
general_state = "listen",
min_time = 10000,
max_time = 11000,
timeout = 3000,
transitions = {idle = 100, harmonica = 0, guitar = 0, story = 0},
precondition = sr_camp_harmonica_precondition
},
guitar = {
director_state = "play_guitar",
general_state = "listen",
min_time = 10000,
max_time = 11000,
timeout = 4500,
transitions = {idle = 100, harmonica = 0, guitar = 0, story = 0},
precondition = sr_camp_guitar_precondition
},
story = {
director_state = "tell",
general_state = "listen",
min_time = 10000,
max_time = 11000,
timeout = 0,
transitions = {idle = 100, harmonica = 0, guitar = 0, story = 0},
precondition = sr_camp_story_precondition
},
}
self.active_state_time = 0
self.timeout = 0
self.idle_talker = nil
end
-- Ïåðåêëþ÷àåò ñîñòîÿíèÿ êåìïà
function CCampManager:update()
-- Åñëè ñàóíäìåíåäæåð ãîâîðèò êàêóþ òî èñòîðèþ - æäåì îêîí÷àíèÿ.
if not self.sound_manager:is_finished() then
self.sound_manager:update()
return
end
if self.sound_manager_started == false then
return
end
-- Åñëè êòî-òî ãîâîðèò àéäëîâóþ ôðàçó, æäåì ïîêà îí äîãîâîðèò.
if(self.idle_talker~=nil) then
if(xr_sound.sound_table[self.idle_talker]) then
return
else
self.idle_talker = nil
end
end
-- Âûáîð ñîñòîÿíèÿ êåìïà. Òóò ðåøàåòñÿ ÷òî äåëàòü äàëüøå.
--printf("camp time %s", tostring(self.active_state_time - time_global()))
if(self.active_state_time < time_global()) then
self:set_next_state()
if self:get_director() == false then
self.active_state = "idle"
for k,v in pairs(self.npc) do
v.state = self.active_state
end
--self:set_next_state()
end
self.sound_manager_started = false
for k,v in pairs(self.npc) do
if(db.storage[k]) then
xr_logic.issue_event(db.storage[k].object, db.storage[k][db.storage[k].active_scheme], "update")
end
local meet = db.storage[k] and db.storage[k].meet and db.storage[k].meet.meet_manager
if meet then
meet.npc_is_camp_director = self.director == k
end
end
end
-- Âûáèðàåì íîâóþ òåìó äëÿ ñàóíäìåíåäæåðà (Äëÿ ãèòàðû è ãàðìîøêè íóæíî áóäåò þçàòü äðóãîé ìåòîä, ÷òîáû íå íà÷àëè èãðàòü çâóê äî òîãî, êàê äîñòàíóò èíñòðóìåíò)
if(self.timeout~=0) and (self.timeout<=time_global()) then
self:set_story()
self.timeout = 0
end
-- Áîëòîâíÿ â àéäëå
if(self.active_state=="idle") then
local npc_count = 0
local talkers = {}
for k,v in pairs(self.npc) do
npc_count = npc_count + 1
table.insert(talkers, k)
end
if(npc_count~=0) then
self.idle_talker = talkers[math.random(#talkers)]
xr_sound.set_sound_play(self.idle_talker, "state")
end
end
end
function CCampManager:set_next_state()
--printf("CAMP set_next_state")
local transitions = self.states[self.active_state].transitions
local rnd = math.random(100)
for k,v in pairs(transitions) do
--printf("check %s value %s rnd %s", k, v, rnd )
if(rnd<v) then
if self.states[k].precondition(self) == true then
self.active_state = k
--printf("FOUND")
break
end
else
rnd = rnd - v
end
end
--printf("active state %s", self.active_state)
for k,v in pairs(self.npc) do
v.state = self.active_state
end
self.active_state_time = time_global()+math.random(self.states[self.active_state].min_time, self.states[self.active_state].max_time)
self.timeout = time_global()+self.states[self.active_state].timeout
end
function CCampManager:get_director()
if(self.active_state=="idle") then
self.director = nil
return
end
local directors = {}
local npc_count = 0
for k,v in pairs(self.npc) do
npc_count = npc_count + 1
local storage = db.storage[k]
if storage ~= nil then
local scheme = storage.active_scheme and storage[storage.active_scheme]
local npc = storage.object
if(v[self.active_state]==npc_role.director) and (scheme ~= nil and scheme.base_action == scheme.description) and not xr_meet.is_meet(npc) then
table.insert(directors, k)
end
end
end
if(npc_count==0) then
self.director = nil
return
end
if(#directors<1) then
return false
--abort("There is no director for state [%s]. Camp [%s]!!!", self.active_state, self.object:name())
elseif(#directors==1) then
self.director = directors[1]
else
self.director = directors[math.random(#directors)]
end
--printf("camp director [%s]", self.director)
end
function CCampManager:set_story()
if(self.active_state=="story") then
self.sound_manager:set_storyteller(self.director)
self.sound_manager:set_story(self.story_table[math.random(#self.story_table)])
self.sound_manager_started = true
elseif(self.active_state=="idle") then
self.sound_manager_started = true
end
end
-- Âîçâðàùàåò òåêóùåå äåéñòâèå êåìïà
function CCampManager:get_camp_action(npc_id)
if(npc_id==nil) then
abort("Trying to use destroyed object!")
end
if(self.npc[npc_id]==nil) then
return
end
return self.npc[npc_id].state, self.director==npc_id
end
-- Ðåãèñòðèò ïåðñîíàæà â êåìï
function CCampManager:register_npc(npc_id)
-- local npc_id = npc:id()
--printf("Register NPC to camp %s", self.object:id())
self.npc[npc_id] = {state = self.active_state}
db.storage[npc_id].registred_camp = self.object:id()
-- Ïðè ðåãèñòðàöèè ïåðñîíàæà, ïðîâåðÿåì êàêèå ðîëè îí ìîæåò âûïîëíÿòü.
for k,v in pairs(self.states) do
--printf("FIND NPC ROLE %s", npc_id)
local role = self:get_npc_role(npc_id, k)
if(role==npc_role.noone) then
abort("Wrong role for npc[%s] with id[%d] in camp [%s]!!!", npc:name(), npc_id, self.object:name())
end
self.npc[npc_id][k] = role
end
self.sound_manager:register_npc(npc_id)
xr_logic.issue_event(db.storage[npc_id].object, db.storage[npc_id][db.storage[npc_id].active_scheme], "update")
end
-- Óáèðàåò ïåðñîíàæà èç êåìïà
function CCampManager:unregister_npc(npc_id)
-- local npc_id = npc:id()
-- Åñëè óäàëÿåòñÿ ðåæèññåð ëàãåðÿ
if self.director == npc_id then
self.sound_manager_started = false
self.active_state_time = 0
self.director = nil
self.active_state = "idle"
for k,v in pairs(self.npc) do
v.state = self.active_state
end
end
db.storage[npc_id].registred_camp = nil
self.npc[npc_id] = nil
self.sound_manager:unregister_npc(npc_id)
end
function CCampManager:get_npc_role(npc_id, state)
local scheme = db.storage[npc_id][db.storage[npc_id].active_scheme]
if scheme == nil then
return npc_role.noone
end
local npc_actions = scheme.approved_actions
local descr = scheme.description
if(state=="harmonica") or (state=="guitar") then
descr = descr.."_"..state
--printf("finding music director [%s]", descr)
for i = 1,#npc_actions do
--printf("check action [%s]", npc_actions[i].name)
if(npc_actions[i].name==descr) then
--printf("DIRECTOR FOUND music")
return npc_role.director
end
end
return npc_role.listener
elseif(state=="story") then
for i = 1,#npc_actions do
if(npc_actions[i].name==descr) or (npc_actions[i].name==descr.."_weapon") then
--printf("DIRECTOR FOUND story")
return npc_role.director
end
end
return npc_role.listener
elseif(state=="idle") then
return npc_role.listener
end
return npc_role.noone
end
--------------------------------------------------------------------------------
function get_current_camp(position)
for k,v in pairs(bind_camp.camps) do
if v.object:inside(position) then
return v.camp
end
end
return nil
end
function start_guitar(npc)
local camp_id = db.storage[npc:id()].registred_camp
if camp_id == nil then
return
--abort("trying to play guitar without camp [%s]",tostring(npc:name()))
end
local camp = bind_camp.camps[camp_id].camp
camp.sound_manager:set_storyteller(camp.director)
camp.sound_manager:set_story(camp.guitar_table[math.random(#camp.guitar_table)])
camp.sound_manager_started = true
camp.sound_manager:update()
end
function start_harmonica(npc)
local camp_id = db.storage[npc:id()].registred_camp
if camp_id == nil then
return
--abort("trying to play harmonica without camp")
end
local camp = bind_camp.camps[camp_id].camp
camp.sound_manager:set_storyteller(camp.director)
camp.sound_manager:set_story(camp.harmonica_table[math.random(#camp.harmonica_table)])
camp.sound_manager_started = true
camp.sound_manager:update()
end