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

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


7-icon-d6949c2e87c4f53ebe9e144c56bd549c.___31-icon-160a560baabc6dadb18a21e53978b1fd___ 50-icon-a62970b61b25e77f0b79bb2b3ffb0ab6

 



Тема не для общения.

Сообщения оставлять только с уроками в таком же формате.

Предложения и замечания пишем в личку авторов уроков.
С вопросами - в тему ковырялок: [soC], [CS], [CoP].

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

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


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

Уроки от @Zeka1996Korneev


Сложность: Легко


Файлы: Любой стандартный диалог
1. Создаём файл ваше_название_скрипта.script в папке gamedata/scripts и пишем в него:
news_manager.send_tip - это сама функция, которая отсылает сообщение.
"%c[255,255,128,128] - это цвет сообщения, идет по моему по цветам RGB.
%c[default] - это конец кода цвета сообщения, дальше текст идёт в стандартном цвете.
\n - это перенос на другую строчку.

2. В любой диалог пишем функцию:

<action>ваше_название_скрипта.ваш_текст</action>

Например в dialogs_trading.xml в диалоге doctor_dialog_start после фразы doctor_dialog_start_13, пишем:
<action>ваше_название_скрипта.ваш_текст</action>
Теперь после того как поговорите с Доктором (NLC5) на ПДА придёт сообщение с вашим текстом.

function ваш_текст(first_speaker, second_speaker)
    news_manager.send_tip(db.actor, "%c[255,255,128,128]ПРИМЕР:\n%c[default]ВАШ ТЕКСТ", nil, nil, 30000)
end


Сложность: Средне
Файлы: spawn_sections.ltx, devices.ltx, любой стандартный диалог.
Для того, чтобы замерить координаты можно воспользоваться аддончиком Position Informer. (В теме инструментарий для мододелов)
1. Создаём файл ваше_название_скрипта.script в папке gamedata/scripts и пишем в него:

function ваше_название_функции()                   --/ название функции
alife():create(section,position,levelvertex,gamevertex)   --/ вписываем свои координаты
end

2. В папке config/scripts создаём файл m_taynik.ltx и пишем в него:

[spawn] --/ Это то, что появится в тайнике
предмет
предмет
предмет
предмет
предмет


3. Открываем файл spawn_sections.ltx из папки gamedata/config/creatures и пишем:

[m_taynik]:ваш_текст
visual = equipments\item_rukzak
radius = 1
custom_data = scripts\m_taynik.ltx

4. Открываем файл devices.ltx и пишем:

[ваш_текст] --/ название секции
GroupControlSection    = spawn_group
discovery_dependency =
$spawn                 = "devices\inventory box"
class                = O_INVBOX
cform                = skeleton
visual                = physics\box\expl_dinamit.ogf
script_binding      = bind_physic_object.init

5. Пихаем в любой диалог функцию спавна:

<action>ваше_название_скрипта.ваше_название_функция</action>

Например в dialogs_trading.xml в диалоге doctor_dialog_start после фразы doctor_dialog_start_13, пишем:
<action>ваше_название_скрипта.ваше_название_функции</action>
Теперь после того как поговорите с Доктором (NLC5) по заданным координатам появится рюкзак.


Cложность: Легко
Файлы: unique_items.ltx
Создание костюма, который например является модификацией существующего.
1. Открываем файл unique_items.ltx (gamedata/config/misc) и в конец файла пишем:

[любой_текст_m1]:novice_outfit           ;Модифицированный костюм
$spawn                              = "outfit\uniq\любой_текст_m1"
inv_name                    = название в конфиге
inv_name_short                    = название в конфиге
description                    = описание в конфиге
cost                        = 3000
health_restore_speed                = 0.0004
bleeding_restore_speed                = -0.002
inv_grid_x                    = 12
inv_grid_y                    = 21

Тут прописаны отличия от самого костюма. В данном случае от novice_outfit
inv_name - название
inv_name_short - название
description - описание
cost - цена
health_restore_speed - скорость восстановления здоровья когда одет этот костюм
bleeding_restore_speed - скорость уменьшения кровотечения
inv_grid_x и inv_grid_y - иконка.
Получается, что в отличие от куртки новичка у этой куртки повышенная цена, она быстрее восстанавливает здоровье, убирает кровотечение, у куртки другое описание и название, другая иконка.


Как создать абсолютно новый костюм с уникальным визуалом.
Сложность: Тяжело
1. Открываем outfit.ltx (gamedata/config/misc)
Копируем секцию например СКАТ-10М в конец файла и редактируем:

[ваше_название_костюма]:outfit_base
GroupControlSection    = spawn_group
discovery_dependency =
$spawn             = "outfit\ваше_название_костюма"
;$prefetch         = 32
class            = E_STLK
cform           = skeleton
visual          = equipments\ваше_название_костюма
actor_visual    = actors\soldier\ваша_модель.ogf
ef_equipment_type    = 4
inv_name            = ваше_название_костюма_в_конфиге
inv_name_short        = ваше_название_костюма_в_конфиге
description            = ваше_название_костюма_описание_в_конфиге
inv_weight            = 16.0    ;Вес костюма
slot                = 6
inv_grid_width        = 2       ;Координаты иконки
inv_grid_height        = 3
inv_grid_x            = 18
inv_grid_y            = 17
full_icon_name        = npc_icon_militaryspec_outfit
cost                = 48000        ;Стоимость костюма
full_scale_icon        = 10,6    ;иконка сталкера в костюме в полный рост
immunities_sect        = ваше_название_костюма_immunities ;указывает на секцию с параметрами
; MEDIUM RESISTANCE
burn_protection                 = 0.5
strike_protection                 = 0.5
shock_protection                 = 0.5
wound_protection                = 0.5
radiation_protection             = 0.5
telepatic_protection             = 0.5
chemical_burn_protection         = 0.5
explosion_protection             = 0.5
fire_wound_protection              = 0.5
bones_koeff_protection =    armor_helmet_damage
	[ваше_название_костюма_immunities]  ;коэффициенты иммунитета самого костюма
burn_immunity                = 0.004  
strike_immunity                = 0.003
shock_immunity                = 0.003
wound_immunity                = 0.005
radiation_immunity            = 0.00
telepatic_immunity            = 0.00
chemical_burn_immunity        = 0.003
explosion_immunity            = 0.004
fire_wound_immunity            = 0.006

2. Открываем файл string_table_outfits.xml из папки (gamedata/config/text/rus) и в конец файла пишем:

<string id="ваше_название_костюма_в_конфиге">
        <text>То, что отображается в игре (название)</text>
    </string>
    <string id="ваше_название_костюма_описание_в_конфиге">
        <text>То, что отображается в игре (описание)</text>
    </string>

3. Находим в папке gamedata/meshes/actors/soldier файл stalker_military_black.ogf делаем его копию и переименовываем её как хочется, например в stalker_military_white.ogf. Открываем её блокнотом и находим это: act\act_stalker_military_1. Меняем на любой текст, но главное чтобы символов было столько же, иначе модель не будет работать. Меняем например на это: _ct_stalker_military.
 
4. Делаем тоже самое с stalker_comander_suit.ogf (gamedata/meshes/equipments) - получаем stalker_comander_suit_white.ogf
 
5. Создаём текстуру с названием _ct_stalker_military.dds (можно взять готовую из любого текстурного мода и переназвать как надо.
 
6.Прописываем в продажу торговцу и радуемся.


Сложность: Легко
Как сделать простой диалог.
1. Открываем, например файл dialogs_escape.xml (gamedata/config/gameplay) и пишем в конец:

<dialog id="test_dialog">
        <phrase_list>
            <phrase id="0">
        <text>test_dialog_0</text>
        <next>1</next>
            </phrase>
            <phrase id="1">
                <text>test_dialog_1</text>
            </phrase>
        </phrase_list>
    </dialog>

Это скелет диалога. В нём будут написаны все инфопоршни и actions.
<dialog id="test_dialog"> - это название диалога, которое нужно будет написать НПС.
<phrase id="0"> - номер фразы.
<text>test_dialog_0</text> - это текст фразы.
<next>?</next> - переход к фразе.
 
2. Теперь нужно написать тексты диалога. Заходим в файл stable_dialogs_bar.xml (gamedata/config/text/rus) и пишем в конце:

<string id="test_dialog_0">
        <text>Это тестовый диалог</text>
    </string>
    <string id="test_dialog_1">
        <text>Угу.</text>
    </string>

<string id="test_dialog_0"> - это то, на что ссылается скелет диалога.
<text>Это тестовый диалог</text> - собственно текст.
 
3. Теперь нужно прописать этот диалог НПС. Например Бармену. Открываем файл character_desc_bar.xml и находим секцию Бармена. Она идёт самой первой.
После всех <actor_dialog>???</actor_dialog>, прописываем свой:
<actor_dialog>test_dialog</actor_dialog>


Сложность: Средне
Как создать диалог посложнее.
Как создать диалог с разными вариантами ответов.
Как создать диалог который исчезнет после прочтения.
1. Открываем, например файл dialogs_escape.xml (gamedata/config/gameplay) и пишем в конец:

<dialog id="test_dialog">
        <phrase_list>
            <phrase id="0">
        <text>test_dialog_0</text>
        <next>1</next>
            </phrase>
            <phrase id="1">
                <text>test_dialog_1</text>
        <next>2</next>
        <next>3</next>
            </phrase>
            <phrase id="2">
                <text>test_dialog_2</text>
            </phrase>
            <phrase id="3">
                <text>test_dialog_3</text>
            </phrase>
        </phrase_list>
    </dialog>

<next>2</next> и <next>3</next> - это возможные ответы Меченого.
 
2. Теперь нужно написать тексты диалога. Заходим в файл stable_dialogs_bar.xml (gamedata/config/text/rus) и пишем в конце:

<string id="test_dialog_0">
        <text>Как дела?</text>
    </string>
    <string id="test_dialog_1">
        <text>Нормально, а у тебя?</text>
    </string>
    <string id="test_dialog_2">
        <text>Нормально</text>
    </string>
    <string id="test_dialog_3">
        <text>Хреново.</text>
    </string>

3. Чтобы этот диалог не появлялся, пишем инфопоршень. Например в файле info_l01escape.xml, пишем:

<info_portion id="test_pogovoril"></info_portion>

4. Дописываем инфопоршень в скелет диалога:

<dialog id="test_dialog">
<dont_has_info>test_pogovoril</dont_has_info>
        <phrase_list>
            <phrase id="0">
        <text>test_dialog_0</text>
        <next>1</next>
            </phrase>
            <phrase id="1">
                <text>test_dialog_1</text>
        <next>2</next>
        <next>3</next>
            </phrase>
            <phrase id="2">
                <text>test_dialog_2</text>
      <give_info>test_pogovoril</give_info>
            </phrase>
            <phrase id="3">
                <text>test_dialog_3</text>
      <give_info>test_pogovoril</give_info>
            </phrase>
        </phrase_list>
    </dialog>

<dont_has_info>test_pogovoril</dont_has_info> - если ГГ получил инфопоршень, диалог не показывать.
<give_info>test_pogovoril</give_info> - дать ГГ инфопоршень.
Получается, что когда ГГ скажет любую из 2 фраз, диалог больше не появится.


Сложность: Сложно
Как сделать разные action в диалогах.
 
1. Создаём обычный диалог:

<dialog id="test_dialog">
<dont_has_info>test_pogovoril</dont_has_info>
        <phrase_list>
            <phrase id="0">
        <text>test_dialog_0</text>
        <next>1</next>
            </phrase>
            <phrase id="1">
                <text>test_dialog_1</text>
        <next>2</next>
        <next>3</next>
        <next>4</next>
            </phrase>
            <phrase id="2">
                <text>test_dialog_2</text>
            </phrase>
            <phrase id="3">
                <text>test_dialog_3</text>
            </phrase>
            <phrase id="4">
                <text>test_dialog_4</text>
            </phrase>
        </phrase_list>
    </dialog>

C такими текстами:

<string id="test_dialog_0">
        <text>Я тестю функции.</text>
    </string>
    <string id="test_dialog_1">
        <text>Ок, какую?</text>
    </string>
    <string id="test_dialog_2">
        <text>Дать деньги</text>
    </string>
    <string id="test_dialog_3">
        <text>Дать ПМ</text>
    </string>
    <string id="test_dialog_4">
        <text>Заспавнить ПМ</text>
    </string>

2.Создаём свой скрипт в папке gamedata/script например test.script и пишем в него 3 функции:

function dat_dengi(first_speaker, second_speaker)
    dialogs.relocate_money(second_speaker, 3000, "in")
end

Это функция отдачи денег ГГ. На месте 3000 любое число. На месте dat_dengi любое название.

function dat_item(first_speaker, second_speaker)
    dialogs.relocate_item_section(second_speaker, "wpn_pm", "in")
end

Это функция отдачи предмета ГГ. На месте wpn_pm любой предмет. На месте dat_item любое название.

function spawn_item_or_monster_or_stalker()
alife():create("wpn_pm",vector():set(pos),lvid,gvid)
end

Это функция спавна чего либо. На месте wpn_pm любой предмет,монстр или сталкер. На месте (pos),lvid,gvid) любые координаты. На месте spawn_item_or_monster_or_stalker любое название.
Так же функция может быть одна, но с несколькими действиями. Например:

function all(first_speaker, second_speaker)
    dialogs.relocate_money(second_speaker, 3000, "in")
    dialogs.relocate_item_section(second_speaker, "wpn_pm", "in")
    alife():create("wpn_pm",vector():set(pos),lvid,gvid)
end

Значит что одновременно ГГ дадут 3000 рублей, ПМ и по заданным координатам заспавнится ПМ.

3. Впишем функции в диалог:

<dialog id="test_dialog">
        <phrase_list>
            <phrase id="0">
        <text>test_dialog_0</text>
        <next>1</next>
            </phrase>
            <phrase id="1">
                <text>test_dialog_1</text>
        <next>2</next>
        <next>3</next>
        <next>4</next>
            </phrase>
            <phrase id="2">
                <text>test_dialog_2</text>
                <action>test.dat_dengi</action>
            </phrase>
            <phrase id="3">
                <text>test_dialog_3</text>
                <action>test.dat_item</action>
            </phrase>
            <phrase id="4">
                <text>test_dialog_4</text>
                <action>test.spawn_item_or_monster_or_stalker</action>
            </phrase>
        </phrase_list>
    </dialog>

Это значит что после после фразы <text>test_dialog_2</text> ГГ дадут 3000руб. А после после фразы <text>test_dialog_3</text>, ГГ дадут ПМ. И после после фразы <text>test_dialog_3</text>, заспавнится ПМ.


Cложность: Сложно.
Как сделать разные precondition в диалогах.
 
Прекондишоны - это проверки на появление диалога
1. Создаём обычный диалог:

<dialog id="test_dialog">
        <phrase_list>
            <phrase id="0">
        <text>test_dialog_0</text>
        <next>1</next>
            </phrase>
            <phrase id="1">
                <text>test_dialog_1</text>
        <next>2</next>
        <next>3</next>
            </phrase>
            <phrase id="2">
                <text>test_dialog_2</text>
            </phrase>
            <phrase id="3">
                <text>test_dialog_3</text>
            </phrase>
        </phrase_list>
    </dialog>

C такими текстами:

<string id="test_dialog_0">
        <text>Тест прекондишонов.</text>
    </string>
    <string id="test_dialog_1">
        <text>Какой?</text>
    </string>
    <string id="test_dialog_2">
        <text>Эта фраза появляется если у ГГ есть ??? рублей.</text>
    </string>
    <string id="test_dialog_3">
        <text>Эта фраза появляется если у ГГ есть ??? предмет.</text>
    </string>

2. Создаём свой скрипт в папке gamedata/script например test.script и пишем в него 3 функции-прекондишона:

function has_money_???()
  local money = math.floor(200 *
xr_statistic_freeplay.get_freeplay_statistic():get_found_pda_discount())
  return db.actor:money()>=money
end

Это функция проверки количества денег ГГ. На месте 200 любое число.
На месте has_money_??? любое название.

function has_item(task, objective)
    if db.actor ~= nil then
        return db.actor:object("wpn_pm") ~= nil
    end
    return false
end

Это функция проверки наличия какого либо предмета у ГГ. На месте wpn_pm любой предмет. На месте has_item любое название.

3.Впишем функции в диалог:

<dialog id="test_dialog">
        <phrase_list>
            <phrase id="0">
        <text>test_dialog_0</text>
        <next>1</next>
            </phrase>
            <phrase id="1">
                <text>test_dialog_1</text>
        <next>2</next>
        <next>3</next>
            </phrase>
            <phrase id="2">
                <text>test_dialog_2</text>
        <precondition>test.has_money???</precondition>
            </phrase>
            <phrase id="3">
                <text>test_dialog_3</text>
        <precondition>test.has_item</precondition>
            </phrase>
        </phrase_list>
    </dialog>

Это значит что фраза <text>test_dialog_2</text> появится если у ГГ есть 200рублей
Это значит что фраза <text>test_dialog_3</text> появится если у ГГ есть ПМ.


Сложность: Легко
Допустим вы захотели написать много диалогов, и не хочется их писать в оригинальные файлы.
Делаем так:
1. Открываем localization.ltx и прописываем в самый конец:

ваш_файл_текстов

2. Создаём ваш_файл_текстов в папке "gamedata/config/text/rus/" и пишем в них диалоги/описания/любые тексты по аналогии с другими файлами в папке "rus"


Сложность: Средне
Все характеристики персонажей находятся в файлах "character_desc_...xml".
Откроем файл "character_desc_escape.xml" из папки gamedata/config/gameplay
Находим секцию Волка:

<!---------------------------------------esc_wolf----------------------------------------------------->
    <specific_character id="esc_wolf" team_default = "1"> - Это id персонажа: на него ссылается например "all.spawn"
        <name>esc_wolf_name</name>  - Это имя персонажа.                           
        <icon>ui_npc_u_stalker_neytral_balon_1</icon> - Это иконка персонажа
        <bio>esc_wolf_bio</bio> - Это биография персонажа(в игре не используется)
        <class>esc_wolf</class>
        <community>stalker</community> - Это группировка персонажа
