Перейти к контенту

Уроки по модостроению


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

Здравствуйте. Хочу написать метод возвращения в ЧН губной гармошки. В интернете есть статьи для ТЧ, но в ЧН требуются дополнительные действия, которые пришлось поискать.

Сначала открываем файл xr_kamp.script по адресу gamedata/scripts

Скрытый текст

Здесь в строчке  self.trans_kamp = { idle  = { idle = 0, pre_harmonica = 0, pre_guitar = 50, story = 50}, выставляем вероятность pre_harmonica выше нуля, я например сделал так:  self.trans_kamp = { idle  = { idle = 0, pre_harmonica = 20, pre_guitar = 30, story = 50} но в сумме должно получиться не больше 100. Параметр pre_harmonica — это вероятность с которой НПС начнет играть на гармошке, pre_guitar —  соответственно вероятность игры на гитаре, и story — предположительно вероятность рассказа анекдотов. Далее ищем в файле этот отрывок и убираем черточки впереди, должно получиться так:

        if npc:object("harmonica_a") then
            self.npc[npc_id].states["play_harmonica"] = true
            self.npc[npc_id].states["wait_harmonica"] = true
            self.kamp_states["pre_harmonica"] = true
            self.kamp_states["harmonica"] = true
            self.kamp_states["post_harmonica"] = true
        else
            self.npc[npc_id].states["play_harmonica"] = false
            self.npc[npc_id].states["wait_harmonica"] = false
            self.kamp_states["pre_harmonica"] = false
            self.kamp_states["harmonica"] = false
            self.kamp_states["post_harmonica"] = false
        end

Дальше находим файл character_items.xml по адресу gamedata/configs/gameplay

Где в список добавляем: harmonica_a = 1, prob=0.6 \n, это позволит гармошке появляться в инвентаре НПС, где первая цифра кол-во предметов, а вторая (0.6) вероятность появления, можете написать свою, но она должна быть не больше 1.

Далее файл script_sound_music_and_stories.ltx по адресу gamedata/configs/misc:

Скрытый текст

В нем пишем в самом начале под:

intro_music
play_guitar
reac_music
play_harmonica ;- добавляем это

 

Далее под:

 

[reac_music]
type = npc
avail_communities = csky, stalker, bandit, dolg, freedom, army, renegade, killer, ecolog
npc_prefix = true
path = reactions\music\reaction_music_
shuffle = rnd
idle = 1,1,100
group_snd = true

 

[play_harmonica]
type = npc
avail_communities = csky, stalker, bandit, dolg, freedom, army, renegade, killer, ecolog 
;- здесь группировки которые будут играть на гармошке.
npc_prefix = true
path = music\harmonica_ 
;- адрес звуковых файлов
shuffle = rnd
idle = 1,1,100

 

Ну и последнее, в ЧН вместо звуковых файлов стоят "заглушка" — файл без звука, поэтому вам придется искать звуковые файлы на стороне. Я брал из Call of Chernobyl. Когда найдете их переименуйте в harmonica_номер по порядку, и скиньте в папку music, по адресу gamedata/sounds/characters_voice/human_номер(придется добавлять во все)/(группировка, к примеру bandit)/music. И ещё, необходимо будет начать новую игру, иначе вылет.

 


Примечание: если у вас есть анимация, но нет звука губной гармошки, необходимо сделать следующее: открываем файл state_mgr_animation_list.script по адресу gamedata/scripts

Скрытый текст

Находим анимацию "harmonica" (в оригинале это строки 437-452) и для элемента "into_music" меняем значение "harmonica" на "play_harmonica" (используем ровно то самое имя, которое дали добавленной в script_sound_music_and_stories.ltx секции, содержащей описание звуковых файлов). Должно получиться так:

        harmonica    = {    prop    = { maxidle = 3,
                                    sumidle = 3,
                                    rnd = 80 },
                        into    = { [0]    = {"sit_2_harmonica_1_0", {a="harmonica_a"}, "sit_2_harmonica_1_1"}},
                        out        = { [0]    = {"harmonica_1_sit_2_0", {d="harmonica_a"}, "harmonica_1_sit_2_1"} },
                        idle    = { [0]    = "harmonica_1" },
                        rnd        = { [0]    = {    "harmonica_2",
                                            "harmonica_3" } },
                        subanim = { [1] = {    prop = { maxidle = 3,
                                                     sumidle = 3,
                                                     rnd = 0 },
                                            into_music = "play_harmonica", -- в этой строчке
                                            into    = nil,
                                            out        = nil,
                                            idle    = { [0]    = "harmonica_0" },                                            
                                            rnd        = nil }}},

Анимация гитары чуть выше содержит правильное наименование секции звуковых файлов, в качестве примера.

 

  • Полезно 3
Ссылка на комментарий

Некролог (оповещение о смерти сталкера)
Сложность: легко
Автор скрипта: 
Weanchester, взято из stalkerin.gameru
Доработал: Hind

Скрытый текст

Создаём скрипт в папке gamedata/scripts и называем его как хотим (в данном случае dmb.script)
Туда пишем:

local level_name = {
	["l01_escape"] = "Кордон",
	["l02_garbage"] = "Свалка",
	["l03_agroprom"] = "НИИ Агропром",
	["l03u_agr_underground"] = "Подземелье НИИ Агропром",
	["l04_darkvalley"] = "Тёмная долина",
	["l04u_labx18"] = "Лаборатория X-18",
	["l05_bar"] = "Бар",
	["l06_rostok"] = "Дикая территория",
	["l07_military"] = "Арм.склады",
	["l08_yantar"] = "Янтарь",
	["l08u_brainlab"] = "Лаборатория X-16",
	["l10u_bunker"] = "Лаборатория X-10",
	["l10_radar"] = "Радар",
	["l11_pripyat"] = "Припять",
	["l12_stancia"] = "ЧАЭС",
	["l12_stancia_2"] = "ЧАЭС",
	["l12u_sarcofag"] = "Саркофаг",
	["l12u_control_monolith"] = "Управление Монолитом"
			}

local community = {
	["stalker"] = "Одиночка",
	["monolith"] = "Монолит",
	["military"] = "Военные",
	["bandit"] = "Бандит",
	["killer"] = "Наемник",
	["ecolog"] = "Эколог",
	["dolg"] = "Долг",
	["freedom"] = "Свобода",
	["zombied"] = "Зомбированный",
	["trader"] = "Торговец"
		}
 
function kill_npc(victim, who)
	if victim and IsStalker(victim) then
		local t = time_global()
		local dead_news = "%c[0,255,0,0]ПОГИБ СТАЛКЕР \\n%c[255,160,160,160]Группировка: %c[default]"..community[victim:character_community()].."\\n%c[255,160,160,160]Кличка: %c[default]"..victim:character_name().."\\n%c[255,160,160,160]Локация: %c[default]"..level_name[level.name()]..""
		db.actor:give_game_news(dead_news, "ui\\ui_icons_npc", Frect():set(2,130,124,124), 3000, 4000)
	elseif t > time_global() + 3000 then
		dmb2.news_sound()
	end
end

 


Вот и всё! Теперь после смерти сталкеров, спустя 3 секунды у нас будет оповещение о смерти со звуком!
З.Ы. Статья создана новичком, поэтому и оформлена по васяновски. Прошу меня простить если не понятно :)


Рабочая гитара
Сложность: средне
Автор скрипта: Hind
*некоторые функции брал из открытых источников. к сожалению авторов не помню
Лежала как то без дела гитара, поделюсь с народом.:drinks:

Скрытый текст

В этом уроке рассмотрим создание рабочей гитары, которая будет играть ту музыку, которую мы захотим. Нам надо всего 3 файла: bind_stalker.script, ваш_скрипт1.script, ваш_скрипт2.script (в моём случае это dmb и dmb2 соответственно)

Скрытый текст

Итак, в bind_stalker.script пишем:
В function actor_binder:net_destroy() пишем:

self.object:set_callback(callback.use_object, nil)


В function actor_binder:reinit() пишем:

self.object:set_callback(callback.use_object, self.use_object, self)


И где хотим добавляем следующую функцию:

function actor_binder:use_object(obj)
	dmb.use_item(obj)
	dmb.use_snd(obj)
end

 


Далее идём в наш созданный скрипт (в данном случае у меня это dmb.script), и там пишем следующее:

Скрытый текст
local tSound ={
gitara = "interface\\inv_gitara", -- путь до нашего звука при юзании предмета. Вместо него ставим какой хотим, разумеется
}

function use_item(obj)
	local obj = obj:section()
	if obj then
		if obj == "gitara" then -- наш предмет (в данном случае я уже создал юзабельный предмет, и подогнал его как Гитару)
			dmb2.start_timer() -- включаем таймер
		end
	end
end

function use_snd(obj)
	if obj and tSound[obj:section()] then
	local snd = xr_sound.get_safe_sound_object(tSound[obj:section()])
		if snd then
			snd:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 2.0)
		end
	end
