Перейти к содержанию

Рекомендуемые сообщения

 
 

а ты как в кастом дату написал рестриктора?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

FacingSlave 

[logic]
cfg = scripts\dead_city\restrictor\dead_city_start_space_restrictor_logic.ltx

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

DEL

Изменено пользователем denis2000

Путь во мгле. Связь времен.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

P.S. решил тем что перебросил файл с логикой в другую папку

  • Смех 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

Решил "воссоздать" в механику рассказа НПС у костра историй и легенд голосом Профа, с последующей выдачей окружающими НПС реакций типа "ого!". В скриптах я полный ноль, поэтому решил просто копировать готовое. За пример брал секцию "story" и "test_story" в конфигах и скриптах.

Таким образом, в папке configs\misc в файле sound_stories.ltx были проведены следующие манипуляции:

Спойлер

 

[test_story]
;номер, звук, пауза(сек)
0 = teller,            intro_joke, 1
1 = teller,            joke,        0.1
2 = reaction_all,     reac_laugh,    0.2
3 = reaction,        reac_joke,    0

[test_legend] -- моя секция для легенд/история
;номер, звук, пауза(сек)
0 = teller,            legend,        0.1
1 = reaction,        reac_legend,    0

 

В файле script_sound_music_and_stories.ltx были прописаны следующие секции:

Спойлер

 

legend
reac_legend

[legend]
type = npc
avail_communities = stalker
npc_prefix = true
path = talk\stories\legend002_part_
shuffle = rnd
idle = 0,0
group_snd = true

[reac_legend]
type = npc
avail_communities = stalker
npc_prefix = true
path = reactions\story\cool_info_
shuffle = rnd
idle = 0,0

 

Далее идут скрипты. Там в файле xr_kamp я просто дублировал все значения и строки, связанные с секцией story. Прикладываю измененные фрагменты кода.

Спойлер

local avail_state =
{
    idle                = {directed = standard_states},
    pre_harmonica       = {directed = {"wait_harmonica"}, undirected = standard_states},
    harmonica           = {directed = {"play_harmonica"}, undirected = standard_states},
    post_harmonica      = {directed = {"wait_harmonica"}, undirected = standard_states},
    pre_guitar          = {directed = {"wait_guitar"},    undirected = standard_states},
    guitar              = {directed = {"play_guitar"},    undirected = standard_states},
    post_guitar         = {directed = {"wait_guitar"},    undirected = standard_states},
    story               = {directed = {"declarate"},      undirected = standard_states},
    legend              = {directed = {"declarate"},      undirected = standard_states},
}

local avail_sound =
{
    idle                = {directed = "idle"},
    pre_harmonica       = {directed = "pre_harmonica",    undirected = ""},
    harmonica           = {directed = "",                 undirected = ""},
    post_harmonica      = {directed = "",                 undirected = "reac_harmonica"},
    pre_guitar          = {directed = "pre_guitar",       undirected = ""},
    guitar              = {directed = "",                 undirected = ""},
    post_guitar         = {directed = "",                 undirected = "reac_guitar"},
    story               = {directed = "",                 undirected = ""},
    legend              = {directed = "",                 undirected = ""},
}

local timeout =
{
    idle                = {min = 30000},
    pre_harmonica       = {min = 3000},
    harmonica           = {min = 5000, soundstart = true},
    post_harmonica      = {min = 3000},
    pre_guitar          = {min = 3000},
    guitar              = {min = 5000, soundstart = true},
    post_guitar         = {min = 3000},
    story               = {min = 1000, soundstart = true},
    legend              = {min = 1000, soundstart = true},
}

local target_states =
{
    idle                = {idle = 0, pre_harmonica = 25, pre_guitar = 25, story = 50, legend = 50},
    pre_harmonica       = {harmonica = 100},
    harmonica           = {post_harmonica = 100},
    post_harmonica      = {idle = 70, harmonica = 30},
    pre_guitar          = {guitar = 100},
    guitar              = {post_guitar = 100},
    post_guitar         = {idle = 70, guitar = 30},
    story               = {idle = 100},
    legend              = {idle = 100},
}