<terrain_sect>stalker_terrain</terrain_sect>
        
        <rank>434</rank> - Это ранг персонажа
        <reputation>5</reputation> - Это репутация персонажа
        <money min="600" max="2000" infinitive="0"/> - Это количество денег у персонажа(минимальное и максимальное)
        
        <snd_config>characters_voice\human_01\stalker\</snd_config>  - Это звуки, которые использует персонаж
        <crouch_type>-1</crouch_type>
        <visual>actors\neytral\stalker_neytral_balon_1</visual>   - Это визуал персонажа. Какой визуал, такой и костюм
        <supplies>
            [spawn] \n - Это спавн вещей, которые появятся у персонажа
            .........\n
            .........\n
            ..........\n
            hand_radio \n
            sigaret \n
        </supplies>
        
#include "gameplay\character_criticals_4.xml"
        <start_dialog>escape_lager_volk_talk</start_dialog>   - Это диалоги персонажа
    </specific_character>

Запишем Волка в группировку "Свобода", дадим ему калашников, оденем в другой костюм, поменяем имя:

<!---------------------------------------esc_wolf----------------------------------------------------->
    <specific_character id="esc_wolf" team_default = "1">
        <name>Долботряс</name> - тут заменили имя
        <icon>ui_npc_u_stalker_neytral_nauchniy</icon>
        <bio>esc_wolf_bio</bio>
        <class>esc_wolf</class>
        <community>freedom</community> <terrain_sect>stalker_terrain</terrain_sect>
        
        <rank>434</rank>
        <reputation>5</reputation>
        <money min="600" max="2000" infinitive="0"/>
        
        <snd_config>characters_voice\human_01\stalker\</snd_config>
        <crouch_type>-1</crouch_type>
        <visual>actors\neytral\stalker_neytral_nauchniy</visual>
        <supplies>
            [spawn] \n
            ammo_9x18_fmj = 1 \n
            wpn_ak74u \n
            ammo_5.45x39_fmj = 1 \n
            device_torch \n
        </supplies>
        
#include "gameplay\character_criticals_4.xml"
        <start_dialog>escape_lager_volk_talk</start_dialog>
    </specific_character>


Cложность: Сложно
Внимание! Для работы метода необходимы функции АМК мода! -- если делать на оригинале по этой статье.
Открываем файл character_desc_....xml (в зависимости от локи)
1. И пишем:

<specific_character id="test" team_default = "1">
        <name>Тестовый</name>
        <icon>ui_npc_u_stalker_do_nauchniy</icon>
        <map_icon x="0" y="0"></map_icon>
        <bio>sim_stalker_master_bio</bio>
        <class>test</class>
        <community>stalker</community> <terrain_sect>stalker_terrain</terrain_sect>
        <money min="100000" max="110000" infinitive="1"></money>
        <rank>570</rank>
        <reputation>100</reputation>
        <visual>actors\dolg\stalker_do_nauchniy</visual>
        <snd_config>characters_voice\human_03\stalker\</snd_config>
        <crouch_type>0</crouch_type>
        <supplies>
            [spawn] \n
            wpn_groza \n
            ammo_9x39_ap \n
            ammo_9x19_fmj \n
        
#include "gameplay\character_food.xml" \n
#include "gameplay\character_drugs.xml"
        </supplies>
#include "gameplay\character_criticals_6.xml"
#include "gameplay\character_dialogs.xml"
    </specific_character>

2. Открываем amk_npc_profile.xml и пишем:

<character id="test">
<class>test</class>
</character>

3. Открываем spawn_sections.ltx и пишем:

[test]:stalker
$spawn                 = "respawn\test"
character_profile    = test
spec_rank = master
community = stalker

4. Создаём файл test_npc_logic.ltx в папке config/scripts и пишем там:

[logic]
active = camper
combat_ignore = combat_ignore
	[camper]
sniper = false
radius = 5
def_state_campering = threat_na
path_walk = mil_zomb_stalker_walk1
path_look = mil_zomb_stalker_look1

5. Создаём любой скрипт и пишем туда:

function spawn_npc_test()
local
obj=alife():create("test",vector():set(101.435539245605,-8.38547039031982,164.284591674805),3
96523,1643)
local params=amk.read_stalker_params(obj)
params.custom="[logic]\ncfg = scripts\\test_npc_logic.ltx"
amk.write_stalker_params(params,obj)
end

Прописываем функцию в любой диалог и разговариваем в игре.
В итоге наш НПС заспавнится в домике, где стоит Сумасшедший сталкер (на милитари).


Cложность: Легко
1. Прописать в логике НПС: trade = misc\trade_....ltx
2. Создать этот файл в папке config/misc и прописать там:

[trader]
buy_condition = trader_generic_buy
sell_condition = {+esc_kill_bandits_quest_done} trader_after_fabric_sell, trader_start_sell
buy_supplies = {+esc_kill_bandits_quest_done} supplies_after_fabric, supplies_start
#include "shop_???\???_buy.ltx"
#include "shop_???\???_supl.ltx"
#include "shop_???\???_trade.ltx"

3. Создать папку "shop_???" и скопировать туда файлы торговли от Сидоровича(например) переназвать файлы, изменить торговлю.


Зачем это нужно? Для квестов.
Внимание! Для работы метода необходимы функции АМК мода! -- если делать на оригинале по этой статье.
Сложность: Средне
1. Создаём свой скрипт (подробно в предыдущих уроках) и пишем в него:

function spawn_trupik_test()
    local obj=amk.spawn_item("секция НПС в файле spawn sections",vector():set(pos),game vertex,level vertex)
    if (_g.IsStalker(obj)) then
        local tbl = amk.read_stalker_params(obj)
        tbl.sid = 48802
        tbl.health = 0
        tbl.updhealth = 0
        amk.write_stalker_params(tbl, obj)                    
    end

2. Прописываем эту функцию в любой диалог (подробно в уроках выше)
На месте spawn_trupik_test ваш текст.
Замерять координаты можно утилиткой Position Informer.


Уроки от других авторов

Автор: Руся
Сложность: Сложно
Итак, по многочисленным вопросам выкладываю способ, который в общем-то очень простой, но работает. Итак, как сделать, чтобы при нажатии кнопки ТАВ в игре у вас выполнялось какое-то действие? Сразу два пояснения.
Известен способ как прибиндить кнопкам функции скрипта, но только когда открыто главное меню, или меню спальника, или любое другое скриптовое меню. В скриптовых файлах этих меню есть виртуальный колбек на отлов нажатия кнопок клавиатуры, поэтому когда открыто меню, например, спальника того же - нельзя использовать аптечку или бинт с помощью нажатия горячей кнопки [ или ]. А вот в файле скрипта на них можно прибиндить какую-то функцию, но повторюсь - это только в момент когда на экране есть скриптовое меню.
Второй способ, как сделать работу скрипта по нажатию кнопки в игре - не существует. Однако, имитацию такого способа удалось создать, но только для клавиши ТАВ.
Объяснение довольно простое - при нажатии кнопки ТАВ в игре на экран выводится текущее задание, которое отмечено в ПДА. Я подозреваю, что когда текущих заданий в ПДА не останется (например, в АМК 1.4 когда доходишь до уровня ЧАЭС 2, после разговора с О-Сознанием, пропадало последнее задание "Убить Стрелка", и не оставалось ни одного) - способ перестанет работать, но это надо проверять.
Так вот, оказывается, текущее задание выводится на главный экран игры, то есть на ХУД, не просто так, а в виде кастом статика. Этот кастом статик записан в файле gamedata\config\ui\ui_custom_msgs.xml и называется он main_task. Вот его-то и можно поймать скриптом, и соответственно, назначить на момент его ловли какое-то действие. Пример ниже.
Все мы знаем функцию апдейта из файла бинд_сталкер. Вот на неё-то и повесим колбек на специальный скрипт tabula_rasa.script, вот так:

if tabula_rasa then tabula_rasa.update(delta) end

Понятно, что вставить этот колбек надо в функцию апдейта в скрипте bind_stalker.script, а теперь займёмся самим новым скриптом. В нём будет две основных функции - самого апдейта, где будет проверяться, нет ли на главном экране кастом статика main_task, и вторая функция, где будет выполняться какое-то действие.

local timer = 0
function update(delta)
   timer = timer+delta
   if timer>1000000 then timer = 1000000 end
   local hud = get_hud()
   if hud:GetCustomStatic("main_task") and timer>1000 then
      do_something()
      timer = 0
   end
end
function do_something()
   local item = db.actor:object("antirad")
   if antirad then
      db.actor:eat(item)
   end
end

Вот такая вот функция. А теперь - что она делает? Правильно, при нажатии ТАВ происходит использование антирада, одной штуки, если он есть. Но такое использование произойдёт не чаще, чем раз в 1000 миллисекунд, для чего есть специальная проверка - в переменной timer хранится время, прощедшее с момента последнего нажатия ТАВ, при котором timer обнуляется. Время хранится в миллисекундах, поэтому 1000 равно одной секунде. Ну а строка где проверяется, не равен ли timer миллиону - это просто страховка от возможного огромного значения переменной


Сложность: Сложно
По распаковке алл.спавна с помощью acdc.
Сегодня мы разберем основу работы с ACDC. Но... Для начала небольшое отступление. Вы зададите вопрос, почему же лучше работать с ACDC нежели чем с xrSpawner? Отвечаю: xrSpawner при всех его преимуществах имеет множество более значительных минусов. Во первых, xrSpawner не определяет не game_vertex, ни level_vertex. А также он измеряет только позицию. Я думаю работающие с xrSpawner, замечали что, порой объекты которые они спаунят спаунером не всегда появляются на месте. Или вообще не появляются. Потому что повторяю xrSpawner не определяет вертексы т.е. точная позиция и распределение по АИ-сетке. Итак начнём работу! У нас есть программа ACDC, руки и мозги в голове. Кладём all.spawn в папку utils и жмём на батник "распаковка". Итак all.spawn распакован! Мы там видим файлы alife и way. В файлах alife только обьекты которые спаунятся. А в way только пути. Я думаю с алайфом всё понятно. Разберем way. Пути. Путь это и ест путь. По которому может двигаться живой объект. Сейчас мы это рассмотрим: Для начала устроим текстовый беспредел Найдём файл alife_l01_escape, а в нём

[869]
; cse_abstract properties
section_name = actor
name = level_prefix_actor_0001
s_rp = 0
position = -139.449829101563,-29.6908683776855,-351.492797851563
direction = 0,0.00895109120756388,0
s_flags = 0x29
	[dont_spawn_character_supplies]
[spawn]
wpn_binoc
novice_outfit
device_torch
END
; cse_visual properties
visual_name = actors\hero\stalker_novice
; cse_alife_creature_abstract properties
g_team = 0
g_squad = 0
g_group = 0
health = 1
dynamic_out_restrictions =
dynamic_in_restrictions =
upd:health = 1
upd:timestamp = 0x75732029
upd:creature_flags = 0x70
upd:position = -139.449829101563,-29.6908683776855,-351.492797851563
upd:o_model = 0
upd:o_torso = 0.00895109120756388,0,-0.999959945678711
upd:g_team = 0
upd:g_squad = 0
upd:g_group = 0
; cse_alife_trader_abstract properties
money = 40
trader_flags = 0
character_profile = actor
; cse_ph_skeleton properties
; cse_alife_creature_actor properties
upd:actor_state = 0xd20
upd:actor_accel_header = 0
upd:actor_accel_data = 0
upd:actor_velocity_header = 0
upd:actor_velocity_data = 0
upd:actor_radiation = 0
upd:actor_weapon = 110
upd:num_items = 0

Примерно такие строки. Для начала расщедримся Припишем актору в:
[dont_spawn_character_supplies]
[spawn] такие строки.

[dont_spawn_character_supplies]
[spawn]
wpn_binoc
wpn_vintorez
ammo_9x39_pab9 = 20
wpn_usp
ammo_11.43x23_hydro = 22
novice_outfit
device_torch

Получиться что мы подарим Меченому при начале игры Винторез, 600 патронов к нему, пистолет USP и 420 патронов к нему. Так. Теперь Меченый у нас будет крутым рэмбо Теперь ещё и подарим ему денежек.

; cse_alife_trader_abstract properties
money = 40
trader_flags = 0
character_profile = actor

В строчке money напишем любое число. Тока астрономические не надо(не проверял). Ну теперь Меченый не только рэмбо но и миллионер. Теперь займемся координатами. У нас они такие:

position = -139.449829101563,-29.6908683776855,-351.492797851563
direction = 0,0.00895109120756388,0

Это наши позиция и дирекция.

; cse_alife_object properties
game_vertex_id = 19 (Тот самый вертекс на игре)
distance = 0.699999988079071
level_vertex_id = 111256 (вертекс на уровне)
object_flags = 0xffffffbf
custom_data = <<END

А теперь пропишем туда такие координаты:

position = -167.232299804688,-25.4363708496094,-354.692901611328
direction = 0,-0.365248799324036,0
; cse_alife_object properties
game_vertex_id = 0
distance = 0.699999988079071
level_vertex_id = 82413
object_flags = 0xffffffbf
custom_data = <<END
upd:health = 1
upd:timestamp = 0x75732029
upd:creature_flags = 0x70
upd:position = -167.232299804688,-25.4363708496094,-354.692901611328
upd:o_model = 0
upd:o_torso = -0.365248799324036,0,0.930909931659698
upd:g_team = 0
upd:g_squad = 0
upd:g_group = 0

Теперь игра начнётся в здании блокпоста на 2 этаже. С этим мы закончим. Теперь создадим нового НПС:

[871]
; cse_abstract properties
section_name = stalker
name = esc_bridge_soldier1
position = -133.27989196777,-30.146812438965,-372.0263671875
direction = 0.028013030067086,0,0.9996075630188
; cse_alife_trader_abstract properties
money = 5000
character_profile = esc_soldier_regular
; cse_alife_object properties
game_vertex_id = 20
distance = 16.1000003814697
level_vertex_id = 118083
object_flags = 0xffffffbf
custom_data = <<END
[logic]
active = walker
[walker]
path_walk = hodim_dvor
END
; cse_visual properties
visual_name = actors\soldier\soldier_bandana_3
; cse_alife_creature_abstract properties
g_team = 0
g_squad = 1
g_group = 2
health = 1
dynamic_out_restrictions =
dynamic_in_restrictions =
upd:health = 1
upd:timestamp = 0
upd:creature_flags = 0
upd:position = -133.27989196777,-30.146812438965,-372.0263671875
upd:o_model = 0
upd:o_torso = 0.028013030067086,0,0.9996075630188
upd:g_team = 0
upd:g_squad = 1
upd:g_group = 2
; cse_alife_monster_abstract properties
upd:next_game_vertex_id = 65535
upd:prev_game_vertex_id = 65535
upd:distance_from_point = 0
upd:distance_to_point = 0
; cse_alife_human_abstract properties
predicate5 = 1,2,2,1,2
predicate4 = 0,1,1,1
; cse_ph_skeleton properties
upd:start_dialog =
; se_stalker properties

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

[logic]
active = walker
[walker]
path_walk = hodim_dvor
Элементарная логика НПС. hodim_dvor-Это путь по которому будет ходить НПС. НПС есть всё готово. Но путя то у нас нет Создадим его в файле way_l01_escape. Припишем вот такие строчки.
[hodim_dvor]
points = p0,p1
p0:name = name00
p0:position = -120.44634246826,-30.15016746521,-363.68786621094
p0:game_vertex_id = 24
p0:level_vertex_id = 132887
p0:links = p1(1)
p1:name = name01 номер точки
p1:position = -132.61611938477,-30.142726898193,-363.87365722656 - только позиция
p1:game_vertex_id = 19 вертекс на игре
p1:level_vertex_id = 118862 вертекс на уровне
p1:links = p0(1) на какую точку после этой перейдёт НПС. (тут он будет ходить туда сюда, если не написать линкс то он остановиться на месте)

Всё! Вгоняем в way эти строки(тока мои комментарии писать не надо) Всё готово можно тестить изменения:_))))). Как снимать координаты и работать с PI расскажу в следующей статье. Теперь жмём на батник запаковка и усё! Пихаем all.spawn в игру. Только лучше ещё поправить отношения актора к военным и наоборот в лучшую сторону. Чтобы непись сразу пошёл по своему пути. Он удет ходить от казармы до дома(там поймёте) Статью написал [[Rez@niy]]


Автор: steelrat
Для этого нам понадобятся стандартные файлы:
config/ui/ui_custom_msgs.xml
scripts/bind_stalker.script

Сложность: Легко
1. Создаём файл ваше_название_скрипта.script в папке gamedata/scripts и пишем в него:

function show_time()
    local hud = get_hud()
    local cs = hud:GetCustomStatic("hud_show_time")
    if cs == nil then
        hud:AddCustomStatic("hud_time_static", true)
        hud:AddCustomStatic("hud_show_time", true)
        cs = hud:GetCustomStatic("hud_show_time")
    end
	    local time_h = level.get_time_hours()
    local time_m = level.get_time_minutes()
    local msg
    if time_m >= 10 then
        msg = string.format(" %02d:%02d\n", time_h, time_m)
    else
        msg = string.format(" %02d:%02d\n", time_h, time_m)
    end
	    if cs ~= nil then cs:wnd():SetText(msg) end
end

2. Далее открываем файл ui_custom_msgs.xml в config/ui и пишем туда:

    <hud_time_static  x="852" y="17" width="156" height="52">
        <text complex_mode="0" x="65" y="0" font="letterica16" r="255" g="255" b="255" a="130">Time</text>
        <texture>ui_hud_frame_clock</texture>
    </hud_time_static>
    <hud_show_time x="862" y="38" width="156" height="52">
        <text x="0" y="0" font="graffiti19" r="255" g="255" b="255" a="140" align="c"/>
    </hud_show_time>