end

 


и идём во второй наш скрипт, где пишем:

Скрытый текст
function action_timer()
    alife():create("gitara", db.actor:position(), 1, db.actor:game_vertex_id(), db.actor:id())
end
 
function start_timer() -- функция на которую мы ссылались при юзании в первом скрипте
    local iTimer = time_global() + 17000 -- наше время песни, т.е. 17 секунд. Спустя 17 секунд, гитара нам вернется в инвентарь.
    local function check_timer()
        return time_global() > iTimer
    end
    level.add_call(check_timer, action_timer)
end

 


Ну, и вроде всё! Не забудьте проверить правильность копирования, убрать стрелочки, с помощью которых я указывал на что-либо, и вуаля.


Если где-то ошибся, или не работает, маякните :biggrin:

  • Полезно 2
Ссылка на комментарий

Мой первый, но, надеюсь, полезный урок :)

 

Скрытый текст

Что нам понадобится:

 

Paint.NET

gamedata\textures\ui\ui_iconstotal.dds

gamedata\scripts\news_manager.script

Ваше изображение.

 

Сжимаем: Для сжатия используем бесплатную утилиту. Сжимаем до 83x47 пикселей.

 

После сжатия открываем ui_iconstotal.dds и вставляем в пустое поле ваше изображение. Наводим курсор на верхний левый пиксель нашего изображения и смотрим координаты внизу (иллюстрация)

 

Затем, заходим в файл news_manager.script и ищем массив tips_icons, добавляем в конец запись в формате имя_иконки {x-координата, y-координата}. Пример.

 

Готово! Теперь при отправке сообщения можно указать свою иконку! Пример (sender - имя иконки, например "barman").

 

 

  • Нравится 1

А где зима?

img.php?nick=Balavnik&sert=2&text=t6

Ссылка на комментарий

@Painter Тут можно посмотреть где прописаны партиклы. Можно заменить партиклы на подходящие. То что объекты разрывает в аномалях добавляет некой живности миру ИМХО.

  • Нравится 1
Ссылка на комментарий

Существует ли урок по редактированию gamemtl.xr, с целью добавления дополнительных звуков шагов ГГ?  Или у кого-то уже есть правленный?

 

Я слышал для работы нужен gamemtl_xr_editor.

Ссылка на комментарий
1 час назад, Фокусник сказал:

Существует ли урок по редактированию gamemtl.xr

Может тебе это нужно?

1 - https://www.amk-team.ru/forum/topic/11124-gamemtlxr-shadersxr-lanimsxr-i-format-ppe/

2- https://xray-engine.org/index.php?title=gamemtl.xr_compiler/decompiler_(gamemtl.xr_cdc)

 

 

 

Изменено пользователем shahvkit
  • Спасибо 2
  • Нравится 1
Ссылка на комментарий
Скрытый текст

bind_stalker.script  (в нём две правки, чтобы поставить рюкзак на землю, но поднять не сможем)

1.
----------------------------------------------------------------------------------------------------------------------
function actor_binder:take_item_from_box(box, item)

перематываем в конец функции, и перед последним end вставляем код

end
-->>Treasure rucksack 1/2
    if self.rr_id~=nil then
        -- пытаемся получить объект по id
        local se_obj=alife():object(self.rr_id)
        -- проверяем, что объекта нет
        if se_obj==nil or se_obj:section_name()~="inv_ruck" then
            local ruck=alife():create("active_ruck", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id())
            level.map_add_object_spot_ser(ruck.id, "red_location", "%c[255,238,155,23]Моя нычка для хабара")
            news_manager.send_tip(db.actor, "Тайник заложен.", nil, nil, 5000)
        end
        -- сбросим переменную
        self.rr_id=nil
    end
    --<<
end
----------------------------------------------------------------------------------------------------------------------

2.

function actor_binder:on_item_drop(obj)

перематываем в конец функции, и перед последним end вставляем код

end
        -->>Treasure rucksack 2/2
    if obj:section()=="inv_ruck" then
        -- запомним id объекта
        self.rr_id=obj:id()
    end
    --<<
end
----------------------------------------------------------------------------------------------------------------------

3.

treasure_manager.script  (делаем правку, чтобы поднять рюкзак с земли к себе в инвентарь)


function take_item_from_box(box, box_story_id, item)
    if box:is_inv_box_empty() == true then
        treasure_empty(box, box_story_id)
    end
        if box:section() == "active_ruck" and box:is_inv_box_empty() then
        level.start_stop_menu(level.main_input_receiver(), true)    
        alife():release(alife():object(box:id()), true) 
        alife():create("inv_ruck", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())
        end
end
----------------------------------------------------------------------------------------------------------------------

4.

configs/misc/devices  (дописываем в самом конце файла строки)

[inv_ruck]:identity_immunities
GroupControlSection = spawn_group
discovery_dependency =
$spawn    = "food and drugs\antirad"
$prefetch   = 32
class   = II_ANTIR
cform           = skeleton
visual          = dynamics\devices\dev_rukzak\dev_rukzak.ogf
description  = enc_tre_ruck

inv_weight   = 1
inv_name   = tre_ruck
inv_name_short  = tre_ruck_s

inv_grid_width  = 2
inv_grid_height  = 2
inv_grid_x   = 20
inv_grid_y   =7
cost    =     800

;eatable item
eat_health = 0
eat_satiety = 0
eat_power = 0
eat_radiation = 0
eat_alcohol = 0
wounds_heal_perc = 0
eat_portions_num = 1

;food item
animation_slot  = 4

;hud item
hud = wpn_vodka_hud