-----

    local p = math.random(0, max_rnd)

    for state_name, prob in pairs (avail_states) do
        p = p - prob
        if p <= 0 then
            if state_name == "idle" then
                self.director = nil
                if self.kamp_state ~= "idle" then
                    camp_npc.begin = nil
                end
            elseif state_name == "story" then
                self.sound_manager:set_story("test_story")
                self.director = npc_id
            else
                camp_npc.begin = nil
                if timeout[state_name].soundstart then
                    camp_npc.need_sound_begin = true
                end
                self.director = npc_id
            end
            self.kamp_state = state_name
            self.begin = time_global()
            for _, npc_data in pairs (self.npc) do
                npc_data.is_new = true
            end
            return
        end
    end


 ------   


local p = math.random(0, max_rnd)

    for state_name, prob in pairs (avail_states) do
        p = p - prob
        if p <= 0 then
            if state_name == "idle" then
                self.director = nil
                if self.kamp_state ~= "idle" then
                    camp_npc.begin = nil
                end
            elseif state_name == "legend" then
                self.sound_manager:set_legend("test_legend")
                self.director = npc_id
            else
                camp_npc.begin = nil
                if timeout[state_name].soundstart then
                    camp_npc.need_sound_begin = true
                end
                self.director = npc_id
            end
            self.kamp_state = state_name
            self.begin = time_global()
            for _, npc_data in pairs (self.npc) do
                npc_data.is_new = true
            end
            return
        end
    end
end

-----

    if self.kamp_state == "story" then
        sound = ""
    else
        sound = avail_sound[self.kamp_state][is_director and "directed" or "undirected"]
    end

    if self.kamp_state == "legend" then
        sound = ""
    else
        sound = avail_sound[self.kamp_state][is_director and "directed" or "undirected"]
    end

    return state, sound
end

------

    if trance_state == nil then
        self.npc[npc_id] =
        {
            position_idx = nil,
            trance_state = nil,
            is_new = false,
            need_sound_begin = false,
            states = {declarate = true, sit = true, sit_ass = true, sit_knee = true},
            kamp_states = {idle = true, story = true, legend = true},
        }
    else
        self.npc[npc_id] =
        {
            position_idx = nil,
            trance_state = trance_state,
            is_new = false,
            need_sound_begin = false,
            states = {declarate = true, trans = true},
            kamp_states = {idle = true, story = true, legend = true},
        }
    end

 

И, наконец, в скрипте sound_manager добавил функции set_legend и CLegend по аналогии с set_story и CStory

Спойлер

 


-' Установить какую историю менеджер должен отыграть
function sound_manager:set_story(story_id)
    self.story = CStory(story_id)
    --printf("Set story sm [%s] = [%s]", self.id, story_id)
end
--' Установить какую легенду менеджер должен отыграть
function sound_manager:set_legend(legend_id)
    self.story = CLegend(legend_id)
    --printf("Set story sm [%s] = [%s]", self.id, legend_id)
end

-----

--' Класс "история". Содержит дерево фраз. У каждой фразы указано должен ли ее говорить рассказчик или слушатели.
class "CStory"
function CStory:__init(story_id)
    --printf("Creating story [%s]", tostring(story_id))

    if not story_ltx:section_exist(story_id) then
        abort("There is no story [%s] in sound_stories.ltx", tostring(story_id))
    end

    self.replics = {}
    --' Вычитываем шаблон истории из ini файла

    local n = story_ltx:line_count(story_id)
    local id, value = "",""

    for i=0,n-1 do
        result, id, value    = story_ltx:r_line(story_id,i,"","")

        local t = parse_names(value)

        if t[1] ~= "teller" and t[1] ~= "reaction" and t[1] ~= "reaction_all" then
            abort("Wrong fist field [%s] in story [%s]", tostring(t[1]), tostring(story_id))
        end

        self.replics = {who = t[1], theme = t[2], timeout = t[3]}
    end
    self.id = tostring(story_id)
    self.max_phrase_count = n-1
    self.next_phrase = 0
    --print_table(self.replics)