3. Открываем файл bind_stalker.script и пишем после:

function actor_binder:update(delta)
    object_binder.update(self, delta)
    local time = time_global()
    game_stats.update (delta, self.object)

следующее:

ваше_название_скрипта.show_time()


Автор: Xmk, на основе полоски оружия из Симбиона.
Для этого нам понадобятся стандартные файлы:
config/ui/maingame.xml
config/ui/ui_custom_msgs.xml
scripts/bind_stalker.script


Сложность: Средняя
1. Создаём файл new_hud_health.script в папке gamedata/scripts и пишем в него:

local hud_name = "hud_health"
	-- записываем переменную
function save_variable(variable_name, value)
  xr_logic.pstor_store(db.actor, variable_name, value)
end
	-- загружаем переменную
function load_variable(variable_name, value_if_not_found)
  return xr_logic.pstor_retrieve(db.actor, variable_name, value_if_not_found)
end
	-- удаляем переменную
function del_variable(variable_name)
  if db.storage[db.actor:id()].pstor[variable_name] then
    db.storage[db.actor:id()].pstor[variable_name] = nil
  end
end
	-- координаты(параметры) x, y, width, height
local pbg = {x=0,y=0,w=0,h=0} --/ bg
local plv = {x=0,y=0,w=0,h=0} --/ lv
	local skl_w = -1 --/ текущая длина шкалы
local wide  = false --/ текущий режим экрана
	local color        = 0
local change_color = false
local change_wpn   = false
local hud_show     = false
	function update(bShow)
    local hud = get_hud()
    local cs_bg = hud:GetCustomStatic("hud_health_bg")
    local cs_lv = hud:GetCustomStatic("hud_health_lv")
	    if (load_variable("opt_hp",true) == false or bShow == false) then
        if cs_bg then hud:RemoveCustomStatic("hud_health_bg") end
        if cs_lv then hud:RemoveCustomStatic("hud_health_lv") end
        return
        save_variable("opt_hp",false)
    end
	    local hp = db.actor.health
	    if (hp == nil or hp == 0) then
        if hud_show == false then --/ рамку можно не стирать при смене оружия
            if cs_bg then hud:RemoveCustomStatic("hud_health_bg") end
        end
        if cs_lv then hud:RemoveCustomStatic("hud_health_lv") end
        return
    end
	    -- проверка смены режима экрана
    if wide ~= db.wide then
        wide = db.wide
        if cs_bg then hud:RemoveCustomStatic("hud_health_bg") end
        if cs_lv then hud:RemoveCustomStatic("hud_health_lv") end
        cs_bg, cs_lv = nil, nil
    end
	    local cur_hud = "hud_health_bg"
    if cs_bg == nil then
        hud:AddCustomStatic(cur_hud, true)
        cs_bg = hud:GetCustomStatic(cur_hud)
        local wnd = cs_bg:wnd()
        if wnd then
            pbg = read_params(cur_hud)
            wnd:SetWndPos(pbg.x,pbg.y)
            wnd:SetWidth (pbg.w)
            wnd:SetHeight(pbg.h)
            wnd:SetAutoDelete(true)
        end
    end
	    cur_hud = "hud_health_lv"
    if cs_lv == nil then
        hud:AddCustomStatic(cur_hud, true)
        cs_lv = hud:GetCustomStatic(cur_hud)
        local wnd = cs_lv:wnd()
        if wnd ~= nil then
            plv = read_params(cur_hud)
            wnd:SetWndPos(pbg.x+plv.x,pbg.y+plv.y)
            wnd:SetWidth (skl_w)
            wnd:SetHeight(plv.h)
            wnd:SetAutoDelete(true)
            change_color = true --/ смена цвета
        end
    end
	    if cs_lv ~= nil then
        local hp_w = math.floor(hp * plv.w)
        if hp_w ~= skl_w then
            if hp_w < 1 then
                skl_w = -1
            else
                skl_w = hp_w
            end
        end
        local texture_c = get_texture(hp)
        local wnd = cs_lv:wnd()
        wnd:SetWidth(skl_w) --/ Set Level Condition
        wnd:InitTexture(texture_c) --/ Set ColorTexture
        wnd:SetText(string.format(math.floor(hp*100+0.0001)).."%")
    end
	end
	function read_params(cur_hud)
    local ltx = ini_file("scripts\\new_hud_health.ltx")
    local section = cur_hud
    if wide then section = section.."_wide" end
    if ltx and ltx:section_exist(section) then
        local p = {x=0,y=0,w=0,h=0}
        local result, idx, value, i
        for i=0, ltx:line_count(section)-1 do
            result, idx, value = ltx:r_line(section, i, "", "")
            if idx == "x" then
                p.x = tonumber(value)
            elseif idx == "y" then
                p.y = tonumber(value)
            elseif idx == "width" then
                p.w = tonumber(value)
            elseif idx == "height" then
                p.h = tonumber(value)
            end
        end
        return p
    end
end
	function get_texture(hp)
    local textures = {
        [0] = "ui_mg_progress_efficiency_full", --/ зеленая
        [1] = "ui_hud_shk_car", --/ оранжевая
        [2] = "ui_hud_shk_health" --/ красная
    }
    local clr = 0 --/ current color
    if hp > 0.7 then clr = 0
    elseif hp > 0.3 then clr = 1
    elseif hp < 0.3 then clr = 2
    end
    if color ~= clr then
        color = clr
        change_color = true
    else
        change_color = false
    end
    return textures
end

2. Создаём файл new_hud_health.ltx в папке gamedata/config/scripts и пишем в него:

[hud_health_bg]
x = 860
y = 660
width = 155
height = 34
	[hud_health_lv]
x = 33
y = 5
width  = 110
height = 10
	[hud_health_bg_wide]
x = 900
y = 660
width = 123
height = 34
	[hud_health_lv_wide]
x = 24
y = 5
width = 84
height = 10

3. В файле ui_custom_msgs.xml прописываем:

<hud_health_bg x="0" y="0" width="1" height="1" stretch="1" complex_mode="1">
    <texture>ui_hud_shkala_health</texture>
</hud_health_bg>
<hud_health_lv x="0" y="0" stretch="1" complex_mode="1">
    <texture><!-- заглушка --></texture>
    <text x="85" y="0" font="arial_14" r="255" g="255" b="255" a="255" ttl="8" complex_mode="1"/>
</hud_health_lv>

4. Открываем файл maingame.xml
Находим строчки:

<static_health ....>
.....
</static_health>

и

<progress_bar_health ...>
....
</progress_bar_health>

Выделяем и заменяем на следующее:

    <static_health x="860" y="660" width="155" height="34">
        <texture></texture>
        <auto_static x="5" y="10" width="19" height="18">
            <texture></texture>
        </auto_static>
    </static_health>
    <progress_bar_health x="33" y="5" width="110" height="10" horz="1" min="0" max="100" pos="0">
        <progress>
            <texture></texture>
        </progress>
    </progress_bar_health>

5. Открываем файл bind_stalker.script и пишем после:

.....
    level_tasks.add_lchanger_location()
	    self.bCheckStart = false        
end

следующее:

new_hud_health.update()

После этой строчки должно стоять end, проверьте.
Вроде все, если что пишите что неправильно поправлю



Автор: Xmk
Придумал давно, но толком не тестировал, сделал на основе голода из OGSM CS

Для этого нам понадобятся файлы (AMK Mod):
config/misc/items.ltx
config/text/rus/string_table_enc_equipment.xml
scripts/amk.script
script/amk_mod.script


Сложность: Сложно
1. Создаём файл ваше_название_скрипта.script в папке gamedata/scripts и пишем в него:

snd = sound_object([[ambient\underground\rnd_giant]])
	-- Проверяем нужно ли покурить. Вызывается каждые 6 игровых минут
function test_for_need_kur()
    amk.save_variable("kur",amk.load_variable("kur",0)+1)
    amk.g_start_timer("kur",0,0,6)
    kur_reduce_health()
end
	-- Уменьшение здоровья, если долго не курил
function kur_reduce_health()
    local tmp = amk.load_variable("kur",0)
    if tmp > 150 then
        if db.actor.health > 0.15 then
            db.actor.health = - 0.15
        end
        if not snd:playing() then
            snd:play_at_pos(db.actor, vector():set(0,0,0), 0, sound_object.s2d)
        end
    end
end
	-- Курение
function kur_item(oid, time)
    if alife():object(oid)==nil then
        local tmp = amk.load_variable("kur",0) - time*10
        if tmp < 0 then tmp = 0 end
        amk.save_variable("kur", tmp)
        kur_reduce_health()
    end
end

2. Открываем файл amk.script.
После:

function __do_timer_action(select_string,params_string)

пишем:

if select_string=="kur" then
название_вашего_скрипта.test_for_need_kur()
end

3. Открываем файл amk_mod.script
в функции first_run пишем:

amk.g_start_timer("kur",0,0,6)

затем в функции check_sleep_item(obj) после

    elseif section=="treasure_item" then
        stype="tr_item"

но перед end пишем:

  elseif section == "sigaret" then
    stype = "sgr"

4. Открываем файл items.ltx. Добавляем новый предмет:

[sigaret]:identity_immunities
GroupControlSection  = spawn_group
discovery_dependency =
$spawn               = "food and drugs\antirad"
$prefetch            = 32
class                = II_ANTIR
cform                = skeleton
visual               = weapons\sigaret\sigaret.ogf
	inv_name             = sigareta
inv_name_short       = sigareta
description          = enc_food_sigareta
	inv_weight           = 0.02
inv_grid_width       = 1
inv_grid_height      = 2
inv_grid_x           = 10
inv_grid_y           = 24
	cost                 = 50
	; 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

5. Открываем файл string_table_enc_equipment.xml

<string id="sigareta">
    <text>Сигарета</text>
</string>
<string id="enc_food_sigareta">
    <text>Пишем любое описание сигареты, мне че то в голову ниче не приходит</text>
</string>

вроде ни че не забыл...




  • http://www.amk-team.ru/forum/uploads//ratings/bf.gif × 1
  • http://www.amk-team.ru/forum/uploads//ratings/thumb_up.png × 1
  • http://www.amk-team.ru/forum/uploads//ratings/wrench_orange.png × 4

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


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

Для начала нужно создать диалог, сделаем его у Волка:


Заходим в gamedata\config\gameplay\dialogs_escape.xml и в самом конце до строчки </game_dialogs> пишем:
<dialog id="escape_volk_ak74u_quest">
    <has_info>esc_kill_bandits_quest_done</has_info>
    <dont_has_info>escape_volk_ak74u_start</dont_has_info>
    <phrase_list>
        <phrase id="0">
            <text>escape_volk_ak74u_quest_0</text>
            <next>1</next>
        </phrase>
        <phrase id="1">
            <text>escape_volk_ak74u_quest_1</text>
            <next>2</next>
            <next>3</next>
        </phrase>
        <phrase id="2">
            <text>escape_volk_ak74u_quest_2</text>
            <give_info>escape_volk_ak74u_start</give_info>
            <action>new_life.spawn_ak74u</action>
        </phrase>
        <phrase id="3">
            <text>escape_volk_ak74u_quest_3</text>
            <action>dialogs.break_dialog</action>
        </phrase>
    </phrase_list>
</dialog>

<dialog id="escape_volk_ak74u_quest_completed">
    <precondition>new_life.escape_volk_ak74u_have</precondition>
    <has_info>escape_volk_ak74u_have</has_info>
    <dont_has_info>escape_volk_ак74u_done</dont_has_info>
    <phrase_list>
        <phrase id="0">
            <text>escape_volk_ak74u_quest_completed_0</text>
            <next>1</next>
        </phrase>
        <phrase id="1">
            <text>escape_volk_ak74u_quest_completed_1</text>
            <next>2</next>
        </phrase>
        <phrase id="2">
            <text>escape_volk_ak74u_quest_completed_2</text>
            <give_info>escape_volk_ak74u_done</give_info>
            <action>new_life.give_volk_ak74u</action>
            <next>3</next>
        </phrase>
        <phrase id="3">
            <text>escape_volk_ak74u_quest_completed_3</text>
            <action>new_life.complete_volk_quest</action>
        </phrase>
    </phrase_list>
</dialog>

Теперь нужно прописать эти диалоги Волку, для этого заходим в gamedata\config\gameplay\character_desc_escape.xml и находим профиль Волка(он называется esc_wolf), перед строкой </specific_character> пишем:

<actor_dialog>escape_volk_ak74u_quest</actor_dialog>
<actor_dialog>escape_volk_ak74u_quest_completed</actor_dialog>

Нам понадобятся два диалога: 1 для получения квеста, 2 для передачи автомата.
<dialog id="escape_volk_ak74u_quest"> - Это название диалога
<has_info>esc_kill_bandits_quest_done</has_info> - эта строка означает что квест появится только если получен инфопоршень esc_kill_bandits_quest_done
<dont_has_info>escape_volk_ak74u_start</dont_has_info> - эта строка означает что если получен инфопоршень escape_volk_ak74u_start, то этот диалог больше не появится.
<text>escape_volk_ak74u_quest_0</text> - это ссылка на текст фразы меченого
<next>1</next> - это ссылка на текст с id= 1 , а id= 1 это <text>escape_volk_ak74u_quest_1</text> (ссылка на текст Волка)
<next>2</next>
<next>3</next>
- эти две строчки означают что идет разветвление диалога
<give_info>escape_volk_ak74u_start</give_info> - выдача инфопоршня, после которого начинается квест
<action>new_life.spawn_ak74u</action> - функция вызываемая из скрипта new_life, в данном случае спаунится предмет AK74У
<action>dialogs.break_dialog</action> - функция отвечающая за выход из диалога

Во втором диалоге есть строка <precondition>new_life.escape_volk_ak74u_have</precondition> - она отвечает за появление диалога если выполняется функция escape_volk_ak74u_have

Теперь нужно сделать текст диалога на русском языке, для этого заходим в gamedata\config\tex\rus\stable_dialogs_escape.xml и в нём пишем следующее(в конце перед </string_table>):

<string id="escape_volk_ak74u_quest_0">
    <text>Здорова Волк, для меня есть какая-нибудь работа?</text>
</string>
<string id="escape_volk_ak74u_quest_1">
    <text>Да, есть одно дело: вобщем шёл сюда в лагерь к Сидырычу, решил пройти через тоннель чтоб воякам денег не платить, а там собак было штук десять. Ну я начал отстреливаться, где-то шестерых убил и патроны кончились, пришлось АКСУ выкинуть, чтоб от стаи собак убежать. Таки лежит там наверно АКСУ. \nНу как, возьмёшься? Только осторожней там, после последнего выброса появились в тоннеле перещающиеся аномалии электра.</text>
</string>
<string id="escape_volk_ak74u_quest_2">
    <text>Да, я как раз буду рядом проходить, конечно принесу...</text>
</string>
<string id="escape_volk_ak74u_quest_3">
    <text>Нет, Волк, сам туда иди...</text>
</string>
<string id="escape_volk_ak74u_quest_completed_0">
    <text>Привет, Волк, ну как оно?...</text>
</string>
<string id="escape_volk_ak74u_quest_completed_1">
    <text>Сидор водку не даёт, хе хе, а так всё хорошо.</text>
</string>
<string id="escape_volk_ak74u_quest_completed_2">
    <text>Вот, нашел я твой АКСУ.</text>
</string>
<string id="escape_volk_ak74u_quest_completed_3">
    <text>Эх спасибо тебе Меченый, вот держи, может на что-нибудь хватит.</text>
</string>

Итак, диалог готов, теперь нужно сделать сам квест, для этого заходим в gamedata\config\gameplay\tasks_escape.xml и в самом конце пишем:

<game_task id="escape_volk_ak74u">
    <title>Найти потерянный АКСУ</title>
    <objective>
        <text>Найти потерянный АКСУ</text>
        <icon>ui_iconsTotal_weapons</icon>
        <infoportion_complete>escape_volk_ak74u_done</infoportion_complete>
        <article>tex_escape_volk_ak74u</article>
    </objective>
    <objective>
        <text>Найти АКСУ</text>
        <function_complete>new_life.escape_volk_ak74u_have</function_complete>
        <infoportion_set_complete>escape_volk_ak74u_have</infoportion_set_complete>
    </objective>
    <objective>
        <text>Принести АКСУ Волку</text>
        <map_location_type hint="Волк">blue_location</map_location_type>
        <object_story_id>Escape_novice_lager_volk</object_story_id>
        <infoportion_complete>escape_volk_ak74u_done</infoportion_complete>
    </objective>
</game_task>

<game_task id="escape_volk_ak74u"> - id квеста;
<title>Найти потерянный АКСУ</title> - название квеста;
<text>Найти потерянный АКСУ</text> - название подзадачи;
<icon>ui_iconsTotal_weapons</icon> - иконка задания;
<infoportion_complete>escape_volk_ak74u_done</infoportion_complete> - квест будет выполнен, если был получен инфопоршень escape_volk_ak74u_done;
<article>tex_escape_volk_ak74u</article> - ссылка на текстовый файл с описанием задания;
<text>Найти АКСУ</text> - название подзадачи;
<function_complete>new_life.escape_volk_ak74u_have</function_complete> - проверка на наличие предмета;
<infoportion_set_complete>escape_volk_ak74u_have</infoportion_set_complete> если функция new_life.escape_volk_ak74u_have выполнилась, то выдаётся инфопоршень escape_volk_ak74u_have и выполняется подзадача;
<text>Принести АКСУ Волку</text> - название второй подзадачи;
<map_location_type hint="Волк">blue_location</map_location_type> - указатель на Волка;
<object_story_id>Escape_novice_lager_volk</object_story_id> - id Волка в Файле gamedata\config\game_story_ids.ltx[/i][/b];
<infoportion_complete>escape_volk_ak74u_done</infoportion_complete> - если будет получен этот инфопоршень, то выполнится подзадача и соответственно сам квест.