[active_ruck]:inventory_box
visual          = dynamics\devices\dev_rukzak\dev_rukzak.ogf
custom_data = scripts\treasure_inventory_box.ltx
radius = 1
----------------------------------------------------------------------------------------------------------------------

5. 

configs/misc/trade_generic (дописываем в файле строки, содержащие в разделе предметы код  inv_ruck )

inv_ruck

----------------------------------------------------------------------------------------------------------------------
6.
configs/misc/trade 

прописываем любому торговцу  inv_ruck  (рюкзак в продажу)
----------------------------------------------------------------------------------------------------------------------

7.

configs/localization  (добавляем строки, чтобы стало так)

[string_table]
language        = rus
font_prefix     = ;_west ;_cent

;список xml файлов, содержащих таблицы символов
files = tre_ruck
----------------------------------------------------------------------------------------------------------------------

8.

configs/text/rus/tre_ruck    (в новом созданном файле tre_ruck  прописываем строки)

<?xml version="1.0" encoding="windows-1251" ?>
<string_table>
    <string id="tre_ruck">
        <text>Пустой рюкзак</text>
    </string>
    <string id="tre_ruck_s">
        <text>Пустой рюкзак</text>
    </string>
    <string id="enc_tre_ruck">
        <text>Походный рюкзак из прорезиненной камуфляжной ткани, не промокает и слабозаметен, поэтому идеально подходит для закладки своего тайника в каком-нибудь укромном месте.</text>
    </string>    
</string_table>

----------------------------------------------------------------------------------------------------------------------
9.

textures/ui/ui_icon_equipment   прописываем иконку, снимаем координаты для файла devices

----------------------------------------------------------------------------------------------------------------------

Добавляем иконку в инвентарь, тут размер inv_grid_width  = 2, inv_grid_height  = 2, inv_grid_x   = 20, inv_grid_y   =7, чтобы много места не занимал в инвентаре

 

image.png

 

Всё.

 

Скрытый текст

1.
gamedata/configs/gameplay/info_portions

 

<?xml version='1.0' encoding="windows-1251"?>

<game_information_portions>               ; ЭТА СТРОКА ЕСТЬ СВЕРХУ  :)))) 

<!-- ATM Sleeping Bag start -->                                                                         ; ЭТО ДОБАВИТЬ :))))  

   <info_portion id="has_sleeping_bag"></info_portion>                                           ; ЭТО ДОБАВИТЬ :))))  

<!-- ATM Sleeping Bag end -->                                                                          ; ЭТО ДОБАВИТЬ :))))  

  <info_portion id="global_dialogs">           ; ЭТА СТРОКА ЕСТЬ СНИЗУ   :)))) 

 

2.
gamedata/configs/misc

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;    ATM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ЭТО ПРОПИСАТЬ СВЕРХУ ЕДЫ  :))))  
[sleepingbag]:identity_immunities
GroupControlSection    = spawn_group
discovery_dependency =
$spawn             = "food and drugs\sleepingbag"
$prefetch         = 32
class            = II_ANTIR
cform           = skeleton
visual          = dynamics\devices\dev_rukzak\dev_rukzak.ogf
description        = "Спальный мешок. Полезная вещь, чтобы переночевать в Зоне"

inv_name            = "Спальный мешок"
inv_name_short        = Спальный мешок
inv_weight            = 0.0

inv_grid_width        = 2
inv_grid_height        = 2
inv_grid_x            = 20   ; цифры пишим свои, после добавления иконки в файл gamedata/textures/ui/ui_icon_equipment
inv_grid_y            = 12   ; цифры пишим свои, после добавления иконки в файл gamedata/textures/ui/ui_icon_equipment
cost                = 800

; eatable item
eat_health = 0
eat_satiety = 0
eat_power = 0
eat_radiation = 0
wounds_heal_perc = 0
eat_portions_num = 1

; food item
animation_slot        = 4

;hud item
hud = wpn_vodka_hud

quest_item    = true  ; если true - нельзя выложить, всегда в инвентаре, если false - можно выложить в любой ящик, можно потерять!

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;    FOOD
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

3.
gamedata/configs/ui/ui_movies

 

</intro_game>              ; ЭТА СТРОКА ЕСТЬ СВЕРХУ  :)))) 


<!-- ATM Sleeping Bag start -->           ; ЭТО ДОБАВИТЬ :))))   

<atmdream>
    <play_each_item>1</play_each_item>
    <global_wnd x="0" y="0" width="1024" height="768">
        <auto_static x="0" y="0" width="1024" height="768" stretch="1">
            <window_name>back</window_name>
            <texture>intro\intro_back</texture>
        </auto_static>
    </global_wnd>
    
    <item type="video">
        <sound>characters_voice\human_02\csky\states\sleep\sleep_4.ogg</sound>
        <pause_state>off</pause_state>
        <can_be_stopped>off</can_be_stopped>
        <function_on_stop>atmsleep.sleep_stop</function_on_stop>
        <video_wnd x="0" y="0" width="1024" height="768" stretch="1">
            <texture x="0" y="1" width="1024" height="768">intro\intro_back</texture>
        </video_wnd>
    </item>
</atmdream>

<!-- ATM Sleeping Bag end -->


  <x18_dream>             ; ЭТА СТРОКА ЕСТЬ СНИЗУ   :)))) 

 

4.
gamedata/configs/ui/ui_sleep   

ui_sleep — ЭТОТ ФАЙЛ НУЖНО СОЗДАТЬ САМОМУ, БЕРЁМ ЛЮБОЙ ФАЙЛ ИЗ ПАПКИ И СТИРАЕМ ЕГО СОДЕРЖИМОЕ ПОЛНОСТЬЮ, ПОСЛЕ ЭТОГО В ЧИСТЫЙ ФАЙЛ ВСТАВЛЯЕМ СТРОКИ НИЖЕ :)))

 

<w>
    <background x="0" y="0" width="380" height="160">
        <texture x="0" y="0" width="377" height="154">ui\atmsleep</texture>
    </background>
    
    <button_sleep x="78" y="101" width="116" height="30">
          <texture x="21" y="212" width="116" height="43">ui\atmsleep</texture>
          <text font="graffiti19">Sleep</text>
          <text_color>
              <e r="227" g="199" b="178"/> <t r="180" g="153" b="155"/> <d r="106" g="95" b="91"/> <h r="0" g="0" b="0"/>
          </text_color>
    </button_sleep>
    
    <button_quit x="206" y="101" width="116" height="30">
          <texture x="21" y="212" width="116" height="43">ui\atmsleep</texture>
          <text font="graffiti19">Cancel</text>
          <text_color>
              <e r="227" g="199" b="178"/> <t r="180" g="153" b="155"/> <d r="106" g="95" b="91"/> <h r="0" g="0" b="0"/>
          </text_color>
    </button_quit>
    
    <button_left x="157" y="58" width="40" height="25">
          <texture x="20" y="163" width="40" height="25">ui\atmsleep</texture>
    </button_left>
    
    <button_right x="305" y="58" width="40" height="25">
          <texture x="61" y="163" width="40" height="25">ui\atmsleep</texture>
    </button_right>
        
    <safetybar x="158" y="42" width="186" height="9">
        <texture x="21" y="265" width="186" height="9">ui\atmsleep</texture>
    </safetybar>
    
    <fearbar x="158" y="42" width="186" height="9">
        <texture x="21" y="195" width="186" height="9">ui\atmsleep</texture>
    </fearbar>
    
    <display x="200" y="59" width="102" height="23">
        <texture x="23" y="285" width="102" height="23">ui\atmsleep</texture>
        <texture>ui_button_main02</texture>
          <text font="graffiti19">1h</text>
          <text_color>
              <e r="227" g="199" b="178"/> <t r="180" g="153" b="155"/> <d r="106" g="95" b="91"/> <h r="0" g="0" b="0"/>
          </text_color>
    </display>

    <text1 x="158" y="42" width="186" height="9">
        <texture x="21" y="195" width="186" height="9">ui\atmsleep</texture>
    </text1>    