end
--' Закончена ли история
function CStory:is_finished()
    return self.next_phrase > self.max_phrase_count
end
--' Ресет истории
function CStory:reset_story()
    self.next_phrase = 0
end
--' Возвращает следующую фразу
function CStory:get_next_phrase()
    local phrase = self.replics[self.next_phrase]
    self.next_phrase = self.next_phrase + 1
    return phrase
end

--' Класс "легенда". Содержит дерево фраз. У каждой фразы указано должен ли ее говорить рассказчик или слушатели.
class "CLegend"
function CLegend:__init(legend_id)
    --printf("Creating story [%s]", tostring(legend_id))

    if not story_ltx:section_exist(legend_id) then
        abort("There is no story [%s] in sound_stories.ltx", tostring(legend_id))
    end

    self.replics = {}
    --' Вычитываем шаблон истории из ini файла

    local n = story_ltx:line_count(legend_id)
    local id, value = "",""

    for i=0,n-1 do
        result, id, value    = story_ltx:r_line(legend_id,i,"","")

        local t = parse_names(value)

        if t[1] ~= "teller" and t[1] ~= "reaction" and t[1] ~= "reaction_all" then
            abort("Wrong fist field [%s] in story [%s]", tostring(t[1]), tostring(legend_id))
        end

        self.replics = {who = t[1], theme = t[2], timeout = t[3]}
    end
    self.id = tostring(legend_id)
    self.max_phrase_count = n-1
    self.next_phrase = 0
    --print_table(self.replics)
end
--' Закончена ли история
function CLegend:is_finished()
    return self.next_phrase > self.max_phrase_count
end
--' Ресет истории
function CLegend:reset_story()
    self.next_phrase = 0
end
--' Возвращает следующую фразу
function CLegend:get_next_phrase()
    local phrase = self.replics[self.next_phrase]
    self.next_phrase = self.next_phrase + 1
    return phrase
end

 

В игре (вы будете удивлены) ничего не работает. Не вылетает, но НПС перестали рассказывать даже анекдоты у костра, просто молчат, играют на инструментах, иногда бормочут что-то под нос.

Как поправить положение и нормально внедрить механику рассказывания НПС у костра историй с последующими реакциями окружающих НПС?

Изменено пользователем Бессмертный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

Бессмертный Глянул мельком. ВЕЗДЕ в скриптах, где добавляли элементы в таблицу лишние запятые в конце.

PS: И используйте тег код, тег спойлер корежит выкладываемый код!

Изменено пользователем denis2000

Путь во мгле. Связь времен.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 
4 часа назад, denis2000 сказал:

Бессмертный Глянул мельком. ВЕЗДЕ в скриптах, где добавляли элементы в таблицу лишние запятые в конце.

PS: И используйте тег код, тег спойлер корежит выкладываемый код!

Хм. Где, например? Если вы про начало скрипта xr_kamp, то я просто копировал строки от story, и если там были запятые, то я тоже их переносил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

Напомните пожалуйста, как перемотать время на определенное через триггер? Мне надо, чтобы после выхода с локации было определенное время, чтобы синхронизировать с событиями.

Изменено пользователем Ayden

Волк волку- волк, человек человеку- собутыльник.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 
42 минуты назад, Ayden сказал:

перемотать время

При использовании проводников на локации есть функция перемотки, `level.change_game_time`. А в xr_effects есть две реализации, установка точного времени, или просто изменение по дельте. `xr_effects.set_game_time` и `xr_effects.forward_game_time`. В общем, в ЗП это много где использовалось. 

  • Жму руку 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 