Нужно сделать инфопоршни, заходим в gamedata\config\gameplay\info_l01escape.xml и в нём в конце до строчки </game_information_portions> пишем:


<info_portion id="escape_volk_ak74u_start">
    <task>escape_volk_ak74u</task>
</info_portion>
<info_portion id="escape_volk_ak74u_have"></info_portion>
<info_portion id="escape_volk_ak74u_done"></info_portion>

Теперь нужно сделать описание квеста, заходим в gamedata\config\gameplay\storyline_info_escape.xml и пишем в конце:

<article id="tex_escape_volk_ak74u" name="Найти потерянный ак74u" article_type="task">
<texture x="0" y="800" width="200" height="100">ui\ui_icon_equipment</texture>
<text>tex_escape_volk_ak74u</text>
</article>

Сделаем описание на русском, заходим в stable_dialogs_escape.xml и в конце до строки </string_table> пишем:

<string id="tex_escape_volk_ak74u">
<text>Волк попросил принести потерянный в туннеле АКСУ</text>
</string>

Теперь создадим скриптовый файл new_life в gamedata\scripts\new_life.script и пишем:

function spawn_ak74u()
    amk.spawn_item("wpn_ak74u",vector():set(-78.85,-1.29,154.74),163,189935) -- спавн ak74u в тоннеле на кордоне
end

function escape_volk_ak74u_have()
    return sak.have_item_namber("wpn_ak74u",1) ~= false -- проверка на нахождение предмета в рюкзаке
end

function give_volk_ak74u(first_speaker, second_speaker) -- передача предмета
    sak.out_item_namber("wpn_ak74u", 1)
end

function complete_volk_quest(first_speaker, second_speaker) -- получение награды
    dialogs.relocate_money(second_speaker, 1500, "in")
end

Чтобы эти скрипты заработали, нужно создать файлы amk.script и sak.script.
В аmk.script пишем:

function spawn_item(spawn_item, pos, gv,lv)
if gv==nil then gv=db.actor:game_vertex_id() end
if lv==nil then lv=db.actor:level_vertex_id() end
return alife():create(spawn_item, pos, lv, gv)
end

function remove_item_from_inventory(remove_item,npc)
if npc==nil then npc=db.actor end
if remove_item~=nil then
-- npc:mark_item_dropped(remove_item)
alife():release(alife():object(remove_item:id()), true)
return true
end
return false
end

В sak.script пишем:

local items_count=0
local itemin=nil

function have_item_namber(itm,need_namber)
local actor=db.actor
items_count=0
itemin=itm
actor:iterate_inventory(cheking_item,actor)
if items_count>=need_namber then
return true
else
return false
end
end

function cheking_item(actor,item)
local items=item:section()
if items==itemin then
items_count=items_count+1
end
end

function create_items(npc,section,number)
for i=1,number do
alife():create(section,
npc:position(),
npc:level_vertex_id(),
npc:game_vertex_id(),
npc:id())
end
end

local reloc_params={}
local stalk
function out_item_namber(itm_section,need_number)
reloc_params.itm_section=itm_section
reloc_params.itm_cnt=need_number
reloc_params.itm_cnt_found=0
db.actor:iterate_inventory(checkout_items_count,db.actor)
reloc_params.itm_cnt_found=0
if reloc_params.itm_cnt_found<=reloc_params.itm_cnt then
db.actor:iterate_inventory(out_items_count,db.actor)
end
news_manager.relocate_item(db.actor, "out", itm_section)
reloc_params={}
end

function relocate_item_namber(stalker,itm_section,need_number)
stalk=stalker
reloc_params.itm_section=itm_section
reloc_params.itm_cnt=need_number
reloc_params.itm_cnt_found=0
db.actor:iterate_inventory(checkout_items_count,db.actor)
reloc_params.itm_cnt_found=0
if reloc_params.itm_cnt_found<=reloc_params.itm_cnt then
db.actor:iterate_inventory(reloc_items_count,db.actor)
end
news_manager.relocate_item(db.actor, "out", itm_section)
reloc_params={}
end

function checkout_items_count(actor,item)
if item.section and item:section()==reloc_params.itm_section then
reloc_params.itm_cnt_found = reloc_params.itm_cnt_found + 1
end
end

function reloc_items_count(actor,item)
if item.section and item:section()==reloc_params.itm_section and reloc_params.itm_cnt_found<reloc_params.itm_cnt then
db.actor:transfer_item(item, stalk)
reloc_params.itm_cnt_found = reloc_params.itm_cnt_found + 1
end
end

function out_items_count(actor,item)
if item.section and item:section()==reloc_params.itm_section and reloc_params.itm_cnt_found<reloc_params.itm_cnt then
amk.remove_item_from_inventory(item, actor)
reloc_params.itm_cnt_found = reloc_params.itm_cnt_found + 1
end
end

Всё! Можно тестировать.

Примечание!!! Если вы делаете такой квест на оригинальном сталкере, то ОБЯЗАТЕЛЬНО нужно создать файлы amk.script и sak.script.
Если вы делаете квест на amk моде, то нужно создать только файл sak.script

Автор: sasha47007

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

  • http://www.amk-team.ru/forum/uploads//ratings/wrench_orange.png × 1

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


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

Тутор по гулагам.
Вот IG-2007 на оф.форуме осенью прошлого года написал такой тутор по гулагам. Здесь показана работа в гулаге для сталкера. Днем он гуляет (walker), а ночью сидит у костра (kamp).

1) Пропишите в all.spawn своему смарту такую custom_data:
custom_data = <<END
[smart_terrain]
type = esc_new_lager
capacity = 1
END

2) Пропишите в all.spawn два пути: один из нескольких точек для схемы walker (esc_new_lager_npc1_walk), другой из одной точки (центр кампа) для kamp (esc_new_lager_npc1_kamp)
3) Откройте файл config\misc\gulag_escape.ltx и добавьте в самый конец работу для своего сталкера:

[logic@esc_new_lager_npc1]
active = walker@esc_new_lager_npc1

[walker@esc_new_lager_npc1]
path_walk = npc1_walk
on_info = {!is_day} kamp@esc_new_lager_npc1

[kamp@esc_new_lager_npc1]
center_point = npc1_kamp
on_info = {=is_day} walker@esc_new_lager_npc1

4) Откройте файл gulag_escape.script и добавьте в него:
4.1) в функцию load_job:

if type == "esc_new_lager" then
    t = { section = "logic@esc_new_lager_npc1",
    idle = 0,
    prior = 5, state = {0},
    online = false,
    in_rest = "", out_rest = ""
    }
    table.insert(sj, t)
end

4.2) в функцию load_states:

if type == "esc_new_lager" then
    return function (gulag)
        return 0
    end
end

4.3) в функцию checkStalker:

if gulag_type == "esc_new_lager" then
    return npc_community == "stalker"
end

 


И кстати. По тутору по работе с алл.спавн. Хочется внести ясность по одному из них.
Вот эту информацию написал я, а не Rezaniy. Получается, что он чужую работу выдает за свою.

По распаковке алл.спавна с помощью acdc.
Расскажу, как делать это без батников.
Если надо распаковать алл.спавн.
1. Помещаем файл алл.спавн в папку, где находятся файлы от acdc. Лучше создать ее на диске С:
2. Нажимаем ПУСК - Выполнить. Появляется командное окно.
3. Вводим команду cmd. Появляется черное окно.
4. В нем пишем cd\ Далее нажимаем enter. Происходит перенос на другую строчку. Эта команда задает диск С для работы с ним.
5. Далее пишем cd C:\"название папки, куда поместили acdc". Нажимаем enter. Переход на другую строчку. Теперь задали папку с которой будем работать. Вот здесь и надо будет вводить команды для acdc.
6. Вводим acdc.pl -d all.spawn Нажимаем enter.
7. Если асдс подходит для данного алл.спавна, то вскоре все распакуется и распакованные файлы можно будет обнаружить в папке с асдс.
8. Если асдс не подходит, то он выдаст ошибку. Тут же в этом черном окне. Надо будет внимательно прочитать о чем ошибка. Обычно для разных модов не хватает какого-нибудь описания чего-нибудь. Например, может ругаться что не может найти af_soul.
Тогда надо будет открыть файл acdc.pl блокнотом. Там найти, где описываются артефакты и в конце строк с артефактами сделать запись для af_soul, напримере других артефактов. После сохранить файл и заново набрать команду по распаковке.
9. После того, как сделали изменения в алл.спавне, надо будет таким же образом войти в папку с acdc, как описывалось раньше.
10. Набрать следующую команду: acdc.pl -c all.ltx
11. Если все сделали правильно в алл.спавне, то через некоторе время в папке с асдс появится файл all.spawn.new. Его надо будет переименовать в all.spawn
12. Правило при работе с алл.спавном - не забывайте правильно пронумеровывать вновь создаваемые секции. Для этого надо найти самый большой номер секции в алл.спавне. И присваивать своим секциям номера по порядку за этим номером.

 

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

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


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

1. Кладём ролик в папку

gamedata\textures\sleep\. Собственно, в любую папку, лишь бы она была в каталоге textures. Просто в sleep лежат ролики сна в оригинале.
имя файла любое, формат ogm, а разрешение ролика вроде можно сделать любое. Я не стал заморачиваться и просто скопировал существующий ролик сна с монолитом.
2. Озвучку ролика кладем по той-же схеме в папку в корневом каталогу gamedata\sounds\. У меня папка называется my_sleep. Имена файлов для левого и правого канала должны выглядеть так
my_sleep_sound_l.ogg
и
my_sleep_sound_r.ogg
длина звуков может быть разной и вообще говоря не совпадать с длиной ролика.
3. Правим файл \gamedata\config\ui\ui_movies.xml. Добавляем туда что-то в этом роде:
    <my_dream>
        <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>my_sleep\my_sleep_sound</sound>
            <pause_state>on</pause_state>
            <function_on_stop>sleep_manager.stopper</function_on_stop>
            <video_wnd x="0" y="0" width="1024" height="768" stretch="1">
                <texture x="0" y="1" width="512" height="286">sleep\dream_sarcofag</texture>
            </video_wnd>
        </item>
    </my_dream>

Название тега my_dream - это моё имя для сна. Если я верно всё понимаю, то вся эта фигня описывает окно, в котором играется видеоролик.
4. Теперь собственно добавляем сон. Правим файл gamedata\config\misc\dream.ltx.
Там есть секции с именами [regular_dream#] где # - это номера снов. Сейчас там есть regular_dream1, regular_dream2 и regular_dream3. Добавляем секцию:
[regular_dream4]
dream       = my_dream
probability = 40
type        = happy
параметры:
dream - это ранее заданное имя сна (в нашем случае my_dream).
probability - ясное дело, что нужно для вычисления вероятности появления именно этого сна. Но я пока не понял по какому алгоритму она вычисляется на основе этого параметра. Я просто сделал число побольше, дабы протестировать побыстрее.
type - может быть nightmare, normal и happy. По названию вроде понятно, что это. Но на что влияет пока не ясно.
5. Ну и завершающий этап. В этом же файле в секцию [dreams] к параметру regular добавляем к списку новый сон regular_dream4. Вроде такого
regular = regular_dream1, regular_dream2, regular_dream3, regular_dream4

Тестируем... Опа! Новый сон. Поскольку я звуки взял случайно, то при этом в левом ухе у меня орет кот, а в правом играет мрачный эмбиент =)
Ну и естественно работать будет только при установленном АМК. Что там именно сделано, для того чтобы сон вообще был, я пока не разбирался.

У любого клиентского объекта имеется метод give_game_news
Он и выводит сообщения на экран. Экспериментом выяснил, что сообщение можно вывести совершенно от любого клиентского объекта, хоть от куска колбасы (хвала дизайнерскому гению GSC! Ну почему не сделать просто глобальную функцию?). Однако, следуя традиции и здравому смыслу, мы таки воспользуемся для этого объектом, соответствующим ГГ, т.е. актёром.

    local sactor = alife():actor() --получаем серверный объект актера
    local cactor = level.object_by_id(sactor.id) --по его ID получаем клиентский объект актера
    cactor:give_game_news(
        "Свободу тушканам!\\nТушканчики всех стран, объединяйтесь!", -- строка сообщение, может быть многострочной
        "ui\\ui_npc_monster",        --текстура, из которой берется аватара "отправителя"
        Frect():set(0,215,163,105),  --координаты и размеры вырезаемого из текстуры изображения
        math.random(1000, 3000),     --начало показа сообщения с текущего момента (в миллисекундах)
        5000                         --длительность показа сообщения (в миллисекундах)
        )
Доп. комментарии к аргументам give_game_news:
имя текстуры - это имя файла DDS без расширения, адресуемого относительно папки \gamedata\textures\
в этом выражении Frect():set(0,215,163,105)
0,215 - это координаты верхнего левого угла нужного изображения
163,105 - его размеры
Размеры и координаты могут быть любыми, но полученное изображение будет увеличено или уменьшено до размеров 83х47
В данном случае изображение тушкана из файла ui_npc_monster.dds было уменьшено.
Параметр времени начала показа нужен, очевидно, для внесения некоторой живости в игру. Дело в том, что код Lua получает управление только в определённые моменты, по определённым событиям. В такой момент можно сгенерить пачку сообщений и раскидать их по времени с помощью этого параметра, создав таким образом некоторую имитацию жизнедеятельности на ближайшее время. Думаю, таким же образом можно имитировать диалоги. Просто генерится пачка сообщений и им задаётся вывод с небольшим интервалом.

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

  • http://www.amk-team.ru/forum/uploads//ratings/thumb_up.png × 4

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


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

Тутор по системе апгрейдов (ЧН)

Для редактирования уже существующих апгрейдов на примере АК74 нам

обязательно понадобятся файлы:
1. configs\weapons\upgrades\w_ak74_up.ltx
2. configs\text\rus\st_items_weapons_upgrades.xml
3. configs\weapons\upgrades_properties.ltx
4. configs\weapons\w_ak74.ltx
5. configs\ui\textures_descr\ui_ingame2_common.xml

Итак, начнём, открыв файл №1. Видим уже привычную нам параметро-секционную структуру файла:
[секция1]
параметр1 = значение1
параметр2 = значение2
параметр3 = значение3
...

[секция2]
параметр1 = значение1
параметр2 = значение2
...

Все секции в файле №1 можно разбить на три типа:
1. Показывающие стоимость, изменения и значения описаний при апгрейде. Эти секции - не главные, на них идёт ссылка с секций вторых типов. Рассмотрим параметры на примере секции:

[up_sect_c_ak74]
cost                      = 1600
value                    = -30

cam_dispersion              = -0.21;0.7
cam_dispersion_inc             = -0.21;0.7
cam_step_angle_horz            = -0.21;0.7

zoom_cam_dispersion          = -0.2;0.6
zoom_cam_dispersion_inc      = -0.2;0.6
zoom_cam_step_angle_horz     = -0.2;0.6

Параметр cost означает цену, которую должен заплатить игрок для осуществления апгрейда.

Параметр value. Мы знаем, что во множестве апгрейдов есть такие, описания которых сводится к типу: [характеристика] [+ или -] [значение]%. Например: "Отдача -30%". Значение, которое показывается в данном случае берётся из параметра value (остальные случаи, в которых описание не подходит под эту схему, например, "не стреляет дробью" рассмотрим потом). Внимание: это значение является словесным описанием и никак не влияет на характеристики оружия". Т.е. можно в нашей секции поставить value = -10000. Суть апгрейда не изменится, изменяется только его описание.

Параметры изменения характеристик. Далее следуют изменения характеристик оружия. В значениях параметров указывается изменение, относительное по отношению к старым характеристикам. Допустим, перед апгрейдом было:

cam_dispersion = 0.7

Указав в параметрах в файле №1:

cam_dispersion = -0.21

в результате получаем:

cam_dispersion = 0.49

2. Главные секции апгрейда. Опять рассмотрим параметры:

[up_c_ak74]
scheme_index            = 0, 2
known                   = 1
effects                 = up_gr_ac_ak74
section                 = up_sect_c_ak74
property                = prop_recoil

precondition_functor    = inventory_upgrades.precondition_functor_a
precondition_parameter  = true

effect_functor          = inventory_upgrades.effect_functor_a
effect_parameter        = something_here

; ui
prereq_functor          = inventory_upgrades.prereq_functor_a
prereq_tooltip_functor  = inventory_upgrades.prereq_tooltip_functor_a
prereq_params           = up_c_ak74
name                    = st_upg_porsh_recoil
description             = st_upg_porsh_recoil_descr
icon                    = ui_wp_upgrade_41

Параметр scheme_index указывает положение иконки апгрейда в дереве апгрейдов (оно появляется при нажатии кнопки "улучшить") Подробнее на этом параметре остановимся во втором спойлере.

Параметр effects. Всем хорошо известно, что ап №1 во втором столбце дерева апов можно получить только тогда, когда проведены апы №1 и №3 в первом столбце. Для открытия апов после проведения других и служит параметр effects, включающий другие апгрейды. Он даёт ссылку на секцию №3. Подробнее на них остановимся чуть ниже.

Параметр section указывает ссылку на секцию №1. От этого значения зависит изменения при апе.

Параметр property указывает тип проводимого апа. Типы апов можно взять в начале файла №3. Подробнее об этом параметре в спойлере №3.

Типы апов:

prop_weight;; Вес
prop_silencer;; Глушитель
prop_underbarrel_slot;; Крепление подствольника
prop_reliability;; Надежность
prop_bullet_speed;; Настильность
prop_recoil;; Отдача
prop_ammo_size;; Патроны
prop_grenade_launcher;; Подствольник
prop_scope_4x;; Прицел 4
prop_scope_1.6x;; Прицел 1.6
prop_rpm;; Скорострельность
prop_calibre;; калибр (9x18, 5x45)
prop_dispersion;; Точность
prop_inertion;; Удобство