</w>

 

5.

gamedata/scripts/atmmain

atmmain — ЭТОТ ФАЙЛ НУЖНО СОЗДАТЬ САМОМУ, БЕРЁМ ЛЮБОЙ ФАЙЛ ИЗ ПАПКИ И СТИРАЕМ ЕГО СОДЕРЖИМОЕ ПОЛНОСТЬЮ, ПОСЛЕ ЭТОГО В ЧИСТЫЙ ФАЙЛ ВСТАВЛЯЕМ СТРОКИ НИЖЕ :)))

-----------------------------------------------------

local ui_sleep_init = false;
local sleepingbag_id = nil;

----------------------------------------------------------------------------------
-- Func: Print in log file.
----------------------------------------------------------------------------------
function prnt(msg)
end

----------------------------------------------------------------------------------
-- Func: Callback on the load game.
----------------------------------------------------------------------------------
function on_game_load()
--    atmanoms.dynanoms():level_spawn();
--    atmmonster.sim_monsters():level_spawn();
--    atmdebug.fill_backpack();    
--    atmdebug.get_level_graphs()
end

----------------------------------------------------------------------------------
-- Func: Callback on the game end.
----------------------------------------------------------------------------------
function on_actor_destroy()
end

----------------------------------------------------------------------------------
-- Func: Callback on the take of item.
----------------------------------------------------------------------------------
function on_item_take(obj)
end

----------------------------------------------------------------------------------
-- Func: Callback on the loss of item.
----------------------------------------------------------------------------------
function on_item_drop(obj)
    if obj:section() == "sleepingbag" then
        sleepingbag_id = obj:id();
        ui_sleep_init = true;        
    end
--    atmdebug.abundance(obj);    
end

----------------------------------------------------------------------------------
-- Func: Update of actor.
----------------------------------------------------------------------------------
function update()
    atmsleep.update()
    if ui_sleep_init then
        if sleepingbag_id and alife():object(sleepingbag_id)==nil then
            ui_sleep_init = false;
            sleepingbag_id = nil;
            local act = db.actor;
            alife():create("sleepingbag", act:position(), act:level_vertex_id(), act:game_vertex_id(), act:id());
            level.start_stop_menu(atmsleep.UISleep(), true);
        else
            ui_sleep_init = false;
            sleepingbag_id = nil;
        end
    end
--    atmdebug.show_debuginfo();
end

----------------------------------------------------------------------------------
-- Func: Save a value in a storage.
----------------------------------------------------------------------------------
function save_val(varname, val)
    xr_logic.pstor_store(db.actor, varname, val);
end

----------------------------------------------------------------------------------
-- Func: Load a value from a storage.
----------------------------------------------------------------------------------
function load_val(varname, defval)
    xr_logic.pstor_retrieve(db.actor, varname, defval);
end


6.

gamedata/scripts/atmpackages

atmpackages — ЭТОТ ФАЙЛ НУЖНО СОЗДАТЬ САМОМУ, БЕРЁМ ЛЮБОЙ ФАЙЛ ИЗ ПАПКИ И СТИРАЕМ ЕГО СОДЕРЖИМОЕ ПОЛНОСТЬЮ, ПОСЛЕ ЭТОГО В ЧИСТЫЙ ФАЙЛ ВСТАВЛЯЕМ СТРОКИ НИЖЕ :)))

----------------------------------------------------

local packet = net_packet();

-- net package reader for "se_zone_anom"
function get_zone_anom(sobj)
    packet:w_begin(0);
    packet:r_seek(2);
    sobj:STATE_Write(packet);
    local tbl={}    
    read_anomalous_zone(tbl, packet);
    tbl.last_spawn_time_present = packet:r_u8();
    return tbl;
end

-- net package writer for "se_zone_anom"
function set_zone_anom(tbl,sobj)
    packet:w_begin(0);
    packet:r_seek(2);
    write_anomalous_zone(tbl,packet);
    packet:w_u8(tbl.last_spawn_time_present);
    local size = packet:w_tell();
    sobj:STATE_Read(packet,size);
end

-- net package reader for "cse_alife_torrid_zone"
function get_torrid_zone(sobj)
    packet:w_begin(0);
    packet:r_seek(2);
    sobj:STATE_Write(packet);
    local tbl={}    
    read_custom_zone(tbl, packet);
    read_motion(tbl, packet);
    return tbl;
end

-- net package writer for "cse_alife_torrid_zone"
function set_torrid_zone(tbl,sobj)
    packet:w_begin(0);
    packet:r_seek(2);
    write_custom_zone(tbl, packet);
    write_motion(tbl, packet);
    local size = packet:w_tell();
    sobj:STATE_Read(packet,size);
end


--read_motion
function read_motion(tbl, packet)
    tbl.motion_name = packet:r_stringZ();
    return tbl;
end

--write_motion
function write_motion(tbl, packet)
    packet:w_stringZ(tbl.motion_name);
end

--read_anomalous_zone
function read_anomalous_zone(tbl, packet)
    read_custom_zone(tbl, packet);
    tbl.offline_interactive_radius = packet:r_float();
    tbl.artefact_spawn_count = packet:r_u16();
    tbl.artefact_position_offset = packet:r_s32();
    return tbl;
end

--write_anomalous_zone
function write_anomalous_zone(tbl, packet)
    write_custom_zone(tbl, packet);
    packet:w_float(tbl.offline_interactive_radius);
    packet:w_u16(tbl.artefact_spawn_count);
    packet:w_s32(tbl.artefact_position_offset);
end

--read_custom_zone
function read_custom_zone(tbl, packet)
    read_space_restrictor(tbl, packet);
    tbl.max_power = packet:r_float();
    tbl.owner_id = packet:r_s32();
    tbl.enabled_time = packet:r_s32();
    tbl.disabled_time = packet:r_s32();
    tbl.start_time_shift = packet:r_s32();    
    return tbl;    
end

--write_custom_zone
function write_custom_zone(tbl, packet)
    write_space_restrictor(tbl, packet);
    packet:w_float(tbl.max_power);
    packet:w_s32(tbl.owner_id);
    packet:w_s32(tbl.enabled_time);
    packet:w_s32(tbl.disabled_time);
    packet:w_s32(tbl.start_time_shift);        
end

--read_space_restrictor
function read_space_restrictor(tbl, packet)
    read_object(tbl,packet);
    read_shape(tbl,packet);
    tbl.restrictor_type    = packet:r_u8();
    return tbl;
end

