XMK 24 Опубликовано 10 Мая 2009 Уроки от @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_outfitinv_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> вроде ни че не забыл... 2 2 6 Поделиться этим сообщением Ссылка на сообщение
XMK 24 Опубликовано 19 Июля 2009 (изменено) Эффект критического ранения.Авторы: 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() Изменено 20 Сентября 2014 пользователем World_Stalker Поделиться этим сообщением Ссылка на сообщение
XMK 24 Опубликовано 17 Августа 2009 (изменено) Вообщем разобрались сегодня как располагать\передвигать карты локаций на глобальной карте.Вот статья - Скачать (1 МБ) (ссылка прямая)Авторы: Руся, XmkЕсли что-то непонятно - пишем Изменено 20 Сентября 2014 пользователем World_Stalker Поделиться этим сообщением Ссылка на сообщение