prop_armor;;Броня
prop_damage;;Повреждение
prop_durability;;Износостойкость (прочность)
prop_restore_bleeding;;Уменьшение кровотечения
prop_restore_health;;Восстановление здоровья
prop_night_vision;;Прибор ночного виденья
prop_power;;Восстановление стамины
prop_tonnage;;Переносимый вес
prop_radio_chem;;Радио-хим защита
prop_thermo_electro;;Термо-электро защита
prop_psy;;Пси защита
prop_artefact;;Слот для артефактов

Параметр prereq_params. В значении параметра указывайте секцию, в которой находится параметр. Нужно для скриптовых целей.

Параметр name содержит ссылку на текстовый блок из файла №2. В нашем случае:

name                    = st_upg_porsh_recoil
<string id="st_upg_porsh_recoil">
    <text>Модификация газового поршня</text>
</string>

Параметр description похож на параметр name, но касается описания апгрейда. Здесь:

description             = st_upg_porsh_recoil_descr
<string id="st_upg_porsh_recoil_descr">
    <text>Установка компенсатора газового поршня позволяет уменьшить отдачу</text>
</string>

Параметр icon содержит указатель на описание иконок в файле №5.
Вот структура файла:

<texture id="[указатель на иконку]" x="[координата x верхнего левого пикселя иконки]" y="[координата y верхнего левого пикселя иконки]" width="[ширина иконки]" height="[высота]" />

В нашем случае:

<texture id="ui_wp_upgrade_41" x="420" y="944" width="70" height="40" />

3. Секции, объединяющие апгрейды в группы апгрейдов. (в единственном параметре elements указываются апгрейды, входящие в группу, т.е. ссылки на секции вторых типов) Из группы апгрейдов может быть проведён только один апгрейд (в первом столбце может быть проведён только один из апгрейдов - №1 или №2). При включении группы апгрейдов включаются все апгрейды, входящие в группу. Для включения группы необходимо, чтобы все апгрейды с эффектом включения этой группы были проведены. (Для открытия группы апгрейдов up_gr_ac_ak74 необходимо, чтобы были проведены апгрейды up_gr_a_ak74 и up_gr_c_ak74. Названия тут ни при чём: в главных секциях (тип секции №2) этих двух апгрейдов параметр effects принимает значение up_gr_ac_ak74)

Таким образом, каждый апгрейд:
1. Имеет какие-то характеристики.
2. Имеет какое-то описание.
3. Принадлежит к какой-то группе апгрейдов.

Теперь несколько важных замечаний:
1. В файле №4 (конфиг самого АК74 и его уникальных модификаций) присутствует несколько параметров:

Параметр upgrades. В его значениях перечисляются группы апгрейдов, апгрейды которых могут быть проведены на чистом АК74. Перечисление идёт через запятую. После последней группы апгрейдов запятая не нужна.
Параметр installed_upgrades указывает апгрейды, которые уже проведены в этом оружии. Здесь указываются не группы апгрейдов, а сами апгрейды, т.е. секции второго типа.

Нам необходимо иметь 7 файлов:
1. configs\weapons\upgrades\w_ak74_up.ltx
2. configs\text\rus\st_items_weapons_upgrades.xml
3. configs\weapons\upgrades_properties.ltx
4. configs\ui\inventory_upgrade_16.xml (для широкоформатных)
5. configs\weapons\w_ak74.ltx
6. configs\ui\textures_descr\ui_ingame2_common.xml
7. scripts\inventory_upgrades.script

Перед прочтением текста ниже рекомендуется прочитать содержание первого спойлера.

Итак, начнём по порядку:
1. Создадим главную секцию (секцию типа №2) нового апгрейда, скопировав любую другую и поменяв параметры и само название секции:

[up_pack_a_ak74]
scheme_index            = 3, 0
known                   = 1
effects                 =
section                 = up_sect_pack_a_ak74
property                = prop_pack

precondition_functor    = inventory_upgrades.precondition_functor_a
precondition_parameter  = true

effect_functor          = inventory_upgrades.effect_functor_a
effect_parameter        = something_here

; ui
prereq_functor          = inventory_upgrades.prereq_functor_a
prereq_tooltip_functor  = inventory_upgrades.prereq_tooltip_functor_a
prereq_params           = up_pack_a_ak74
name                    = st_upg_pack_a_ak74
description             = st_upg_pack_a_ak74_descr
icon                    = ui_wp_upgrade_30

Как видим, в параметре property "prop_pack", мы указали не существующий тип. Мы его создадим самостоятельно чуть позже.

2. Теперь создадим секцию типа №1, которую мы указали в параметре section "up_sect_pack_a_ak74":

[up_sect_pack_a_ak74]
cost                      = 5120
value                    = desc_value_pack_a
rpm                     = 100
cam_dispersion              = -0.21;0.7
cam_dispersion_inc             = -0.21;0.7
cam_step_angle_horz            = -0.21;0.7
zoom_cam_dispersion          = -0.2;0.6
zoom_cam_dispersion_inc      = -0.2;0.6
zoom_cam_step_angle_horz     = -0.2;0.6
grenade_launcher_status = 2
grenade_launcher_name   = wpn_addon_grenade_launcher
grenade_launcher_x      = 126
grenade_launcher_y      = 24
control_inertion_factor    = -0.2
inv_weight                = -0.3
PDM_disp_vel_factor     = -0.3;1.7
PDM_disp_accel_factor   = -0.3;1.7

Здесь я собрал все улучшения четырёх апгрейдов, суммировав цену и делая скидку 20% (1600*4*0.8 = 5120) Отсюда и название апгрейда - st_upg_pack_a_ak74. В значении value я поставил "desc_value_pack_a". В данном случае в value присутствует ссылка на текстовый блок, а не кол-во процентов.

3. Теперь вернёмся в главную секцию. Т.к. апгрейд является пакетом апгрейдов up_sect_a_ak74,up_sect_c_ak74,up_sect_e_ak74,up_sect_g_ak74, то после проведения нашего апгрейда, четыре выше упомянутые должны выключиться. Для этого запишем наш апгрейд одновременно в несколько секций типов №3:

[up_gr_ab_ak74]
elements                = up_a_ak74, up_b_ak74, up_pack_a_ak74

[up_gr_cd_ak74]
elements                = up_c_ak74, up_d_ak74, up_pack_a_ak74

[up_gr_ef_ak74]
elements                = up_e_ak74, up_f_ak74, up_pack_a_ak74

[up_gr_gh_ak74]
elements                = up_g_ak74, up_h_ak74, up_pack_a_ak74

Т.к. из одной группы апгрейдов можно провести только один, то при проведении нашего апгрейда остальные "соседи" по группе апгрейдов выключатся.

4. Теперь, пользуясь файлом №2 запишем текстовые блоки, упомянутые в секциях типов №1 и №2.

    <string id="st_upg_pack_a_ak74">
        <text>Пакет апгрейдов №1</text>
    </string>
    <string id="st_upg_pack_a_ak74_descr">
        <text>Пакет апгрейдов №1, включающий в себя увеличение темпа стрельбы, уменьшение отдачи, установку крепежа для подствольного гранатомёта, уменьшение веса оружия</text>
    </string>
    <string id="st_upg_pack_a_ak74">
        <text>Пакет апгрейдов №1 Убийца</text>
    </string>

5. Теперь создадим ui для нашего апгрейда для того, чтобы кнопка апгрейда была видна в дереве апгрейдов. В парамре scheme_index мы указали "3,0". Это значит, что в дереве апгрейдов этот апгрейд будет в 3-ем столбце и 0-ой строке. К каждому оружию предлагается своя схема дерева апгрейдов. Чтобы узнать схему АК74 откроем его конфиг (файл №5) и найдём параметр upgrade_scheme. Его значение - upgrade_scheme_u17b. Откроем файл №4 со схемами апгрейдов. Вот его общая структура:

<template name="[название схемы]">

      [нулевой столбец]<column>
        [нулевая строка нулевого столбца. [b]Соответствует индексу 0,0[/b]]<cell x="[координата x]" y="[координата y]"   />
        [первая строка нулевого столбца. [b]Соответствует индексу 0,1[/b]]<cell x="[координата x]" y="[координата y]"  />
        ...
      [конец нулевого столбца]</column>

      [начало первого столбца]<column>
        [нулевая строка первого столбца. [b]Соответствует индексу 1,0[/b]]<cell x="[координата x]" y="[координата y]"  />
        ...
      [конец первого столбца]</column>
      ...
    [конец схемы]</template>

Найдём интересующую нас схему и добавим столбец и строку:

   <template name="upgrade_scheme_u17b">

      <column>
        <cell x="17" y="5"   />
        <cell x="17" y="50"  />
        <cell x="17" y="100" />
        <cell x="17" y="145" />
        <cell x="17" y="195" />
        <cell x="17" y="240" />
        <cell x="17" y="290" />
        <cell x="17" y="335" />
        <cell x="17" y="385" />
      </column>

      <column>
        <cell x="100" y="50"  />
        <cell x="100" y="100" />
        <cell x="100" y="240" />
        <cell x="100" y="290" />
        <cell x="100" y="385" />
       </column>

      <column>
        <cell x="183" y="145" />
        <cell x="183" y="195" />
        <cell x="183" y="385" />
      </column>
      
      <column>
        <cell x="183" y="5" />
      </column>

    </template>

6. Создадим новый тип апгрейдов: prop_pack. Для этого воспользуемся файлом №3.
Для начала добавим наш тип в начало файла:

[upgrades_properties]
prop_pack
prop_weight;; Вес
prop_silencer;; Глушитель
prop_underbarrel_slot;; Крепление подствольника
...

Теперь создадим новую секцию:

[prop_pack]
name     = st_prop_weight
icon     = ui_wp_propery_11
functor  = inventory_upgrades.property_functor_d
params   = hit_power, rpm, cost

В нашем случае важен только один параметр:

functor  = inventory_upgrades.property_functor_d

Он указывает, какая скриптовая функция будет составлять описание. Вы можете сами рассмотреть остальные параметры: name - название типа апгрейда (даётся ссылка на текстовый блок), icon - ссылка на указатель иконок из файла №6.

7. Составим функцию описания апгрейда inventory_upgrades.property_functor_d. Для этого откроем файл №7 и впишем туда маленькую функцию:

function property_functor_d( param1, name )
    local prorerty_name = char_ini:r_string(name, "name")
    local value_table = utils.parse_names(param1)
    local section = value_table[1]
    if section then
        local value = char_ini:r_string(section, "value")
        if value then
            return game.translate_string(value)
        end
    end
    return game.translate_string(prorerty_name)
end

 

 

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

  • http://www.amk-team.ru/forum/uploads//ratings/bf.gif × 1

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


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

Для начинающих модмейкеров.

Добавление вещей в рюкзак сталкера после смерти.


Редактируем файл death_items_by_communities.ltx:
[stalker];Указывается вероятность заспаунить или нет (будет ли у сталкера данный предмет после смерти)
;Артефакты
af_medusa                = 0.015;(если заменить 0.015 на 1.0), то будет 100% вероятность что после смерти у сталкера в рюкзаке будет артефакт медуза
af_cristall_flower        = 0.01
af_night_star            = 0.005
af_vyvert                = 0.015
af_gravi                = 0.01
af_gold_fish            = 0.005
af_blood                = 0.015
af_mincer_meat            = 0.01
af_soul                    = 0.005
af_electra_sparkler        = 0.015
af_electra_flash        = 0.01
af_electra_moonlight    = 0.005
af_rusty_thorn            = 0.015
af_rusty_kristall        = 0.01
af_rusty_sea-urchin        = 0.005
af_ameba_slime            = 0.015
af_ameba_slug            = 0.01
af_ameba_mica            = 0.005
af_drops                = 0.015
af_fireball                = 0.01
af_cristall                = 0.005
af_dummy_glassbeads        = 0.005
af_dummy_pellicle        = 0.005
af_dummy_battery        = 0.005
af_dummy_dummy            = 0.005
af_dummy_spring            = 0.005
af_fuzz_kolobok            = 0.005

;Аммуниция
ammo_9x18_fmj            = 1
ammo_9x18_pmm            = 1
ammo_9x19_pbp            = 1
ammo_9x19_fmj            = 1
ammo_11.43x23_hydro        = 1
ammo_11.43x23_fmj        = 1
ammo_12x70_buck            = 1
ammo_12x76_dart            = 1
ammo_12x76_zhekan        = 1
ammo_5.45x39_ap            = 1
ammo_5.45x39_fmj        = 1
ammo_9x39_sp5            = 1
ammo_9x39_ap            = 1
ammo_9x39_pab9            = 1
ammo_5.56x45_ss190        = 1
ammo_5.56x45_ap            = 1
ammo_7.62x54_7h14        = 1
ammo_7.62x54_7h1        = 1
ammo_7.62x54_ap            = 1
ammo_gauss                = 1
ammo_og-7b                = 1
ammo_vog-25p            = 0.1
ammo_vog-25                = 0.1
grenade_f1                = 0.1;(если поставить 1.0, то после смерти вы 100% найдете гранату F1)
grenade_rgd5            = 0.1
ammo_m209                = 0.1

;Медикаменты
bandage                    = 0.4;(если поставить 0, то после смерти вы не найдете у сталкера бинты)
medkit                    = 0.2;(если поставить 0, то после смерти вы не найдете у сталкера аптечку)
medkit_army                = 0
medkit_scientic            = 0.05;(если поставить 1, то после смерти вы 100% найдете у сталкера научную аптечку)
antirad                    = 0.2

;Еда
bread                    = 0.2;(если поставить 1, то после смерти вы 100% найдете у сталкера булку аптечку)
kolbasa                    = 0.2;(если поставить 0.02, то после смерти вы с 2% вероятностью найдете у сталкера колбасу)
conserva                = 0.1
vodka                    = 0.1
energy_drink            = 0.1

 

Как изменить фальшивые концовки...
Правим xr_effects.script:

function sar_monolith_miracle(actor, npc)
    --' Убил лидеров группировок
    if has_alife_info("mil_lukash_dead") and    -- При убийстве Воронина и Лукаша покажут видео
        has_alife_info("bar_voronin_dead")
    then
        game.start_tutorial("mov_desire_3")        -- "Я хочу править миром"
        return                                              
    end

    --' Много денег
    if db.actor:money() >= 50000 then            -- Если поменять 50000 на 500000, то при кол-ве денег 500000 покажут
        game.start_tutorial("mov_desire_2")        -- Видео "Хочу стать богатым"
        return
    end
    --' Хорошая репутация
    if db.actor:character_reputation() >= 1000 then    -- Если поменять на 100 то при репутации 100 у гг, покажут
        game.start_tutorial("mov_desire_1")            -- Видео "Хочу что-бы зона исчезла"
        return
    end

    --' плохая репутация
    if db.actor:character_reputation() <= -1000 then -- Если поменять на -100 то при репутации -100 у гг, покажут
        game.start_tutorial("mov_desire_4")             -- Видео "Хочу уничтожить человечество"
        return
    end

    game.start_tutorial("mov_desire_5")        -- Хочу стать бессмертным
end

 

Делается это так: в файле xr_effects.script ищем строку:

function after_credits(actor, npc)

и ниже находим вот что c:

execute("disconnect")

Меняем "disconnect" например на hud_crosshair 1
и все вместо того чтобы после концовок (похоже даже фальшивых) будет возможно продолжить игру...

Только осталось добавить level_changer (например на Припять и все freeplay работает.)

 

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

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


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

Данный урок довольно прост.


Для реализации сего дива нам понадобится парочка музыкальных треков (music_1, music_2...), предварительно разбитых на два моно канала и переведенных в OGG формат с частотой 44kHz(64kbps). В этом может помочь Adobe Audition 2.0(по крайней мере я ним пользуюсь).
Также есть еще один вариант: Если уж очень лень - Музычку можно вытащить из различных МОДов, обычно в каждом, разработчики, как правило, засовывают новую музыку, которая лежит в "gamedata\sounds\music".
И так берем наши OGG треки и засовываем, в выше указанную папку, gamedata\sounds\music, не забывая про то, что каждая дорожка должна состоять из левого и правого моно канала "magnitofon_l.ogg"- левый канал и "magnitofon_r.ogg"- правый!
Причем количество дорожек не ограничено .
Далее нам понадобится ui_mm_main.xml, который лежит в "gamedata\config\ui" и находим там вот такой текст:
<menu_sound random="0" >
        <!--whell_sound>car\apc_run</whell_sound>
        <whell_click>car\test_car_stop</whell_click-->
        
        <menu_music>music\Terrapack-Empty_noise</menu_music>
        
        <!--menu_music>music\guitar_2</menu_music>
        <menu_music>music\guitar_1</menu_music>
        <menu_music>music\guitar_3</menu_music-->
        
    </menu_sound>
И проводим с ним некоторые манипуляции:
1. В строчке
<menu_sound random="0" >
и цифру "0" меняем на число соответствующие количеству наших муз. композиций, правда на одну единицу больше.
2. Далее после строчки
<menu_music>music\Terrapack-Empty_noise</menu_music>
ниже, на ее примере прописываем новые композиции
<menu_music>music\music_1</menu_music>
И в конечном итоге получится примерно так
    <menu_sound random="7" >
        <!--whell_sound>car\apc_run</whell_sound>
        <whell_click>car\test_car_stop</whell_click-->
        
        <!--whell_sound>car\apc_run</whell_sound>
        <whell_click>car\test_car_stop</whell_click-->    
        <menu_music>music\Terrapack-Empty_noise</menu_music>
        <menu_music>music\music_1</menu_music>
        <menu_music>music\music_2</menu_music>
        <menu_music>music\music_3</menu_music>
        <menu_music>music\music_4</menu_music>
        <menu_music>music\music_5</menu_music>
        <!--menu_music>music\guitar_2</menu_music>
        <menu_music>music\guitar_1</menu_music>
        <menu_music>music\guitar_3</menu_music-->
        
    </menu_sound>