--write_space_restrictor
function write_space_restrictor(tbl, packet)
    write_object(tbl,packet);
    write_shape(tbl,packet);
    packet:w_u8(tbl.restrictor_type);
end

--read_object
function read_object(tbl,packet)
    tbl.gvid = packet:r_u16();
    tbl.dist = packet:r_float();
    tbl.dir_control = packet:r_s32();
    tbl.lvid = packet:r_s32();
    tbl.obj_flags = packet:r_s32();
    tbl.custom_data = packet:r_stringZ();
    tbl.sid = packet:r_s32();
    tbl.spawn_sid = packet:r_s32();    
    return tbl
end

--write_object
function write_object(tbl,packet)
    packet:w_u16(tbl.gvid);
    packet:w_float(tbl.dist);
    packet:w_s32(tbl.dir_control);
    packet:w_s32(tbl.lvid);
    packet:w_s32(tbl.obj_flags);
    packet:w_stringZ(tbl.custom_data);
    packet:w_s32(tbl.sid);
    packet:w_s32(tbl.spawn_sid);
end

--read_shape
function read_shape(tbl,packet)
    local count = packet:r_u8();
    tbl.shape = {}
    for i = 1, count do
        local stype = packet:r_u8();
        tbl.shape = {}
        tbl.shape.stype = stype;
        if stype == 0 then
            tbl.shape.center = packet:r_vec3();
            tbl.shape.radius = packet:r_float();
        else
            tbl.shape.box = packet:r_matrix();
        end
    end 
    return tbl;
end

--write_shape
function write_shape(tbl,packet)
    packet:w_u8(#tbl.shape);
    for i = 1, #tbl.shape do
        packet:w_u8(tbl.shape.stype);
        if tbl.shape.stype == 0 then
            packet:w_vec3(tbl.shape.center);
            packet:w_float(tbl.shape.radius);
        else
            packet:w_matrix(tbl.shape.box);
        end
    end
end


7.

gamedata/scripts/atmsleep

atmsleep — ЭТОТ ФАЙЛ НУЖНО СОЗДАТЬ САМОМУ, БЕРЁМ ЛЮБОЙ ФАЙЛ ИЗ ПАПКИ И СТИРАЕМ ЕГО СОДЕРЖИМОЕ ПОЛНОСТЬЮ, ПОСЛЕ ЭТОГО В ЧИСТЫЙ ФАЙЛ ВСТАВЛЯЕМ СТРОКИ НИЖЕ :)))

----------------------------------------------------

local sleep_activ    = false;
local sleep_time      = 1;    --Time of sleep.
local min_sleep_time = 1;    --Min value of time.
local max_sleep_time = 12;    --Max value of time.

local best_enemy      = nil; --Best enamy.
local danger          = 0;   --Danger value.

local mutants = {
    [clsid.bloodsucker_s]     = 1,
    [clsid.boar_s]             = 2,
    [clsid.dog_s]             = 4,
    [clsid.flesh_s]         = 2,
    [clsid.pseudodog_s]     = 3,
    [clsid.burer_s]         = 1,
    [clsid.cat_s]             = 2,
    [clsid.chimera_s]         = 1,
    [clsid.fracture_s]         = 2,
    [clsid.gigant_s]         = 1,
    [clsid.zombie_s]         = 3,
    [clsid.snork_s]         = 3,
    [clsid.tushkano_s]         = 5,
    [clsid.psy_dog_s]         = 4
}

------------------------------------------------------------------------------------------------
-- Func: Creating of npc or a mutant.
------------------------------------------------------------------------------------------------
function sim_create(section, position, lvid, gvid)
    local sobj = alife():create(section, position, lvid, gvid);
    alife():set_switch_online(sobj.id, true);
    alife():set_switch_offline(sobj.id, false);
    return sobj;
end

------------------------------------------------------------------------------------------------
-- Func: Actor update.
------------------------------------------------------------------------------------------------
function update()
    if sleep_activ == true then
        if db.actor.health < 0.1 then
            sleep_stop();            
        end
    end
end

------------------------------------------------------------------------------------------------
-- Func: Maintenance of health.
------------------------------------------------------------------------------------------------
function health_cr(slptime)
    local koef = slptime / 6;
    if db.actor.health < 1 then
        local health = db.actor.health + koef;
        if health >= 1 then
            db.actor.health = 1;
        else
            db.actor.health = health;
        end
    end
end

------------------------------------------------------------------------------------------------
-- Func: Activation of sleep.
------------------------------------------------------------------------------------------------
function sleep_stop()
    sleep_activ = false;
    surprise();
    level.set_time_factor(system_ini():r_float("alife","time_factor"));
    local weather_manager = level_weathers.get_weather_manager();
    weather_manager:reset(); --reset weather
    level.add_cam_effector("camera_effects\\prison_1.anm", 25, false, "")
    level.add_cam_effector("camera_effects\\hit_back_left.anm", 26, false, "")
end

------------------------------------------------------------------------------------------------
-- Func: Deactivation of sleep.
------------------------------------------------------------------------------------------------
function sleep_start(slptime)
    game.start_tutorial("atmdream");
    db.actor:stop_talk()
    level.set_time_factor(slptime * 480);
    health_cr(slptime);
    sleep_activ = true;
end