17 минут назад, Hrust сказал:

При использовании проводников на локации есть функция перемотки, `level.change_game_time`. А в xr_effects есть две реализации, установка точного времени, или просто изменение по дельте. `xr_effects.set_game_time` и `xr_effects.forward_game_time`. В общем, в ЗП это много где использовалось. 

Ну я видел где-то простенький скрипт в вопроснице вроде, но найти не могу, мне надо на определенное время, выйти в 2 часа ночи, чтобы по логике постовые спали и можно было прошмыгнуть, сам крепкий сон я им реализовал. 


Волк волку- волк, человек человеку- собутыльник.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

Тогда сеттером по примеру можно и воспользоваться, но тут функция именно для разговора была сделана:


function set_game_time(actor, npc, p)
	local real_hours = level.get_time_hours()
	local real_minutes = level.get_time_minutes()
	local hours = tonumber(p[1])
	local minutes = tonumber(p[2])
	if p[2] == nil then
		minutes = 0
	end
	local hours_to_change = hours - real_hours
	if hours_to_change <= 0 then
		hours_to_change = hours_to_change + 24
	end
	local minutes_to_change = minutes - real_minutes
	if minutes_to_change <= 0 then
		minutes_to_change = minutes_to_change + 60
		hours_to_change = hours_to_change - 1
	elseif hours == real_hours then
		hours_to_change = hours_to_change - 24
	end
	level.change_game_time(0,hours_to_change,minutes_to_change)
	level_weathers.get_weather_manager():forced_weather_change()
	surge_manager.get_surge_manager().time_forwarded = true
	printf("set_game_time: time changed to [%d][%d]", hours_to_change, minutes_to_change)
end

Хотя я сам не знаю, в чём отличие, но можно немного переработать приём аргументов, чтобы вместо `p` было два отдельных.

  • Жму руку 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

Hrust Спасибо! Насчет level_weathers.get_weather_manager():forced_weather_change() дало идею, а ведь можно и дождь врубить под это, еще аутентичнее будет для костыльного "стелса") Я просто врагов сделал глуховатыми на скрипте спящими, что только стрельба их разбудит, чисто с ними на 5 минут сценка, чтобы напряжение создать)

Изменено пользователем Ayden
  • Мастер! 1

Волк волку- волк, человек человеку- собутыльник.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

а какие строчки в конфиге оружия отвечает за расположение в режиме прицеливая?

я просто хочу пофиксить кривое расположение прицелов на широковорматном маниторе

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

стрелок_2009 ссылка, настраивается в игре через худ аджаст.

  • Мастер! 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

Ребят, еще вопросец, по интерфейсу, как при диалоге с нпс открыть окно ящика, чтобы нпс нес с собой половину лута (например с ограничением в 30 кг)?) Навеяно Гаммой. 


Волк волку- волк, человек человеку- собутыльник.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 
8 часов назад, denis2000 сказал:

Бессмертный Глянул мельком. ВЕЗДЕ в скриптах, где добавляли элементы в таблицу лишние запятые в конце.

PS: И используйте тег код, тег спойлер корежит выкладываемый код!

По вашему совету поправил отображение кода скриптов под спойлерами.

Не очень понимаю, куда копать в решении вопроса. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

Бессмертный Откуда этот странный код вообще?


Путь во мгле. Связь времен.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

При спавне НПС через смарт_террейн командой =create_squad происходит такой вылет, как исправить и что его вызывает?
 

Спойлер

FATAL ERROR

[error]Expression    : fatal error
[error]Function      : CScriptEngine::lua_error
[error]File          : X:\GitHub\ixray-1.6-stcop\src\xrScripts\script_engine.cpp
[error]Line          : 61
[error]Description   : <no expression>
[error]Arguments     : LUA error: [string "sim_board"]:228: attempt to index local 'spawn_smart' (a nil value)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 
10 минут назад, Gambimo сказал:

ixray-1.6-stcop

Зная этот движок, спрошу: в логе есть какие-нибудь записи, которые начинаются со слова ABORT? Можешь приложить лог?


Мод в разработке - X-7: Эпицентр
Дискорд мода - https://discord.gg/NjnUnKDD

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 
24 минуты назад, denis2000 сказал:

Бессмертный Откуда этот странный код вообще?

Это вырезки (брал только те секции, которые копировал и куда вносил изменения по формату "оригинал "story", далее моя секция "legend") из моих скриптов xr_kamp и sound_manager. На их достоверность не претендую, а вовсе наоборот, ищу, в чем ошибка.

Попробую по-другому поставить вопрос: может есть возможность не изобретать велосипед и какой-то другой способ заставить неписей рассказывать эти истории и после реагировать на них, как это было в некоторых модах на ТЧ?

Так-то можно просто добавить эти истории к одиночным репликам у костра типа "Да-а, еще 3-4 таких похода как вчера, да чтоб хабар не хуже...". Но тогда они будут просто произноситься, без реакции со стороны остальных НПС в лагере. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 
33 минуты назад, Бессмертный сказал:

Это вырезки ... из моих скриптов xr_kamp и sound_manager.

Ладно, не буду спрашивать почему ваш код кардинально отличается от оригинального.
 

Приведите, как у вас до правки и после правки выглядит таблица avail_state например.


Путь во мгле. Связь времен.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

Бессмертный 

15 часов назад, Бессмертный сказал:

В игре (вы будете удивлены) ничего не работает. Не вылетает, но НПС перестали рассказывать даже анекдоты у костра, просто молчат, играют на инструментах, иногда бормочут что-то под нос.

В зп xr_kamp не используется, и нужно править:

\configs\scripts\camp.ltx

\scripts\sr_camp.script

  • Жму руку 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 
9 минут назад, Yara сказал:

В зп xr_kamp не используется

Но вполне работает если задействовать.

С другой стороны, судя по коду, используется не ЗП, а что вопрошающий скрывает!

Изменено пользователем denis2000

Путь во мгле. Связь времен.
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 
21 минуту назад, denis2000 сказал:

Но вполне работает если задействовать.

С другой стороны, судя по коду, используется не ЗП, а что вопрошающий скрывает!

Вопрошающий не скрывает, вопрошающий ошибся темой... За что приношу извинения. Потерялся в темах и запутал вас.

Скрипты у меня, конечно, от ЧН, а не от ЗП.

Если еще актуально, то вот, как выглядит avail_state до правок.

local avail_state =
{
      idle                = {directed = standard_states},
      pre_harmonica       = {directed = {"wait_harmonica"}, undirected = standard_states},
      harmonica           = {directed = {"play_harmonica"}, undirected = standard_states},
      post_harmonica      = {directed = {"wait_harmonica"}, undirected = standard_states},
      pre_guitar          = {directed = {"wait_guitar"},    undirected = standard_states},
      guitar              = {directed = {"play_guitar"},    undirected = standard_states},
      post_guitar         = {directed = {"wait_guitar"},    undirected = standard_states},
      story               = {directed = {"declarate"},      undirected = standard_states},
}

Тем не менее, есть ли способ заставить неписей проигрывать эти "истории" и реагировать на них, просто откопировав часть скриптовых функций от тех же, скажем, анекдотов? Может, есть модификации, где методы реализации можно было бы подсмотреть? 

Или в ЧН и ЗП логика лагеря устроена принципиально разным образом? 

Изменено пользователем Бессмертный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
 

Люди есть скрипт или фича чтобы партикл отражался от нпс?

К примеру есть нпс, я хочу повесить партикл типо от него электричеством отдаём.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти

  • Последние посетители   1 пользователь онлайн