Сохраняем. И теперь при каждом входе в главное меню у нас будут играть рандомно 7 музыкальных композиций!

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

  • http://www.amk-team.ru/forum/uploads//ratings/thumb_up.png × 2

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


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

Эффект критического ранения.
Авторы: amk

1. Создаем файл effect_blood.script и записываем туда следующее:
lite_treshold = 0.05 -- насколько должно уменьшиться здоровье с предыдущего обновления чтоб экран окрасился в красный
crit_treshold = 0.30 -- насколько должно уменьшиться здоровье с предыдущего обновления чтоб ГГ начало шатать
drop_item_on_crit_prob = 0.20 -- вероятность того что ГГ выронит оружие
effector_power_coeff = 0.7
prev_health = -1
chk_h_t = 0

function wounded_pp_update()
  if (chk_h_t or 0) < time_global() then
    chk_h_t = time_global()+1000
    if prev_health > (db.actor.health + lite_treshold) then
      level.add_pp_effector("fire_hit.ppe", 2011, false)
      local effector_power = (prev_health - db.actor.health)*100*effector_power_coeff
      level.set_pp_effector_factor(2011, effector_power)
      if prev_health > db.actor.health + crit_treshold then
        level.add_cam_effector("camera_effects\\fusker.anm", 999, false, "")    
        local snd_obj = xr_sound.get_safe_sound_object([[actor\pain_3]])
        snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 1.0)
        if math.random() < drop_item_on_crit_prob then
          local active_item = db.actor:active_item()
          if active_item and active_item:section() ~= "bolt" and active_item:section()~= "wpn_knife" then
            db.actor:drop_item(active_item)
          end
        end
      end
    end
    prev_health = db.actor.health
  end
end

2. Далее открываем bind_stalker.script:
после строчек:


function actor_binder:update(delta)
  object_binder.update(self, delta)
  local time = time_global()
  game_stats.update (delta, self.object)

пишем:

effect_blood.wounded_pp_update()

 

 

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

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


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

Все мы знаем, что движок ведёт себя, как капризная невеста, и вылетает от малейшего чиха.

1. Синтаксические ошибки в коде. Как правило, лог при этом содержит что-то вроде

attempt to index global '<имя файла>' (a nil value)

т.е. движку не удалось скомпилить модуль и его значение (модуля) равно нулю

 

2. Ошибки времени выполнения Lua. Лог обычно содержит указание ошибки модуль и строку, в которой ошибка произошла. Типа такого:

LUA error: ....k.e.r. 1.0004\gamedata\scripts\<имя файла>.script:<номер строки>: attempt to index global 'npc' (a nil value)

К типичным ошибка относятся попытки вызвать несуществующий метод класса (и вообще индексировать что-бы то ни было несуществующим ключом) или, к примеру, конкатенация строки с nil.

 

3. Ошибки времени выполнения самого игрового движка. Лога обычно нет, т.е. движок тихо слетает, сам в лог ничего не пишет, а забуферизированный до этого момента лог теряется. Иногда, правда, что-то в логе есть, но бывает это весьма редко. Ошибки движка вызваны неправильным использованием функций самого движка. Например, попытка заспавнить объект с несуществующей секцией.

Кроме того скрипты выполняются с прекомпиляцией, поэтому для запуска изменённого скрипта надо как минимум перегрузить сохранёнку. Кстати, для справки. в отличие от скриптов файлы конфигураций подгружаются уже при старте программы ещё до загрузки сохранения. Посему для тестирования изменения в файлах конфигураций надо перезапускать программу.

 

Довольно часто надо проверить некий фрагмент кода, заспавнить объект, проверить некую синтаксическую конструкцию и т.п.

1. Пишу скрипт и получаю вылет игры без лога, если влез в один из заранее прекомпилируемых файлов и сделал там тупую синтаксическую ошибку.

2. Выношу скрипт в отдельный файл и получаю вылет игры с до ужаса информативным сообщением в лог-файле "attempt to index global 'my_cool_script' (a nil value)".

Это значит, что тупую синтаксическую ошибку я сделал в файле my_cool_script.script

Можно до хрипоты говорить о пользе предварительной синтаксической проверки, но как часто мы её не делаем, не так ли?

3. Наконец-то умнею и проверяю скрипт на вшивость заранее. Запускаю игру, загружаю уровень.

загружаю уровень...

загружаю уровень......

Получаю вылет игры, лезу в лог и ищу в конце коротенькое сообщение, из которого следует, что надо поменять пару символов или добавить/стереть одну строчку.

4. Меняю скрипт, повторяю всё заново, скрипт отрабатывает, но делает не то, что мне надо. Чтобы изменения в скрипте вступили в силу, надо перегрузить уровень.

так что повторяю пп.3 и 4, пока не получу то, что мне было нужно.

 

Вот для частичного решения этой проблемы в своё время был сделан специальный тестовый полигон, который позволяет менять и вызывать определённый скрипт, не выходя из игры. Кроме того, часть ошибок (а именно ошибки Lua) блокируются и не приводят к вылетам. Полигон этот сэкономил мне кучу времени.

 

[spoiler=Тестирование скриптов без обрушения и перезапуска игры]Тестирование скриптов без обрушения и перезапуска игры

Ключевыми элементами являются две функции из стандартной библиотеки Lua:

dofile - позволяет загрузить и выполнить как chunk внешний файл.

pcall - позволяет выполнить произвольную функцию в т.н. защищённом режиме. Это значит, что любая ошибка интерпретатора Lua не выйдет за пределы функции, вызванной таким образом. Напомню, что обычно любая ошибка времени выполнения Lua передаётся хост-программе, т.е. игре, и вызывает её вылет.

 

Ну и собственно рецепт пилюли

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

 

    local res, err = pcall(my_proxy.start_chunk_from_file)
    get_console():execute(res and "Succesfull!" or string.gsub(err, " ", "_")) --имитация тернарного оператора

pcall возвращает два значения. Первое - результат запуска. Если все прошло пучком, то true. Второе - добавочное значение с сообщением об ошибке, если ошибка была. Иначе nil.

 

файл my_proxy.script содержит всего одну функцию

 

function start_chunk_from_file()
    local chunk, err = dofile("..\\gamedata\\scripts\\test.lua")
    if err then
        get_console():execute("err="..tostring(string.gsub(err, " ", "_")))
    end
end

dofile принимает имя файла со скриптом, загружает его и выполняет как функцию. Путём экспериментов я выяснил, что текущим каталогом Lua считает папку bin. Так что если хотим держать скрипт там, где и все остальные, то пишем путь относительно этой папки "..\\gamedata\\scripts\\test.lua".

test.lua - это отлаживаемый скрипт.

Обработка ошибок осуществляется аналогично pcall.

 

 

Так можно не выходя из игры и даже не перегружая уровень копаться в скрипте test.lua и запускать его по много раз, существенно менее рискуя обрушить игру. Особенно удобно, если есть два компа и сетка. В этом случае даже Alt-Tab не нужен. Редактируешь файл по сети на одном компе, а запускаешь в загруженной игре на другом.

Само-собой, если сделаем что-то, что фатально затронет игровую логику или что-то из ошибок категории 3, то обрушение может всё равно случиться. Сразу или в другом месте. В основном, в таких случаях уже ничего не поделаешь. Однако, довольно часто можно свести потенциальную ошибку времени выполнения движка к ошибке Lua. Например, если вызвать функцию get_console():execute(<аргумент>) с нулевым аргументом, то получим вылет без лога. Однако ничто не мешает сделать так:

get_console():execute("value="..obj)

В этом случае сначала будет выполняться конкатенация двух строк. Если obj будет равно nil, то получим ошибку Lua, а её тестовый полигон не пропустит, и обрушения игры не будет.

 

И ещё. Это всё работает для ТЧ. Для ЧН мне наладить такой же полигон не удалось. Что-то там изменено в движке, что вызывает у него аллергию на функцию pcall.

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

  • http://www.amk-team.ru/forum/uploads//ratings/wrench_orange.png × 1

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


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


Материал из S.T.A.L.K.E.R. Inside Wiki.

Недавно решил поэкспериментировать с анимками НПС, и теперь выкладываю результаты моих опытов над "людьми". Разумеется, опытные модмейкеры все это давно знают – поэтому материал предназначен для новичков, которые еще не освоили как прописывать неписям разные прикольные анимки, а заодно и озвучку через логику. Все анимки взяты из файла state_lib.script. Анимки, которые имеются в движке, но не вписаны в указанный файл, не рассматриваются. Это тема для отдельной статьи. Озвучка взята из файла sound_script (папка misc). Конечно, хотелось использовать и звуковые темы не вписанные в этот файл, но имеющиеся в папке sounds - но с этим еще надо разобраться.


Вся изложенная ниже схема является единым целым и ее можно ставить в ltx–ный файл логики любому вашему НПС целиком. Она будет зациклена и повторяться по кругу если кое-где поставить другие варианты перехода от одной ремарки к другой.

[logic]
active = remark@base
danger = danger_condition
meet = meet
	[remark@base]
anim = hello_wpn
no_move = true
target = actor
meet = meet
on_actor_dist_le = 2| remark@sit
	[meet]
meet_state = 10|salut@esc_bridge_soldiers| 5|salut_free@esc_lager_killer
meet_state_wpn = 10|ward@cit_base_guard_talk_to_actor2| 5|probe_2@gar_bandits_seryi
victim = 10|actor
victim_wpn = 10|actor
use = true
use_wpn = true
meet_dialog    = escape_lager_guard_start_dialog

В базовой ремарке мой чувак использует анимку Волка - hello_wpn – одной рукой машет ГГ, другой держит ствол. Это начальная анимка, которая будет отрабатываться НПС, пока ГГ не подойдет на дистанцию встречи. В секции meet задается схема реагирования НПС при подходе к нему эктора. В строчке meet_state – реакция при подходе безоружного ГГ. На расстоянии 10 метров НПС отдает честь, затем встает в позицию «смирно» - руки по швам. Это анимка salut. Ближе 5 метров – тоже самое, дальше переходит в позицию «вольно». Это анимка salut_free.
В секции meet можно задавать и то, что НПС будет базарить при виде эктора. В моей схеме: «чего стоишь сталкер, подходи, будем разговаривать» (esc_bridge_soldiers) отдавая салют, и на второй дистанции - «разбежались сосунки и т.д». (esc_lager_killer) В строчке meet_state_wpn - реакция НПС если эктор с пушкой в руках. У меня в этой схеме он встает в позу ward – руки за спиной, голова наклонена вниз. Словом поза тюремщика или надсмотрщика (ward примерно так и переводится). В этой позе НПС на дистанции ближе 10 метров орет «повторяю для тупых - отошел к дальней стене камеры…» (cit_base_guard_talk_to_actor2), а если ГГ подойдет еще ближе - «ты щас сдохнешь падла, понял…» (gar_bandits_seryi) и еще несколько рандомных фраз, которые заданы звуковой темой gar_bandits_seryi. К начальной анимке также можно добавлять любую звуковую тему через строчку snd. В данной ремарке ее нет.

Переходим к следующей схеме. Так как все эти схему у меня завязаны вместе, то переход ко второй ремарке произойдет, когда ГГ подойдет к НПС на дистанцию ближе двух метров. Прописано этой в строчке on_actor_dist_le = 2| remark@sit

[remark@sit]
anim = sit_ass
snd = mil_guard_to_max
no_move = true
target = actor
meet = no_meet
;on_actor_dist_le = 2| remark@raciya
;on_timer = 30000| remark@ raciya
on_signal = sound_end| remark@raciya
danger = danger_condition

Итак, что делает НПС в этой ремарке. Сидит на заднице - sit_ass, орет - mil_guard_to_max – «макс, у нас тут проблема на хуторе нарисовалась, собирай народ…» В секции meet прописано отсутствие встречи, так как задано no_meet. Так что разговаривать с ГГ непись не будет. После отработки заданной звуковой темы идет переход к к ремарке remark@raciya. Сделано это через строчку on_signal = sound_end| remark@raciya. Переведу: на сигнал «конец звуковой темы» переходим к схеме remark@raciya.

Следующая схема.

[remark@raciya]
anim = choose
snd = bar_arena_public
no_move = true
target = actor
meet = meet@raciya
on_timer = 120000| remark@work
;on_actor_dist_ge = 35| remark@work
danger = danger_condition
	[meet@raciya]
meet_state = 7|binocular@val_escort_guards| 5|guard_rac@mil_pavlik_to_ara
meet_state_wpn = 7|hide_rac@mil_ara_ambush                                      
victim = 7|actor
victim_wpn = 7|actor
use = true
use_wpn = true
meet_dialog    = escape_lager_guard_start_dialog

Анимка choose – ГГ что-то высматривает: оглядывается по сторонам, прикладывает руку ко лбу, так же как это делам мы, когда смотрим вдаль против солнца. Звуковая тема – что то там из реплик на арене. При встрече – смотрит в бинокль (если он у него есть) и издевательски базарит - «скоро ты будешь работать обедом для мутантов» (в этой теме реплик несколько). На 5 метрах достает рацию (если есть) - анимка guard_rac и базарит реплики из темы предателя Павлика на милитари «все чисто можете подходить». При угрозе стволом - анимка hide_rac («сидит с рацией»), базар - «это засада, уходим» Через 120 секунд - переход к следующей ремарке: on_timer = 120000| remark@work.

[remark@work]
anim = caution
no_move = true
snd = mil_max_before_collect
target = actor
on_timer = 30000| remark@work2
meet = no_meet
danger = danger_condition

Анимка caution – ГГ слегка согнувшись, что-то внимательно высматривает на земле, руки прикладывает к коленям. А затем радостно сообщает - «ребята у нас появилась работа». Видимо, что-то высмотрел интересное. Через 30 секунд - снова переход.

[remark@work2]
anim = search
no_move = true
snd = mil_collect_phrase3
target = actor
on_timer = 30000| remark@zombied
meet = no_meet
danger = danger_condition

Анимка search - поиск, только более развернутый. ГГ встает на колени или на корточки и начинает что-то искать. Что он при этом произносит – узнаете, когда послушаете. Через 30 секунд переход к схеме зомби.

[remark@zombied]
anim = trans_zombied
snd = pri_followers_leader_phrase1_1
no_move = true
target = actor
on_timer = 60000| remark@wounded
meet = meet@zombied
danger = danger_condition
	[meet@zombied]
meet_state =  5|trans_0@hail
meet_state_wpn    = 5|trans_1@hail
victim        = 5|actor  
victim_wpn    = 5|actor
use            = true
use_wpn        = true
meet_dialog    = escape_lager_guard_start_dialog

Анимка trans_zombied - падает на колени, головой двигает вверх-вниз. trans_1 - также стоит на коленях, только головой вращает по кругу. trans_0 – то же самое, только более энергичней. Или наоборот - извиняюсь если перепутал.

Схема раненый. Тут все понятно.

[remark@wounded]
anim = wounded_heavy_3
snd = help_heavy
target = actor
meet = no_meet
on_timer = 30000| remark@dinner
danger = danger_condition

wounded_heavy_3 – это анимка тяжелораненого. (есть еще и другие анимки раненого). Чувак скрючившись, грохнется на землю. Но на ней не остается, а тут же встает и бежит в сторону в денжере. Что и понятно – здоровье то у него норм. Остальные неписи видевшие как чувак упал, так же срываются в денжере с места. Ищут того, кто «стрелял». Не удивляйтесь, но так они запрограммированы.

Схема обед.

[remark@dinner]
anim = sit_knee
no_move = true
target = actor
meet = meet@dinner
danger = danger_condition
on_actor_dist_ge = 15| remark@dynamite
	[meet@dinner]
meet_state    = 5|eat_bread@wait| 3|eat_energy@wait
meet_state_wpn    = 5|eat_kolbasa@wait| 3|eat_vodka@val_escort_dead
victim = 8|actor
victim_wpn = 8|actor
use = true
use_wpn = true
meet_dialog    = escape_lager_guard_start_dialog

sit_knee - чувак сидит на заднице, опираясь на руку. eat_bread, eat_kolbasa, eat_energy, eat_vodka - тут я думаю ничего объяснять не надо. Чувак хавает и пьет. Пригубив водки, произносит – «пусть земля тебе будет пухом» При отходе эктора на дистанцию больше 15 метров - переход к схеме динамит. Звуковая тема wait – это пауза, в которой непись ничего не говорит.

[remark@dynamite]
anim = dynamite
no_move = true
target = actor
meet = no_meet
on_timer = 30000| remark@claim
danger = danger_condition

dynamite – закладка динамита. Как это выглядит – помните долговца на милитари у стены с динамитом?

[remark@claim]
anim = claim
snd = esc_wolf_thanks
target = actor
meet = meet@claim
danger = danger_condition
on_timer = 60000| remark@story

Анимка claim - НПС подзывает ГГ рукой. snd = esc_wolf_thanks - здесь НПС произносит фразу волка: «меченый теперь тебе проход в лагерь открыт, подходи».

[meet@claim]
meet_state    = 7|refuse@mil_collect_phrase5| 5|probe_2@mil_collect_phrase6
meet_state_wpn    = 7|backoff@gar_dm_bandit_demand          
victim        = 7|actor  
victim_wpn    = 7|actor
use            = true
use_wpn        = true
meet_dialog    = escape_lager_guard_start_dialog

Анимка refuse - непись пожимает плечами и произносит mil_collect_phrase5 - «не срать». probe_2 - судя по сопровождающим ее звукам (независимо от прописанной мной звуковой темы) – это анимка Круглова (его манипуляции с прибором, а может Сахарова - впрочем, это не важно). Если у вашего НПС будет в руках оружие - то смотреться она будет куда интереснее, так как выглядит будто непись проверяет свой ствол, совершая массу интересных движений. Фраза mil_collect_phrase6 - «опа – с нами новое мясо».
backoff - обычная анимка. Непись начинает махать стволом в разные стороны – типа убери ствол, меченый. Фраза - gar_dm_bandit_demand - «бабки артефакты гони», «ты че козел не врубаешься», «гони бабло или бошку отстрелим». Так как тема рандомная (с окончанием rnd в имени темы в файле sound_script – то и фраз несколько)