------------------------------------------------------------------------------------------------
-- Func: Surprise.
------------------------------------------------------------------------------------------------
function surprise()
    local dirs = {
        vector():set(1,  0,  0),
        vector():set(1,  0,  1),
        vector():set(0,  0,  1),
        vector():set(-1, 0,  1),
        vector():set(-1, 0,  0),
        vector():set(-1, 0, -1),
        vector():set(0,  0, -1),
        vector():set(1,  0, -1)
    }
    local lvid = db.actor:level_vertex_id();
    local gvid = db.actor:game_vertex_id();    
    level.add_pp_effector("teleport.ppe", 2006, false);
    if danger > 100 then --actor death 
        if best_enemy == nil then sim_create("bloodsucker_redhunter", db.actor:position(), lvid, gvid); --spawn default mutant
        else sim_create(best_enemy:section(), db.actor:position(), lvid, gvid);    end --spawn the nearest enemy
        db.actor:kill(db.actor);
        return;
    end
    if danger * 10 >= math.random(1, 1000) then    --mutants spawn
        if best_enemy == nil then --mutants not near actor
            for i = 1, 2 do
                local dir = dirs[math.random(1, #dirs)];
                local start_point_id = level.vertex_in_direction(lvid, dir, math.random(15,20));                
                local sobj = sim_create("bloodsucker_redhunter", level.vertex_position(start_point_id), start_point_id, gvid); --spawn     
            end
        elseif best_enemy:alive() then --nearby to actor
            local amount = math.random(1,2);
            if mutants[get_clsid(best_enemy)] then
                amount = mutants[get_clsid(best_enemy)];
            end        
            for i = 1, amount do
                local dir = dirs[math.random(1, #dirs)];
                local start_point_id = level.vertex_in_direction(lvid, dir, math.random(15,20));        
                local sobj = sim_create(best_enemy:section(), level.vertex_position(start_point_id), start_point_id, gvid); --spawn
--                atmdebug.logf("surprise => "..best_enemy:section().." : "..sobj:section_name());
            end
        else --corpse
            local amount = 2;
            local mutant = "bloodsucker_redhunter"; --default mutant
            if mutants[get_clsid(best_enemy)] then
                mutant = best_enemy:section(); --the nearest enemy
                amount = mutants[get_clsid(best_enemy)];
            end
            for i = 1, amount do
                local dir = dirs[math.random(1, #dirs)];
                local start_point_id = level.vertex_in_direction(lvid, dir, math.random(15,20));
                local sobj = sim_create(mutant, level.vertex_position(start_point_id), start_point_id, gvid); --spawn
--                atmdebug.logf("surprise => "..mutant.." : "..sobj:section_name());
            end
        end
    end
end

------------------------------------------------------------------------------------------------
-- Class: UI interfase for sleep.
------------------------------------------------------------------------------------------------
class "UISleep" (CUIScriptWnd)
function UISleep:__init() super()
    best_enemy = nil;
    danger = 0;
    self:init_interface();
    self:init_callbacks();
end

function UISleep:__finalize() 
end

------------------------------------------------------------------------------------------------
-- Func: Initialize UI interface.
------------------------------------------------------------------------------------------------
function UISleep:init_interface()
    local xml = CScriptXmlInit();
    xml:ParseFile("ui_sleep.xml");
    
    --Background.
    self.background = xml:InitStatic("background",self);
    self:SetWndPos(vector2():set(100,100));
    self:SetWndSize(vector2():set(self.background:GetWidth(),self.background:GetHeight()));
    self.background:SetWndPos(vector2():set(0,0));
    
    --Indicator.
    self.safetybar = xml:InitStatic("safetybar",self);
    self.fearbar = xml:InitStatic("fearbar",self);
    self:set_level_danger();
    
    --Display for show hours of sleeping.
    self.display = xml:InitStatic("display",self);
    self.display:SetTextX(44);
    
    --Button for activation of sleeping.
    self.button_sleep = xml:InitButton("button_sleep",self);
    self:Register(self.button_sleep, "button_sleep");
    
    --Button for quit. 
    self.button_quit = xml:InitButton("button_quit",self);
    self:Register(self.button_quit, "button_quit");
    
    --Button for add of hour.
    self.button_left = xml:InitButton("button_left",self);
    self:Register(self.button_left, "button_left");
    
    --Button for sub of hour.
    self.button_right = xml:InitButton("button_right",self);
    self:Register(self.button_right, "button_right");
end

------------------------------------------------------------------------------------------------
-- Func: Set level of danger for indicator.
------------------------------------------------------------------------------------------------
function UISleep:set_level_danger()
    danger = analyzer():evaluation();
    if danger <= 0 then
        self.fearbar:SetOriginalRect(Frect():set(0,0,0,0)); -- empty
    else
        local c = 21; --rectangle (x1, y1, x2, y2) 
        local i = 195;
        local j = 206;
        local k = 203;
        local j2 = c + (j - c) * (danger / 100);
        if j2 > j then 
            j2 = j;
        end
        self.fearbar:SetOriginalRect(Frect():set(c,i,j2,k));
    end
end

------------------------------------------------------------------------------------------------
-- Func: Set callbacks for buttons.
------------------------------------------------------------------------------------------------
function UISleep:init_callbacks()
    self:AddCallback("button_sleep",    ui_events.BUTTON_CLICKED,     self.sleep,    self)
    self:AddCallback("button_quit",        ui_events.BUTTON_CLICKED,     self.ui_quit,    self)
    self:AddCallback("button_right",    ui_events.BUTTON_CLICKED,      self.add_to_time,    self)
    self:AddCallback("button_left",        ui_events.BUTTON_CLICKED,      self.sub_to_time,    self)
end

------------------------------------------------------------------------------------------------
-- Func: Activation of sleep and exit.
------------------------------------------------------------------------------------------------
function UISleep:sleep()
    sleep_start(sleep_time);
    self:ui_quit();
end

------------------------------------------------------------------------------------------------
-- Func: Add hour to time of sleep.
------------------------------------------------------------------------------------------------
function UISleep:add_to_time()
    if sleep_time < max_sleep_time then
        sleep_time = sleep_time + 1;
        self.display:SetText(sleep_time.."h");
        self.display:SetTextX(44);
    end
end

------------------------------------------------------------------------------------------------
-- Func: Sub hour to time of sleep.
------------------------------------------------------------------------------------------------
function UISleep:sub_to_time()
    if sleep_time > min_sleep_time then
        sleep_time = sleep_time - 1;
        self.display:SetText(sleep_time.."h");
        self.display:SetTextX(44);
    end
end

------------------------------------------------------------------------------------------------
-- Func: Binding for keyboard.
------------------------------------------------------------------------------------------------
function UISleep:OnKeyboard(DIK, KeyboardAction)
    CUIScriptWnd.OnKeyboard(self, DIK, KeyboardAction);
    if KeyboardAction == ui_events.WINDOW_KEY_PRESSED then
        if DIK == DIK_keys.DIK_ESCAPE then
            self:ui_quit();
        end
    end
    return true;
end

------------------------------------------------------------------------------------------------
-- Func: Exit.
------------------------------------------------------------------------------------------------
function UISleep:ui_quit()
    sleep_time = 1;
    self:GetHolder():start_stop_menu(self,true);
end

------------------------------------------------------------------------------------------------
-- Class: Analyzer of danger for UI indicator.
------------------------------------------------------------------------------------------------
class "analyzer"
function analyzer:__init()
    self.danger   = 0;
    self.objects  = {};
    self.actorpos = db.actor:position();
--    atmdebug.logf("analyzer => init");
end

------------------------------------------------------------------------------------------------
-- Func: Evaluate danger.
------------------------------------------------------------------------------------------------
function analyzer:evaluation()    
    local min_dist = 300;
    for key, val in pairs(db.storage) do --searcher of enemies
        local obj = level.object_by_id(key);
        if obj and (IsStalker(obj) or IsMonster(obj)) then            
            if obj:position():distance_to(self.actorpos) <= 150 then 
                local distance = obj:position():distance_to(self.actorpos);
                if distance < min_dist and IsMonster(obj) then
                    min_dist = distance;
                    best_enemy = obj;
                end
--                atmdebug.logf("evaluation => section: "..obj:section().."  dist: "..distance);
                table.insert(self.objects, obj);
            end
        end    
    end
    if #self.objects < 1 then 
--        atmdebug.logf("evaluation => self.objects empty");
        return 0 
    end
    for key, obj in pairs(self.objects) do --evaluate danger
        local dist = obj:position():distance_to(self.actorpos);        
        if IsStalker(obj) then
            if obj:alive() and obj:relation(db.actor) == game_object.enemy then
                self.danger = self.danger + (70 / (dist / 10)); --human
            elseif obj:alive() == false then
                self.danger = self.danger + (30 / (dist / 10)); --human corpse
            elseif obj:position():distance_to(self.actorpos) <= 30 then
                self.danger = self.danger - 12; --human friend
            end
        elseif IsMonster(obj) then
            if obj:alive() then
                self.danger = self.danger + (70 / (dist / 10)); --mutant
            else
                self.danger = self.danger + (30 / (dist / 10)); --mutant corpse
            end
        end
    end
--    atmdebug.logf("evaluation => danger: "..self.danger);
    if self.danger < 0 then 
        return 0;
    end
    return self.danger;
end

 

8.

gamedata/scripts/bind_stalker

8.1.
function actor_binder:net_spawn(data)
                printf("actor net spawn")

                level.show_indicators()

                self.bCheckStart = true
                self.weapon_hide = false -- спрятано или нет оружие при разговоре.
        self.weapon_hide_in_dialog = false
                weapon_hide = {} -- устанавливаем глобальный дефолтовый флаг.

                if object_binder.net_spawn(self,data) == false then
                                return false
                end

                db.add_actor(self.object)

                if self.st.disable_input_time == nil then
                                level.enable_input()
                end
                xr_s.on_game_load()                                    --' Distemper 03.2008 --
                atmmain.on_game_load()                                                                      ; ЭТУ СТРОЧКУ ДОБАВИТЬ :))))
                self.weather_manager:reset()
--        game_stats.initialize ()

--        if(actor_stats.add_to_ranking~=nil)then
--                actor_stats.add_to_ranking(self.object:id())
--        end

8.2.
function actor_binder:net_destroy()
        xr_sound.stop_sounds_by_id(self.object:id())
        local board_factions = sim_board.get_sim_board().players
        for k,v in pairs (board_factions) do
            xr_sound.stop_sounds_by_id(v.id)
        end
        if(actor_stats.remove_from_ranking~=nil)then
            actor_stats.remove_from_ranking(self.object:id())
        end
        xr_effects.stc_stop_particle_sounds()
        level.show_indicators()
        level.show_weapon(true)
--        get_console():execute("hud_crosshair 1")
--        get_console():execute("hud_weapon 1")
--    get_console():execute("r2_dof -0.250000,1.400000,200.000000")
--     game_stats.shutdown ()
                db.del_actor(self.object)

                self.object:set_callback(callback.inventory_info, nil)
                self.object:set_callback(callback.article_info, nil)
                self.object:set_callback(callback.on_item_take, nil)
                self.object:set_callback(callback.on_item_drop, nil)
                --self.object:set_callback(callback.actor_sleep, nil)
                self.object:set_callback(callback.task_state, nil)
                self.object:set_callback(callback.level_border_enter, nil)
                self.object:set_callback(callback.level_border_exit, nil)
                self.object:set_callback(callback.take_item_from_box, nil)

                if sr_psy_antenna.psy_antenna then
                                sr_psy_antenna.psy_antenna:destroy()
                                sr_psy_antenna.psy_antenna = false
                end
        xrs_dyn_music.stop_sound()
                object_binder.net_destroy(self)
--        xr_sound.stop_all_sounds()
                xr_s.on_actor_destroy()                                       --' Distemper 03.2008 --
                atmmain.on_actor_destroy()                                                                      ; ЭТУ СТРОЧКУ ДОБАВИТЬ :))))
end

8.3.
function actor_binder:on_item_take (obj)
        level_tasks.proceed(self.object)
        printf("on_item_take [%s]", obj:name())
        if isArtefact(obj) then
            bind_anomaly_zone.artefact_ways_by_id[obj:id()] = nil
            local artefact =  obj:get_artefact()
            artefact:FollowByPath("NULL",0,vector():set(500,500,500))
            if bind_anomaly_zone.parent_zones_by_artefact_id[obj:id()] ~= nil then
                            bind_anomaly_zone.parent_zones_by_artefact_id[obj:id()]:on_artefact_take()
            end
        end
        for k,v in pairs(task_manager:get_task_manager().task_info) do
            if(v.type=="bring_item" and v.state~="finished") then
                            v:on_item_take(obj)
            end
        end
        atmmain.on_item_take(obj)                                                                                          ; ЭТУ СТРОЧКУ ДОБАВИТЬ :))))
        --game_stats.update_take_item (obj, self.object)
end

8.4.
function actor_binder:on_item_drop (obj)
        level_tasks.proceed(self.object)
        for k,v in pairs(task_manager:get_task_manager().task_info) do
            if(v.type=="bring_item" and v.state~="finished") then
                            v:on_item_drop(obj)
            end
        end
        --game_stats.update_drop_item (obj, self.object)
        atmmain.on_item_drop(obj)                                                                                        ; ЭТУ СТРОЧКУ ДОБАВИТЬ :))))    
end

8.5.  Вписать в эту функцию оргинала строки ниже, заменить оригинальные, сами посмотрите и разберётесь :))))    
function actor_binder:update(delta)
                object_binder.update(self, delta)

-- ATM Sleeping Bag start

    local act = db.actor
    if not has_alife_info("has_sleeping_bag") then
       db.actor:give_info_portion("has_sleeping_bag")
       alife():create("sleepingbag", act:position(), act:level_vertex_id(), act:game_vertex_id(), act:id())
    end

-- ATM Sleeping Bag start

                if self.already_jumped==false and jump_level.need_jump==true and (device().frame > self.spawn_frame+2000) then
            jump_level.try_to_jump()
            self.already_jumped = true
        return
    end

    atmmain.update()
    
                -- DEBUG slowdown
--        slowdown.update()

 

9.

gamedata/scripts/dialogs_marsh

-- dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "sleepingbag", 1) 
; ЭТО ДОБАВИТЬ В ФУНКЦИЮ, СПАЛЬНЫЙ МЕШОК ПОЯВИТСЯ В ИНВЕНТАРЕ В НАЧАЛЕ ИГРЫ  :)))


function tutorial_give_equipment(first_speaker, second_speaker)
    dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "ammo_12x70_buck", 5)
    dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "ammo_9x18_fmj", 2)
    dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "wpn_bm16")
    dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "wpn_pm")
    dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "wpn_knife")
    dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "detector_simple")
    dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "bandage", 5)
    dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "medkit", 2)
    dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "antirad", 1)
    -- dialogs.relocate_item_section_to_actor(first_speaker, second_speaker, "sleepingbag", 1) 
end
 

 

Изменено пользователем Челдон
Добавлено  Купер,

Перемещено.

  • Полезно 1
Ссылка на комментарий
Скрытый текст

 

1.
gamedata/configs/scripts/escape/esc_mil_minigun

fire_range = 100 поменять на fire_range = 70, можно пройти близко вдоль забора из колючей проволоки, если отойти от забора и приблизиться к поваленному дереву пулемёт обнаруживает и убьёт.

 

2.
gamedata/configs/scripts/escape/esc_novice_stalker

СТРОЧКА-БАГ ПРИВОДЯЩАЯ К СМЕРТИ СТАЛКЕРА-НОВИЧКА ПО КЛИЧКЕ "БРОДЯГА", КОТОРОГО СПАСАЕМ ОТ СОБАК ПО ПРОСЬБЕ ВОЛКА, ПОСЛЕ ТОГО, КАК ШРАМ УХОДИТ ИЗ ДЕРЕВНИ НОВИЧКОВ, И ПРИ ЕЁ НОВОМ ПОСЕЩЕНИИ НАХОДИТ ТРУП СТАЛКЕРА У КОСТРА

ВОТ ОНА ; on_actor_dist_ge_nvis = 100 | walker@death %+esc_stalker_novice_fail =kill_npc%  