[remark@story]
anim = mode_shlem
no_move = true
target = actor
meet = meet@story
danger = danger_condition
on_actor_dist_ge = 30| %+passage_to_story_end%
on_info = {+passage_to_story_end} remark@story_end
	[meet@story]
meet_state    = 10|probe@wait| 5|probe_1@hail    
meet_state_wpn    = 10|probe_2@wait| 5|suicide@mil_crazy
victim = 10|actor
victim_wpn = 10|actor
use = true
use_wpn = true
meet_dialog    = escape_lager_guard_start_dialog

mode_shlem - анимка то ли Круглова, то ли Сахарова. Непись будет что то вертеть в руках. probe_1 – тоже самое что и probe_2 , только здесь он плечами вроде бы не дергает. suicide - самоубийство. Советую посмотреть – тем более с озвучкой mil_crazy. probe - укороченный вариант probe_2 и probe_1

[remark@story_end]
anim = probe_3
no_move = true
snd = agr_doctor_1        
target = actor
on_signal = sound_end| remark@base
;on_timer = 180000| remark@ base
meet = no_meet
danger = danger_condition
	[danger_condition]
ignore_distance = 10

probe_3 - интересная анимка (похоже что кругловская)- чувак срывается с места в панике, затем сгибается как будто от боли, хватается за голову. agr_doctor_1 - базар доктора в тайнике стрелка.
Теперь поясню строчки
on_actor_dist_ge = 30| %+passage_to_story_end%
on_info = {+passage_to_story_end} remark@story_end

Когда эктор отойдет от НПС дальше чем 30 метров, ГГ выдается инфопоршень passage_to_story_end. После его получения - on_info - произойдет переход к базовой ремарке. Сам инфопоршень необходимо регистрировать в соответствующих файлах. Так как мой НПС находится на кордоне, то поршень я сунул в файл info_l01escape. Сообственно инфопоршень в строчке on_actor_dist_ge писать не обязательно(я его использовал только для примера) - можно просто поставить имя следующей ремарки - и в нужный момент произойдет переход. Но инфопоршень может понадобиться для других случаев.

Как я уже говорил в начале, схему можно сделать полностью зацикленной. Нужно лишь в тех блоках, где идет переход к следующей схеме через on_signal поставить таймер или дистанцию. Почему так - не знаю. Но у меня по второму кругу схема стопорилась на тех блоках, где шел переход через on_signal = sound_end|. По таймеру же все прекрасно крутится. Схема из второй части - как раз зацикленная.

P.S. : Кажется понял почему у меня стопорилась схема при использовании перехода on_signal = sound_end|. Дело в том, что если в имени звука, по завершении которого схема должна перейти к новому блоку стоит флажок seq, то он вроде как отыграется только один раз (если в этой теме нет дополнительных реплик). Следовательно по второму кругу он просто не будет срабатывать, а значит и схема застопорится. Так что для этого нужно ставить звук в имени которого в файле sound_script есть флажок rnd. Тема mil_guard_to_max как раз с флажком seq (и реплика только одна - без вариантов). Потому здесь (в схеме sit) она и будет стопориться на втором круге, если не заменить тему на другую. Но это еще надо проверить. Закоментированные строчки - пред которыми стоит ; - может смело выкидывать - это остатки проб разных вариантов.


Еще одна схема. На этот раз в нее добавлены еще постэффекты.

[logic]
active = remark@base
danger = danger_condition
meet = meet
	[remark@base]
anim = hello_wpn
no_move = true
target = actor
meet = meet
on_actor_dist_le = 2| remark@punch
danger = danger_condition

С первой ремаркой все понятно. Переход ко второй на дистанции ближе 2 метров.

[remark@punch]
anim = punch
snd = cit_jail_guard_sneer
meet = meet@punch
target = actor
on_signal = sound_end| %=run_cam_effector(fatigue)%
on_timer = 60000| remark@doctor_wakeup  %=run_postprocess(deadcity_wake:1777:false)%  
danger = danger_condition
	[meet@punch]
meet_state    = 5|hide_s_left@wait| 4|hide_s_right@wait
meet_state_wpn    = 5|backoff2@threat_back
victim = 10|actor
victim_wpn = 10|actor
use = true
use_wpn = true
meet_dialog    = escape_lager_guard_start_dialog

punch – анимка удара рукой (или прикладом). Так как я не специалист по боксу, то не скажу точно как именно называется этот удар с правой в челюсть. Если поставите ее в meet_state_wpn на дистанции 2 метра - ГГ получит реальный удар в морду прикладом ствола. Так как я эксперементировал на своем торговце - то он (будучи безоружным) бил чисто кулаком. А если вместо запуска анимации камеры %=run_cam_effector(fatigue)% поставите запуск функции %=killactor%, то НПС кинется вас убивать.
hide_s_left* и hide_s_right - непись присядет с разворотом ствола вправо или влево. backoff2 - более веселая анимка backoff. НПС покажет ГГ что-то вроде фака, перед тем как помахать стволом и при этом скажет что-то весьма нелицеприятное. %=run_cam_effector(fatigue)% - это вызов анимации камеры /fatigue/ из папки anims. Земля уйдет из под ног ГГ. Ненадолго. Сработает сразу же после окончания фразы cit_jail_guard_sneer. А ровно через минуту от начала работы схемы – запуск постпроцесса %=run_postprocess(deadcity_wake:1777:false)% и переход к следующей схеме.
deadcity_wake – это постпроцесс, который должен был использоваться в Мертвом городе, если бы разрабы МГ все таки доделали. Если не видели - обязательно посмотрите.Сначала черный экран, затем прояснение с раздвоением картинки и красным фоном.

В следующей схеме идет продолжение постпроцесса – первые 15 секунд. Потом его остановка: on_timer = 15000| %=stop_postprocess(1777)%.

[remark@doctor_wakeup]
anim = doctor_wakeup
snd = cit_doctor_start_dlg
meet = meet@doctor_wakeup
target = actor
on_timer = 15000| %=stop_postprocess(1777)%
on_timer2 = 180000| remark@prisoner
danger = danger_condition
	[meet@doctor_wakeup]
meet_state    = 3|sleep@cit_jail_guard_sleep| 2|sleep_sit@wait
meet_state_wpn    = 3|wounded_zombie@wait
victim = 10|actor
victim_wpn = 10|actor
use = true
use_wpn = true
meet_dialog    = escape_lager_guard_start_dialog

Начальная анимация - doctor_wakeup – доктор в мертвом городе. НПС склонится вниз – как будто над чьим то телом (по задумке – над меченым) и начнет базарить. Но совсем не то, что стоит у меня в строчке snd. Видимо, данная анимка завязана со звуком, и иначе не идет. Фразу прописанную мною - cit_doctor_start_dlg – нпс произнесет потом. Обе озвучки длинные – та, что идет с анимкой – монолог доктора в подземелье агропрома в тайнике Стрелка – типа, «что ж ты меченый в растяжку полез, сам же придумал эту хрень…» Моя озвучка - cit_doctor_start_dlg – неиспользованный монолог доктора в мертвом городе. Через 180 секунд – завершение схемы и переход к следующей.

Схема – пленный.

[remark@prisoner]
anim = prisoner
snd = agr_krot_fear
meet = meet@prisoner
target = actor
on_timer = 60000| remark@base
danger = danger_condition
	[meet@prisoner]
meet_state    = 5|help_me@gar_dm_newbie_no_money
meet_state_wpn    = 5|hands_up@agr_dont_shoot
victim = 10|actor
victim_wpn = 10|actor
use = true
use_wpn = true
meet_dialog    = escape_lager_guard_start_dialog
	[danger_condition]
ignore_distance = 10

Анимка – prisoner – пленный. Помните Шустрого у бандитов? Вот это она и есть. Фраза - agr_krot_fear – не смотря на то, что в названии звуковой темы имя Крота, орет ее Шустрый: типа братцы я тут, спасите.
help_me - машет рукой сидя на одном колене и орет, что у него "нет денег" - gar_dm_newbie_no_money. hands_up - руки кверху и орет "не убивай дяденька" (или типа того) - agr_dont_shoot.
Через 60 секунд возврат к базовой ремарке.


В файле state_lib – большая библиотека анимок. Я успел попробовать только часть. У одного бармена их 12. Правда, из пяти опробованных мной сработала только одна bar_sleep - НПС положит голову на руки сложенные перед лицом и будет спать стоя.

Анимки - barman_talk_freу, barman_shock, barman_wait_danger, barman_walk_danger - никакого эффекта не дали. Видимо, они работают только на бармене. Остальные пробуйте сами.
Анимка psy_pain – пораженный пси-излучением. Чувак сядет на колени, начнет трясти головой и бить себе руками по голове.
psycho_pain – вроде бы тоже самое, только чувак обхватывает голову руками и так сидит.
Анимки psy_shoot, psy_armed, psycho_pain, psycho_shoot – пока остаются на стадии исследования. Так как с ними либо глючит, либо вылетает.


------------------------------------------------------------------------
erlik
------------------------------------------------------------------------



  • http://www.amk-team.ru/forum/uploads//ratings/bf.gif × 3
  • http://www.amk-team.ru/forum/uploads//ratings/thumb_up.png × 1
  • http://www.amk-team.ru/forum/uploads//ratings/wrench_orange.png × 2

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


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


Периодически на различных форумах появляются посты с просьбами объяснить, как можно сделать иконки для игры STALKER. Так как в рамках форума достаточно долго и проблематично это объяснить, а оставлять без ответа желающих тоже не хочется решил написать что-то вроде "мануала" про то как создаю иконки я.

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



формат - exe (в архиве PDF), вес - 14.15 Мб (распакованный 17.6 Мб), объём - 72 страницы с картинками.


Мануал для тех кто страдает "хроническим дефицитом времени" или просто не хочет глубоко вникать в принципы работ с текстурами, а между тем сделать, что-либо хочет. Мануал, про скажем так - "полуавтоматический" способ создания "бампа" с помощью которого можно добиться вполне приличных результатов.
Не претендую на могучее мастерство в этой области, также не претендую на авторство методы я лишь добавил кое какие мелочи, мысли, наработки от себя и написал данный мануал.



формат - 7z SFX (в архиве PDF), вес - 20,88 Мб (распакованный 25.3 Мб), объём - 74 страницы с картинками.


Как-то столкнулся с задачей создания на текстуре оружия "насечек" (вы наверное видели такие "насечки" на некоторых вариантах глушителей, рукояток, стволов и т.д.).
Немного "покумекав" сообразил, как это можно сделать максимально просто, при этом не пожертвовав качеством.
Это не столько «узкоспециализированная инструкция» про создание «насечек», сколько показательная инструкция, про то, что можно решить достаточно «геморройные» и нудные графические задачи, достаточно простым способом. И соответственно решил поделиться данным способом. )




формат - 7z SFX (в архиве PDF), вес - 10.67 Мб (распакованный 12.0 Мб), объём - 28 страницы и все с картинками.


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


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

Вообщем разобрались сегодня как располагать\передвигать карты локаций на глобальной карте.

Вот статья - Скачать (1 МБ) (ссылка прямая)
Авторы: Руся, Xmk

Если что-то непонятно - пишем smile.gif

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

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


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

Сразу оговорюсь, что вся информация ниже предназначена для ТЧ. В ЧН экспортировано пространство имён

io и проблемы как-бы и нет вовсе.

 

Имеются экспортированные в Lua функции log(string), error_log(string) и flush(). И эти функции не работают! По крайней мере никому до сих пор не удалось заставить их работать в релизной версии движка.

Так что общепринятым способом является использование консоли. Известно, что всё, что пишется в консоль, пишется одновременно и в лог-файл. Файл этот находится в месте, определяемом переменной $logs$, которая в свою очередь находится в файле fsgame.ltx.

Для управления консолью имеется класс CConsole. Экземпляр этого класса можно получить с помощью глобальной функции get_console().

В этом классе нет функций, которые позволили бы вывести на консоль (и соответственно в лог) произвольную строку. Однако имеется функция execute(string), которая предназначена для выполнения команд консоли. Разумеется, выполнить можно только те команды, которые поддерживает движок. Если команда не поддерживается, то в консоль выводится сообщение:

! Unknown command: <команда_которую_пытался_выполнить>

Вот так и можно вывести некий текст. Пишем его вместо команды и он попадёт в консоль и в лог в составе сообщения об ошибке. Т.е. можно выводить сообщения так:

get_console():execute(<моё_сообщение>)

У метода есть недостатки.

Первое, сообщение не должно быть командой. Обычно с этим не возникает проблем, но всё-таки следить надо.

Второе, если в сообщении есть пробельные символы, то движок воспринимает как команду только последовательность символов до первого такого символа. Остальное - это как бы аргументы команды. В лог выведется только "команда", а остальное пропадёт. Есть два способа для решения этой проблемы. Первый состоит в замене всех пробелов на другой символ, например знак подчеркивания. Тогда команда вывода в лог будет выглядеть так:

get_console():execute(string.gsub(<моё_сообщение>, " ", "_"))

Функция string.gsub(str, ptrn, rep) заменяет в строке str все вхождения строки ptrn на строку rep.

Второй способ решения проблемы заключается в использовании функции команды консоли load. Эта команда загружает сейв с определённым именем. Если такого нет, то в лог выводится ещё и имя не найденного сейва.

get_console():execute("load ~~~ "..<сообщение>)

Поскольку файла, начинающегося с "~~~" точно не существует, то это сработает всегда. Сообщение в логе в этом случае выглядит так:

! Cannot find saved game ~~~ моё сообщение

При таком способе в сообщении могут быть пробелы и они отобразятся нормально. Кроме того, нет риска, что сообщение окажется командой консоли.

Недостаток метода - лишнее обращение к жёсткому диску на предмет проверки существования сейва. Кроме того, этот метод аккуратно обходится только с пробелами. Прочие специальные символы конвертируются в пробелы.

Полезно также упомянуть про команду консоли "flush", которая позволяет принудительно записать на диск всё, что на данный момент было выведено в консоль. Это может быть весьма полезно, поскольку при краше игры лог потеряется, если только не был записан этой командой. Так что вот такую строчку рекомендуется ставить перед потенциально опасными местами:

get_console():execute("flush")

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

 

Но есть и ещё один способ, который может компенсировать эти недостатки. Оказывается, можно перенаправить консольный вывод движка в текстовый файл. После этого в этот файл можно выводить что угодно функцией Lua print(). Описание этой функции можно посмотреть на сайте Lua. Скажу только, что в сочетании с функцией форматирования текста string.format() так можно вывести в файл совершенно произвольно оформленный текст.

Для реализации метода можно запускать игру через батник примерно такого содержания:

XR_3DA.exe -nointro >> log.txt

 

У метода замечен только один недостаток. Нет никакой возможности принудительно записать файл на диск. Функция Flush осталась в неэкспортированном пространстве имён io. Хотя в отличие от консольного лога этот файл записывается на диск сам, но из-за буферизации часть его может таки пропасть в случае краша игры. При нормальном выходе из игры всё естественно запишется как надо.

 


  • http://www.amk-team.ru/forum/uploads//ratings/bf.gif × 1
  • http://www.amk-team.ru/forum/uploads//ratings/wrench_orange.png × 2

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


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

Спросите для чего это надо? Отвечу коротко и надеюсь понятно.


Для более удобного совмещения модов.
1) Создадим файл dialogs_zver_kopdon.txt далее его с помощью тотал командера( или чем вы пользуетесь) меняем окончание
.txt на .xml и получаем готовый файл. dialogs_zver_kopdon.xml
Открываем его и вставляем в него следующее:
<?xml version="1.0" encoding="windows-1251" ?>
<string_table>




</string_table>

Всё наш файл готов к работе, здесь можно прописывать русскоязычные диалоги.
Помещаем его по адресу .....\S.T.A.L.K.E.R\gamedata\config\text\rus
Что бы его игра увидела нужно его прописать. Открываем файл localization.ltx
который находится по адресу ....\S.T.A.L.K.E.R\gamedata\config
Находим строку

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

и в самом конце списка через запятую прописываем dialogs_zver_kopdon
Всё, можно работать!!!

 

2) Создадим файл zver_kordon_dialogs.xml пропустим создание, так как оно подробно расписано выше.
Откроем файл и и вставим:

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





</game_dialogs>

Файл готов к работе. Здесь формулу диалога. Положим его по адресу:
...\S.T.A.L.K.E.R\gamedata\config\gameplay
Прописываем что бы видела игра по адресу
...\S.T.A.L.K.E.R\gamedata\config\system.ltx
Находим строку: [dialogs] в конце списка прописываем zver_kordon_dialogs
Всё, работаем!!!

3) Создадим файл инфо где будут прописываться инфопоршни.
Создадим файл info_zver_kordon.xml
Откроем файл и вставим:

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

<game_information_portions>




</game_information_portions>

Файл готов к работе.Положим его по адресу:
...\S.T.A.L.K.E.R\gamedata\config\gameplay
Прописываем что бы видела игра по адресу
...\S.T.A.L.K.E.R\gamedata\config\system.ltx
Находим строку: [info_portions] в конце списка прописываем info_zver_kordon.xml
Всё, можно работать!!!

4) Про файл скрипт, он тоже нам нужен в квестописании.
просто создаём файл zver_1.script и помещаем его по адресу:
....\S.T.A.L.K.E.R\gamedata\scripts
Всё, можно работать!!!

И как бонус создние файла из серии character_desc_......xml
Создадим файл character_desc_zver.xml

Откроем файл и вставим:

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

<xml>



</xml>