[walker@run]
wounded = wounded
path_walk = esc_novice_stalker_walk_2
path_look = esc_novice_stalker_look_2
def_state_moving = run
meet = no_meet
on_info = {-esc_novice_info_enemy_dogs =squad_exist(esc_dogs_lair_guard_5_12)} %=set_squad_goodwill_to_npc(esc_dogs_lair_guard_5_12:enemy) +esc_novice_info_enemy_dogs%
on_npc_in_zone = 433 | esc_space_restrictors_2_12_sr_defense | walker@walk
on_actor_dist_ge_nvis = 100 | walker@death %+esc_stalker_novice_fail =kill_npc%    ; ВОТ ОНА В СТРУКТУРЕ, СТЕРЕТЬ :)))

 

3.
gamedata/configs/scripts/escape/esc_wolf

[logic@wolf]
active            = walker@no_meet
suitable            = {=check_npc_name(esc_wolf)} true
on_death            = death
level_spot            = quest_npc

[walker@no_meet]
invulnerable            = true                                                               ; ЭТУ СТРОЧКУ ДОБАВИТЬ  :)))
path_walk            = esc_wolf_way
path_look            = esc_wolf_look
on_info            = {+mar_story_go_to_escape_done} walker@wait
meet                = no_meet

[walker@wait]
invulnerable            = true                                                                ; ЭТУ СТРОЧКУ ДОБАВИТЬ  :)))
path_walk            = esc_wolf_way
path_look            = esc_wolf_look
on_actor_dist_le_nvis    = 8 | {-esc_wolf_call_sound} remark@hello %=play_sound(esc_wolf_call) +esc_wolf_call_sound%
meet                = meet

[remark@hello]
invulnerable            = true                                                                ; ЭТУ СТРОЧКУ ДОБАВИТЬ  :)))
anim                = hello_wpn
target            = actor
on_actor_dist_le        = 3 | walker@ready
on_actor_dist_ge_nvis    = 8 | walker@wait

[walker@ready]
invulnerable            = true                                                                ; ЭТУ СТРОЧКУ ДОБАВИТЬ  :)))
path_walk            = esc_wolf_way
path_look            = esc_wolf_look

[death]
on_info            = %+esc_wolf_dead%

[meet]
invulnerable            = true                                                                 ; ЭТУ СТРОЧКУ ДОБАВИТЬ  :)))
meet_state            = 15| wait@esc_wolf_call | 5| ward@nil
victim                = 15| actor
victim_wpn            = 15| actor
use                = true
use_wpn            = false
abuse                = true

 

4.
gamedata/configs/scripts/escape/esc_wolf_brother

СТРОЧКА-БАГ ПРИВОДЯЩАЯ К СМЕРТИ БРАТА ВОЛКА ПО КЛИЧКЕ "ПЁС", ПОСЛЕ ЕГО СПАСЕНИЯ ИЗ ПЛЕНА БАНДИТОВ У ПЕРЕХОДА В ТЁМНУЮ ДОЛИНУ, ПОСЛЕ ТОГО КАК ШРАМ ПРИВОДИТ ЕГО К ВОЛКУ И УХОДИТ ИЗ ДЕРЕВНИ НОВИЧКОВ, А ПРИ НОВОМ ПОСЕЩЕНИИ ДЕРЕВНИ НАХОДИТ ТРУП БРАТА У КОСТРА

ВОТ ОНА ; on_actor_dist_ge_nvis = 100 | walker@death %+esc_wolf_brother_fail =kill_npc%

[walker@run]
path_walk = esc_wolf_brother_walk_2
path_look = esc_wolf_brother_look_2
def_state_moving = run
meet = no_meet
on_npc_in_zone = 429 | esc_space_restrictors_2_12_sr_defense | walker@walk
on_actor_dist_ge_nvis = 100 | walker@death %+esc_wolf_brother_fail =kill_npc%  ; ВОТ ОНА В СТРУКТУРЕ, СТЕРЕТЬ :)))

 

5.
gamedata/configs/misc/treasure_escape

КУПИТЬ У СТАЛКЕРА-НОВИЧКА ПО КЛИЧКЕ "БРОДЯГА" ПОСЛЕ ЕГО СПАСЕНИЯ ТАЙНИК С ФЛЕШКОЙ АПГРЕЙДА flesh_up_bd_wincheaster1300, В ОРИГИНАЛЕ БЕЗ ПРАВКИ ЭТО СДЕЛАТЬ НЕЛЬЗЯ ИЗ-ЗА ОШИБКИ В ИМЕНИ, И ПОЭТОМУ ПРИМЕНЯЮТ СПАВНЕР, ЧТОБЫ ЗАСПАВНИТЬ ФЛЕШКУ СЕБЕ В ИНВЕНТАРЬ, НО ЭТОГО ДЕЛАТЬ НЕ НУЖНО. НУЖНО ИСПРАВИТЬ ИМЯ И КУПИТЬ ФЛЕШКУ В ИГРЕ, КАК ЗАДУМЫВАЛОСЬ.

esc_stalker_novice_quest  ; ОШИБКА  :(((
esc_stalker_novice           ; ЭТО ПРАВИЛЬНОЕ ИМЯ, ПИШЕМ ЕГО  :))) 

 

;Quest treasure                    ; ВНИЗУ ФАЙЛА treasure_escape СТРОКИ С ПОКУПНЫМИ ТАЙНИКАМИ

[esc_quest_treasure_9] ;Набор обычных патронов для дробовика
target = esc_q9_t_a
name = st_esc_q9_t_a
description = st_esc_q9_t_a_descr
items = flesh_up_bd_wincheaster1300, 1, ammo_12x70_buck, 20, grenade_rgd5, 1
condlist = {=actor_on_level(escape) =check_npc_name(esc_stalker_novice)} true, false    ; ИСПРАВЛЕНО, ТЕПЕРЬ ТОРГУЕТ :)))  
treasure_cost = 800
say_item_name = true

 

 

Скрытый текст

[logic]
active = sr_idle@line_0

[sr_idle@line_0]
on_info = {+agru_leader_dolg_task_complete} sr_timer %=anim_obj_down(agru_door)%

[sr_timer]
type = dec
start_value = 60000
on_value = 0 | sr_idle@line_1
on_actor_in_zone = agru_go_out_zone | %=del_cs_text() =run_postprocess(agr_u_fade) =play_sound(agru_sound_rock) =run_cam_effector(kat_heli_down) =disable_ui% sr_idle@line_2

[sr_idle@line_1]
on_info = sr_idle@line_end %=run_postprocess(agr_u_fade_water)%

[sr_idle@line_end]
on_game_timer = 32 | sr_idle@line_5 %=kill_actor%

[sr_idle@line_2]
on_game_timer = 32 | sr_idle@line_3 %=teleport_actor(agru_teleport_point_walk:agru_teleport_point_look) =run_postprocess(agr_u_fade) =run_cam_effector(kat_heli_down) +agru_stop_siren%

[sr_idle@line_3]
on_game_timer = 30 | sr_cutscene

[sr_cutscene]
point = agru_teleport_point_walk
look = agru_teleport_point_look
cam_effector = scenario_cam\agro_cam_actor
on_signal = cameff_end | sr_idle@line_4

[sr_idle@line_4]
on_game_timer = 60 | sr_idle@line_5 %=enable_ui +agru_teleport_complete =play_sound(agru_actor_stand_up)%

[sr_idle@line_5]

 

Изменено пользователем Челдон
Ссылка на комментарий

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

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...