Файл готов к работе.Здесь мы прописываем профили неписей. Положим его по адресу:
...\S.T.A.L.K.E.R\gamedata\config\gameplay
Прописываем что бы видела игра по адресу
...\S.T.A.L.K.E.R\gamedata\config\system.ltx
Находим строку: [profiles] в конце списка прописываем character_desc_zver
Всё, работаем!!!

 

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

  • http://www.amk-team.ru/forum/uploads//ratings/thumb_up.png × 3
  • http://www.amk-team.ru/forum/uploads//ratings/wrench_orange.png × 1

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


Ссылка на сообщение
Поделиться на других сайтах
 n6260   
<visual>actors\stalker_neutral\stalker_neutral_1_face_1</visual> - Вано

<visual>actors\stalker_neutral\stalker_neutral_1_face_2</visual> - Костоправ

<visual>actors\stalker_neutral\stalker_neutral_1_face_3</visual> - Тремор

<visual>actors\stalker_neutral\stalker_neutral_2_face_1</visual> - Кардан

<visual>actors\stalker_neutral\stalker_neutral_2_face_2</visual>

 

<visual>actors\stalker_neutral\stalker_neutral_2_face_3</visual> - Гаваец

<visual>actors\stalker_neutral\stalker_neutral_2_face_5</visual> - Лоцман

<visual>actors\stalker_neutral\stalker_neutral_2_face_6</visual> - Гонта

<visual>actors\stalker_neutral\stalker_neutral_2_face_7</visual> - Зверобой

 

<visual>actors\stalker_neutral\stalker_neutral_3_face_1</visual> - Борода

 

<visual>actors\stalker_dolg\stalker_dolg_1_face_1</visual> - Зулус

 

<visual>actors\stalker_dolg\stalker_dolg_3_face_1</visual> - Шульга

 

<visual>actors\stalker_neutral\stalker_neutral_nauchniy_face_3</visual> - Азот

 

<visual>actors\stalker_bandit\stalker_bandit_3_face_1</visual>  - Сыч

<visual>actors\stalker_bandit\stalker_bandit_3_face_2</visual> - Ной

<visual>actors\stalker_bandit\stalker_bandit_3_face_3</visual>

 

<visual>actors\stalker_monolith\stalker_monolith_1_face_1</visual> - Командир монолитовцев на Юпитере

 

<visual>actors\stalker_nebo\stalker_nebo_2_face_1</visual> - Новиков

 

<visual>actors\stalker_freedom\stalker_freedom_1_face_1</visual> - Флинт (он же Сорока)

 

<visual>actors\stalker_neutral\stalker_neutral_1</visual> - сталкер в куртке

<visual>actors\stalker_neutral\stalker_neutral_2</visual>

<visual>actors\stalker_neutral\stalker_neutral_3</visual>

<visual>actors\stalker_neutral\stalker_neutral_4</visual>

 

<visual>actors\stalker_neutral\stalker_neutral_2_mask</visual>

 

<visual>actors\stalker_neutral\stalker_neutral_nauchniy</visual>

 

<visual>actors\stalker_dolg\stalker_dolg_1</visual>

<visual>actors\stalker_dolg\stalker_dolg_2</visual>

<visual>actors\stalker_dolg\stalker_dolg_3</visual>

<visual>actors\stalker_dolg\stalker_dolg_4</visual>

 

<visual>actors\stalker_merc\stalker_merc_2</visual>

 

<visual>actors\stalker_merc\stalker_merc_4</visual> - наемник в экзе

 

<visual>actors\stalker_bandit\stalker_bandit_3_mask</visual>

 

<visual>actors\stalker_bandit\stalker_bandit_1</visual>

<visual>actors\stalker_bandit\stalker_bandit_2</visual>

 

<visual>actors\stalker_bandit\stalker_bandit_4</visual>

 

<visual>actors\stalker_soldier\stalker_soldier_2</visual>

<visual>actors\stalker_soldier\stalker_soldier_3</visual>

<visual>actors\stalker_soldier\stalker_soldier_4</visual>

 

<visual>actors\stalker_freedom\stalker_freedom_2_mask</visual>

 

<visual>actors\stalker_freedom\stalker_freedom_1</visual>

<visual>actors\stalker_freedom\stalker_freedom_2</visual>

<visual>actors\stalker_freedom\stalker_freedom_3</visual>

<visual>actors\stalker_freedom\stalker_freedom_4</visual>

 

<visual>actors\stalker_monolith\stalker_monolith_1</visual>

<visual>actors\stalker_monolith\stalker_monolith_2</visual>

<visual>actors\stalker_monolith\stalker_monolith_3</visual>

<visual>actors\stalker_monolith\stalker_monolith_4</visual>

 

<visual>actors\stalker_zombied\stalker_zombied_1</visual>

<visual>actors\stalker_zombied\stalker_zombied_2</visual>

<visual>actors\stalker_zombied\stalker_zombied_3</visual>

<visual>actors\stalker_zombied\stalker_zombied_4</visual>

 

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

  • http://www.amk-team.ru/forum/uploads//ratings/bf.gif × 2
  • http://www.amk-team.ru/forum/uploads//ratings/wrench_orange.png × 2

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


Ссылка на сообщение
Поделиться на других сайтах
Базовый урок , ничего сложного, смарт-терейны не переписывал, сами будете добавлять....
Назовем нашу группировку (айди) grom
1) Открываем файл gamedata\configs\creatures\game_relations.ltx
;названия группировок (порядок должен совпадать с communities_relations)
communities        = actor, 0, bandit, 1, dolg, 2, ecolog, 3, freedom, 4, killer, 5, army, 6, monolith, 7, monster, 8, stalker, 9, zombied, 10, grom, 11

пишем группировку за следующей как в таблице, и указываем номер, по счету из таблицы, после последней запятая не нужна!!!

[communities_relations]
;              |actor|bandit| dolg|ecolog|freedom|killer|    army|monolith|monster|stalker| zombied|grom
;===============================================================================
====================
actor         =     0,     0,     0,     0,       0, -1000,       0,   -5000,  -5000,      0,   -5000
bandit        =     0,  5000,-5000,     0,  -5000,     0,   -5000,   -5000,  -5000,  -1000,   -5000, -5000
dolg          =     0, -5000, 5000,     0,  -5000,     0,       0,   -5000,  -5000,      0,   -5000, 0
ecolog        =     0,     0,    0,     0,      0,     0,       0,       0,      0,      0,       0, 0, 0, 0, 0
freedom       =     0, -5000,-5000,     0,   5000,     0,       0,   -5000,  -5000,      0,   -5000, 0
killer        = -1000,     0,    0,     0,      0,  1000,   -5000,   -5000,  -5000,      0,   -5000, 0
army            =     0, -5000,    0,     0,      0, -5000,    1000,   -5000,  -5000,      0,   -5000, 0
monolith      = -5000, -5000,-5000,     0,  -5000, -5000,   -5000,    1000,  -5000,  -5000,    1000, -5000
monster       = -5000, -5000,-5000,     0,  -5000, -5000,   -5000,   -5000,      0,  -5000,   -5000, -5000
stalker       =     0, -1000,    0,     0,      0,     0,       0,   -5000,  -5000,      0,   -5000, 5000
zombied       = -5000, -5000,-5000,     0,  -5000, -5000,   -5000,    1000,  -5000,  -5000,    1000, -5000
grom        =  -5000, -1000,    0,     0,      0,     0,       0,   -5000,  -5000,      0,   -5000, 5000

Добавляем группировку в таблицу, прописываем отношение к другим группировкам, НЕ ЗАБЫВАЕМ добавлять по еще одному значению по вертикали!

;(порядок должен совпадать с communities_relations)
[communities_sympathy]
actor            =        0.0
bandit            =        0.0
dolg            =        0.0
ecolog            =        0.0
freedom            =        0.0
killer            =        0.0
army            =        0.0
monolith        =        0.0
monster            =        0.0
stalker            =        0.0;0.01
zombied            =        0.0
grom                =         0.0

Сюда тоже добавляем в таком же порядке...

2) Создаем профайл сталкера в gamedata\configs\gameplay\character_desc_general.xml (ну или другой, который вы прописали, или на уровнях)

<specific_character id="grom spez" team_default = "1">
    <name>GENERATE_NAME_stalker</name>
    <icon>ui_inGame2_merc_4</icon>
    <map_icon x="1" y="0"></map_icon>
    <bio>Опытный сталкер. Детальная информация отсутствует.</bio>

    <class>grom_specnaz</class>
    <community>grom</community> <terrain_sect>stalker_terrain</terrain_sect>
    <snd_config>characters_voice\human_03\killer\</snd_config>

    <rank>60</rank>
    <money min="5000" max="10000" infinitive="0"/>
    <reputation>0</reputation>

    <visual>actors\stalker_merc\stalker_merc_4</visual>
    <supplies>
      [spawn] \n
      
      wpn_fn2000 \n
      ammo_5.56x45_ap = 1 \n
      wpn_usp \n
      ammo_11.43x23_hydro = 1 \n
      grenade_f1 = 4 \n

#include "gameplay\character_items_nd.xml"
#include "gameplay\character_food.xml"
#include "gameplay\character_drugs_4.xml"
#include "gameplay\character_drugs_sci.xml"
#include "gameplay\character_drugs_mil.xml"
    </supplies>
#include "gameplay\character_criticals_4.xml"
#include "gameplay\character_dialogs.xml"
  </specific_character>

3) в файле gamedata\configs\gameplay\npc_profile.xml создаем класс нпс, вписываем его айди из профайла и класс.

<character id="grom spez">
        <class>grom_specnaz</class>
    </character>

В файле gamedata\configs\creatures\spawn_sections_general.ltx создаем секцию для спавна:

[ваше название секции]:stalker
$spawn = "respawn\ваше название секции"
character_profile = grom spez -айди нпс_профайла
spec_rank = novice
community = grom ---группировка как в профайле

4) Добавляем в скрипт death_manager.script нашу группировку:

local community_list = { "stalker", "dolg", "freedom", "bandit", "army", "zombied", "ecolog", "killer", "monolith","grom"}

5) В файле gamedata\configs\misc\death_items_by_communities.ltx
Добавляем секцию с группировкой, и продукты для нее...., теоретически можно не трогать этот файл, все будет по дефолту и вылетов не будет тоже, проверял.

6) Чтоб название было по русски в любом файле с текстами

<string id="grom">
<text>Вольный сталкер</text>
</string>

7) Осталось заспавнить, берем секции из spawn_sections_....

 

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

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


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

В этой статье я не буду писать тупые и неинтересные уроки, которые есть в любом факе по модмейкерству, а буду помещать лишь интересные (на мой взгляд) уроки и небольшие статьи


Добавим в файл config\gameplay\encyclopedia_zone.xml новую статью:

<!-------------------------------- Activation - Basic ----------------------------->
<article id="zone_anomalies_activation_basic" name="zone_anomalies_activation-basic" group="Anomalies">
<texture x="500" y="150" width="100" height="100">ui_icon_photo</texture>
        <text>enc_zone_anomalies_activation_basic</text>
    </article>

Здесь:


article id - внутреннее имя статьи, именно на него ссылаются в файлах игры
name - имя статьи, отображаемое в игре, подгружается из строкового массива
texture - картинка и её позиция в статье, в данном случае мы использовали обычный белый шум
text - текст статьи, отображаемый в игре, подгружается из строкового массива
 
Добавим например в config\gameplay\info_l01escape.xml (инфопорции уровня "Кордон") ссылку на получение статьи - скажем, к трупу у туннеля, при обыске которого выдается информация о аномалиях в туннеле (вы его обнаруживаете, проходя второе спецзадание от Сидоровича). Найдем эти строки и дополним их:

Так как в статье у нас есть такое поле:

<text>enc_zone_anomalies_activation_basic</text>

Да и название тоже не написано прямо, а ссылается на определенную строку, то добавим этот самый text в config\text\rus\string_table_enc_zone.xml, в нашем случае:

<string id="enc_zone_anomalies_activation-basic">
<text>Активация - базис</text>
</string>
<string id="enc_zone_anomalies_activation_basic">
<text>С артефактами связана, помимо всего прочего, ''(ну, и так далее, там большой текст)''...</text>
</string>

Дополнительно.
Чтобы статья добавлялась при получении определенного задания, в ..._task.xml (вместо ... стоит название уровня) нужно прописать конструкцию вида:

<article>название_задания_descr</article>

<!-- труп у аномалии -->
<info_portion id="esc_tutorial_dead_novice">
<article>tutorial_moving_anomaly</article>
<article>zone_anomalies_activation_basic</article>
</info_portion>
Главное - никогда не путайте article id, name и text статьи. Я в данном примере это сделать легко. Лучше называйте их непохожими друг на друга названиями.


В файле gamedata\scripts\xr_kamp.script находим:

-- играть на гармошке
-- 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

Раскомментируем эти строки, для этого удалим --. перед строками, исключения строка "-- играть на гармошке"
Затем нужно добавить музыку. Например сталкерам, открываем папку gamedata\sounds\characters_voice\human_01\stalker\music и добавляем туда свою музыку. Имя файла должно быть harmonica_* (где *, 1, 2, 3 и т.д.). Формат файла должен быть *.ogg. Таким же образом добавляем музыку остальным группировкам.


При заходе на экран главного меня муз. заставка будет выбираться случайно из добавленных вами.
1. В директорию gamedata\sounds\music положить два канальных ogg-файла с нужной музыкой, например: my_music_l.ogg (левый канал) и my_music_r.ogg (правый канал)
2. Открыть файл gamedata\config\ui\ui_mm_main.xml, найти в нем строку:

<menu_sound random="0" >

и заменить на:

<menu_sound random="1" >

3. В этом же файле найти строку:

<menu_music>music\wasteland2</menu_music>

и ниже нее выставить следующую строку:

<menu_music>music\my_music</menu_music>

4. Сохранить файл.
5. Если требуется вставить больше муз. заставок, то в параметре random укажите их количество.

!!! Возьмите на заметку !!!
в строке <menu_sound random="0" >
вместо 0 указывайте не количество композиций, а количество композиций - 1, то есть, если вы добавили скажем еще одну мелодию, к той, что была по дефаулту у вас получится примерно так:

<menu_sound random="1" >
	<menu_music>music\wasteland2</menu_music>
<menu_music>music\my_music</menu_music>


1. Кладём ролик в папку gamedata\textures\sleep\. Собственно, в любую папку, лишь бы она была в каталоге textures. Просто в sleep лежат ролики сна в оригинале.
имя файла любое, формат ogm, а разрешение ролика вроде можно сделать любое. Я не стал заморачиваться и просто скопировал существующий ролик сна с монолитом.
2. Озвучку ролика кладем по той-же схеме в папку в корневом каталогу gamedata\sounds\. У меня папка называется my_sleep. Имена файлов для левого и правого канала должны выглядеть так

my_sleep_sound_l.ogg

и

my_sleep_sound_r.ogg

длина звуков может быть разной и вообще говоря не совпадать с длиной ролика.
3. Правим файл gamedata\config\ui\ui_movies.xml. Добавляем туда что-то в этом роде:

    <my_dream>
        <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>my_sleep\my_sleep_sound</sound>
            <pause_state>on</pause_state>
            <function_on_stop>sleep_manager.stopper</function_on_stop>
            <video_wnd x="0" y="0" width="1024" height="768" stretch="1">
                <texture x="0" y="1" width="512" height="286">sleep\dream_sarcofag</texture>
            </video_wnd>
        </item>
    </my_dream>

Название тега my_dream - это моё имя для сна. Если я верно всё понимаю, то вся эта фигня описывает окно, в котором играется видеоролик.
4. Теперь собственно добавляем сон. Правим файл gamedata\config\misc\dream.ltx.
Там есть секции с именами [regular_dream#] где # - это номера снов. Сейчас там есть regular_dream1, regular_dream2 и regular_dream3. Добавляем секцию

[regular_dream4]
dream       = my_dream
probability = 40
type        = happy

параметры:
dream - это ранее заданное имя сна (в нашем случае my_dream).
probability - ясное дело, что нужно для вычисления вероятности появления именно этого сна. Но я пока не понял по какому алгоритму она вычисляется на основе этого параметра. Я просто сделал число побольше, дабы протестировать побыстрее.
type - может быть nightmare, normal и happy. По названию вроде понятно, что это. Но на что влияет пока не ясно.
 
5. Ну и завершающий этап. В этом же файле в секцию [dreams] к параметру regular добавляем к списку новый сон regular_dream4. Вроде такого:

regular = regular_dream1, regular_dream2, regular_dream3, regular_dream4

Тестируем... Опа! Новый сон. Поскольку я звуки взял случайно, то при этом в левом ухе у меня орет кот, а в правом играет мрачный эмбиент =)
Ну и естественно работать будет только при установленном АМК. Что там именно сделано, для того чтобы сон вообще был, я пока не разбирался.



  • http://www.amk-team.ru/forum/uploads//ratings/wrench_orange.png × 2

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


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

Вот решил добавить статейку на STLKER mod-портал по партиклам ссылка

Надеюсь меня за это не расстреляют :ny_ph34r:

Пока еще неполная и есть повторения с другой статьи.

Может кому поможет... :ny_thumbsup:

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


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

Заходишь по адресу

gamedata\configs\scripts, далее определяешься с одной из локаций, далее там есть папка anomaly в ней открываешь любой файлик и дописываешь в строках:
artefacts - после запятой название своего арта (типа af_cristall)
coeff - коэффициент выпадания арта, также добавляешь после запятой (целое число - означает количество артов для спавна)
в принципе вот и всё что надо, можно еще в строке start_artefact подставить "имя" своего арта тогда первым заспавненым артом будет твой!
Другие строки не трогаем!
Пример, что в результате должен получить:
artefacts = af_my_art, af_fireball
coeff = 3, 3
start_artefact = af_my_art

PS. поделись артами для общего дела, если чё пиши в личку!

 

Изменено пользователем World_Stalker
Оформил

  • http://www.amk-team.ru/forum/uploads//ratings/thumb_up.png × 2
  • http://www.amk-team.ru/forum/uploads//ratings/wrench_orange.png × 1

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


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

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

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

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

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

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

Войти

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

Войти

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

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

×