Режим не очень серьёзный. Глаза - глазами, а на слух неписи как собаки, прям! На зверьё прозрачный режим ГГ не действует. Это - пример. Браз что-то сделал, надеюсь лучше, чем у меня.
Создаём пустой файл в \scripts\trans_outfit.script и создаём две функции:
function transparent_gg() --назовём её для памяти - "хулиганы зрения лишают!"
local fov1, range1, id, obj_around, alife_obj, dist_act_npc
if db.actor == nil then
return nil
end
--если ГГ голый
if db.actor:item_in_slot(7) == nil then
fov1 = 150
range1 = 80
--если на ГГ одет костюм новичка
elseif db.actor:item_in_slot(7):section() == "novice_outfit" then
fov1 = 1
range1 = 1
--если на ГГ одет другой броник
else
fov1 = 150
range1 = 80
end
--задача предыдущего куска проанализировать, что надето на ГГ и установить
--соответствующие угол обзора и дальность зрения
--
--дальше перебор ВСЕХ объектов в игре по его id
for id = 1, 65534 do
obj_around = level.object_by_id(id) -- создаём онлайн объект
if obj_around ~= nil and IsStalker(obj_around) then --если есть такой и это сталкер
--создаём серверный объект, соответствующий онлайновому
--сам обескуражен, что не смог определить дистанцию по онлайновому объекту
--ну, наверное, мало рыл
alife_obj = alife():object(id)
if alife_obj then
--определяем дистанцию между ГГ и неписем
dist_act_npc = db.actor:position():distance_to(alife_obj.position)
end
if dist_act_npc <= 120 then --отличаясь огромным человеколюбием я решил не бросать
--в беде ослеплённых сталкеров и восстанавливать им зрение в кольце 120-150 метров.
--ну жалко их, болезных
if obj_around then - проверка обязательна иначе может быть
--вылет при убийстве вражины
obj_around:set_fov(fov1) --портим неписю угол зрения
obj_around:set_range(range1) --портим неписю дальность зрения
end
else
if obj_around then --если непись в кольце 120-150м восстанавливаем зрение
obj_around:set_fov(150)
obj_around:set_range(80)
end
end
end
end
end
--а это стартёр нашей функции "хулиганы зрения лишают!"
--тупой до бесконечности, когда я подоткнулся к таймерам Николая - диалоги начали мелькать.
--но мы ж не таймеры разучиваем. Принцип прост. Вызов ф-ции подтыкаем в апдейт биндера актёра
--и каждый раз наращиваем, предварительно созданную, глобальную переменную на 1 единичку.
--на 50 раз обнуляем глобалку и запускаем "хулиганы зрения лишают!"
function timer_trans()
timer_transparent = timer_transparent + 1
if timer_transparent >= 50 then
timer_transparent = 0
transparent_gg()
end
end
------------------------------------------------------------------------------
Далее открываем файл \scripts\_g.script и внем прописываем свою глобалку:
dev_debug = false
sim_debug = false
mus_vol = 0
amb_vol = 0
timer_transparent = 0 --вот она, родная!
-------------------------------------------------------------------------------
Ну и последний штрих: подключить моторчик, чтобы пятидесятки считались, и "хулиганы
зрения лишают!" запускалась один раз на 50 апдейтов биндера.
Открываем \scripts\bind_stalker.script
ищем функцию апдейта function actor_binder:update(delta)
и так скромненько пристраиваем ей в хвостик свой доморощенный таймер
pda.fill_sleep_zones()
trans_outfit.timer_trans() -- функция из другого файла вызывается с префиксом имяфайла.
-- загрузка мода(постоянное обновление)
if mod_update() then
sgm_loader.sigerous_mod_main()
end
end
-----------------------------------------------
Всё в игре находим/обдираем/покупаем костюм новичка и пробуем инвизибл вар!
|
открываем файл: scripts\surge_manager.ltx
и меням параметры:
local START_MIN_SURGE_TIME -------- минимальное время до первого выброса
local START_MAX_SURGE_TIME ------ максимальное время до первого выброса
local MIN_SURGE_TIME -------------------- минимальное время между выбросами
local MAX_SURGE_TIME ------------------ максимальное время между выбросами
Формат: ЧЧ*ММ*СС игрового времени
|
В файл: \scripts\bind_stalker.script
После:
function actor_binder:update(delta)
object_binder.update(self, delta)
Добавить вот эту строчку:
if db.actor then news_manager.send_tip(db.actor,db.actor:game_vertex_id().." "..db.actor:position().x.." "..db.actor:position().y.." "..db.actor:position().z,0,mutant_hunter,10000,nil,"Gvertex X Y Z") end
Координаты будут выводиться в новости. Писк только напрягает - так выключи звук, поди модишь чего, та звук и не нужен.
|
Хочу поделиться советом, как избежать ошибки, приводящей к вылету (на которую сам часто напарывался).
Надо проверить наличие предмета, и что-то сделать.
Допустим, надо выяснить какой броник надет на ГГ и изменить какие-то параметры.
честно пишем:
local outfit_in_slot=db.actor:item_in_slot(7)
if outfit_in_slot~=nil and outfit_in_slot:section_name()=="чегототам" then
полагая, что LUA проверит первое условие, и , если ГГ голый не будет проверять второе. Однако LUA честно проверит оба условия, а потом сделает вывод true или false. Вот, а теперь представим, что ГГ голый.
Первое условие nil
Второе условие можно интерпретировать так nil:section() -т.е попытку применить функцию объекта к пустоте. Краш!!! Попытка смешать французское с нижегородским в данном случае приводит к печальным результатам! А как?
local outfit_in_slot=db.actor:item_in_slot(7)
if outfit_in_slot~=nil then --если голый валим отсюда, а не узнаём покрой пиджака
if outfit_in_slot:section_name()=="чегототам" then
....................
end
end
|
В файле: scripts\release_body_manager.script
Строки:
IDLE_AFTER_DEATH = 40000 --через 40 секунд после смерти, труп помечается на удаление
body_max_count = 15 --максимальное количество трупов
|
В файле: ui_main_menu.script
Ищем следующую функцию:
function main_menu:OnButton_credits_clicked()
Заменяем ее содержимое на:
local text
local vid
local gvid
local a = vector()
local text
a = db.actor:position()
vid = db.actor:level_vertex_id()
gvid = db.actor:game_vertex_id()
text = "Позиция:\\nX= "..a.x.."\\nY= "..a.y.."\\nZ= "..a.z.."\\nlevel_vertex= "..vid.."\\ngame_vertex_id= "..gvid
news_manager.send_tip(db.actor, text, nil, nil, 30000)
|
Функция проверки денег ГГ:
Добавляем в скрипт такую функцию, либо создаем новый скрипт в папке gamedata\scripts\
В скобках после math.floor указываем нужное кол-во денег
Также операторы для предпоследней строки:
==
|
равно
|
>=
|
больше или равно
|
<=
|
меньше или равно
|
~=
|
Не равно
|
<
|
Меньше
|
>
|
больше
|
function Имя_Функции()
local money = math.floor(Кол-во денег)
return db.actor:money()ОПЕРАТОРmoney
end
Использование прекондишна:
<dialog id="Dialog_1"> - id диалога
<precondition>ИМЯ_Скрипта.ИМЯ_Функции</precondition> - проверка денег
<phrase_list> - ветки диалога
<phrase id="1">
...
</phrase>
</phrase_list>
</dialog>
|
файл: scripts\travel_manager.script
Функция:
function get_price_by_distance(distance)
return math.ceil(distance/50)*50
end
distance - расстояние
50 - коэфициент
|
Создаем скрипт, например scripts\new_script.script
В него вставляем следующие функции:
-- Тут мы проверяем, получали ли мы раньше инфопоршень info_new_level
-- И если мы его не получали, то нам отмечается переход, и выдается этот инфопоршень
-- Нужно это для того, чтобы мы получали Отметку только один раз
function level_changer()
if not has_alife_info("info_new_level") then
otmetit_perehod()
db.actor:give_info_portion("info_new_level")
end
end
function otmetit_perehod()
for i=1,65534 do
local obj = alife():object(i)
if obj then
if obj:name() == "Название 1-го левел чэнджера" then
level.map_add_object_spot_ser(obj.id,"level_changer_up","Подпись 1")
elseif obj:name() == "Название 2-го левел чэнджера" then
level.map_add_object_spot_ser(obj.id,"level_changer_up","Подпись 2")
--elseif .....
end
end
end
Название берётся из поля name level_changer'а в all.spawn;
Подпись - например, "На Кордон".
Далее, в bind_stalker.script после function actor_binder:update(delta) надо написать new_script.level_changer()
и в файле info_portions.xml зарегистрировать наш инфопоршень, добавив строку
<info_portion id="info_new_level"></info_portion>
|
10. Убираем персонажа
function del_nik()
local id, obj, kto
for id=0, 65535 do
obj = alife():object(id)--вот здесь
if obj then
if IsStalker(obj) then
kto = obj:section_name()
if (kto == "nikitka") then
alife():release(alife():object(id), true)
end
end
end
end
news_manager.send_tip(db.actor,"Персонаж удален",0,mutant_hunter,10000,nil,"Тест инфо")
end
|
local npc_id = get_story_object_id("nikitka")
if npc_id ~= nil then
alife():release(alife():object(npc_id), true)
end
|
В файле scripts\travel_manager.script
Ищем:
function uni_traveler_precond(actor, npc)
local squad = get_object_squad(npc)
if squad ~= nil and squad:commander_id() ~= npc:id() then
return false
end
if npc:character_community() == "bandit" then
return false
end
if level.name() == "jupiter_underground" then
return false
end
Закомментируем проверку, что бандиты не могут водить, вот так:
function uni_traveler_precond(actor, npc)
local squad = get_object_squad(npc)
if squad ~= nil and squad:commander_id() ~= npc:id() then
return false
end
--теперь бандиты тоже водят по маршруту
--if npc:character_community() == "bandit" then
--return false
--end
if level.name() == "jupiter_underground" then
return false
end
|
scripts\xr_statistic.script
|
Функция db.actor:item_in_slot(<номер слота>)
Номер слота
|
Описание
|
2
|
Пистолеты (цифра 2 на клавиатуре)
|
3
|
Автоматы (цифра 3 на клавиатуре)
|
7
|
Бронежилет
|
9
|
Детектор
|
12
|
Шлем
|
Например:
проверка db.actor:item_in_slot(9):section() == "detector_scientific"
выдаст "true" если детектор Велес в слоте детекторa (9)
|
1. на F6 навешиваешь обработчик
db.actor:give_info_portion("твой_инфо")
2. на F7 навешиваешь обработчик
db.actor:disable_info_portion("твой_инфо")
8. на F8 навешиваешь обработчик
if db.actor:has_info("твой_инфо") then
news_manager.send_tip(db.actor,"инфо в игре",0,mutant_hunter,10000,nil,"Тест инфо")
end
if db.actor:dont_has_info("твой_инфо") then
news_manager.send_tip(db.actor,"инфо нет",0,mutant_hunter,10000,nil,"Тест инфо")
end
В игре: [ESC]=>[F6]=>[ESC]=>[ESC]=>[F7]=>[ESC]=>[ESC]=>[F8]=>[ESC] и смотри чего тебе новости вякают.
|
db.actor:disable_info_portion("Имя_Infoportion")
|
файл bind_stalker.script
function actor_binder:update(delta)
object_binder.update(self, delta)
function Имя_функции()
if db.actor:object(a) ~= nil then
if a == "ИД_ПРЕДМЕТА" and not db.actor:has_info("Имя_поршня") then
db.actor:give_info_portion("Имя_поршня")
end
end
end
|
function spawn_killers_pda()
local id, npc
if xr_conditions.is_alive(nil,nil,{"ID_NPC"}) then
id = "ID_NPC"
npc = get_story_object_id(id)
npc = alife():object(npc)
alife():create("wpn_rpg7", npc.position, npc.level_vertex_id, npc.game_vertex_id, npc.id)
end
end
|
function kill()
local oNpc = level.object_by_id(ID_NPC)
if oNpc and db.actor:id()~= ID_NPC then
oNpc:kill(oNpc)
end
|
function actor_have_items(first_speaker, second_speaker)
local n=3 -- количество
local count=0
db.actor:iterate_inventory(function (dummy, item) if item:section()=="твой предмет" then count=count+1 end end, nil)
if count>=n then
return true
else
return false
end
end
|
Это:
if <логическое выражение> then
return true
else
return false
end
Надо писать так:
return <логическое выражение>
Если true с false меняются местами, то так:
return not (<логическое выражение>)
|
local s_npc=alife():object(id) -- получаем по id серверный объект непися
if s_npc and s_npc.alive~=nil and not s_npc:alive() then
-- здесь он труп
end
Или так:
if s_npc and s_npc.health~=nil and s_npc:health()<=0 then
-- здесь он труп
end
|
function goodwill_to_stalker()
xr_effects.inc_faction_goodwill_to_actor(db.actor, nil, {"stalker", +3000})
end
|
float add_cam_effector(
string <имя анимации>, -- имя файла *.anm, адресуемого от папки anims
int <идентификатор>, -- произвольное целое число, которое можно использовать для удаления
boolean <зациклить>, -- проигрывать бесконечно
string <коллбек на окончание>) -- имя функции, которая выполнится по окончании
-- действия эффекта. Функция не принимает аргументов и не возвращает значений.
-- Не вызывается при принудительном завершении эффектора функцией remove_cam_effector.
-- Функция возвращает некое число, для каждого файла анимации своё. Зачем нужно - не знаю.
float add_cam_effector2(string, number, boolean, string) -- в целом тоже самое,
-- что и предыдущая функция. Видимая разница в том, что предыдущая смещала позицию камеры
-- от текущего положения актора, а эта сначала перемещает камеру актора в некую стартовую позицию.
void remove_cam_effector(number <идентификатор>) -- убрать эффектор с ранее заданным номером
----
void add_pp_effector(
string <имя постэффекта>, -- имя файла *.ppe, адресуемого от папки anims
int <произвольный идентификатор>, -- для дальнейшего удаления
boolean <зациклить>) -- проигрывать бесконечно
void set_pp_effector_factor(
int <идентификатор>, -- число, ранее заданное при установке эффекта
float <интенсивность>) -- (0, 1) -- интенсивность эффекта
void set_pp_effector_factor(
int <идентификатор>,
float <интенсивность>,
number <скорость изменения>) -- не до конца ясно, но вроде как скорость перехода
-- от текущего состояния к заданному. По какому принципу считается время перехода - непонятно
void remove_pp_effector(int <идентификатор>) -- убрать эффект
---
-- следующие две функции практически не используются. Задействованы незначительно только в ЗП
void add_complex_effector(
string <секция>, -- имя секции в system.ltx, с описанием эффекта
int <идентификатор>)
void remove_complex_effector(int <идентификатор>) -- отмена эффектора
|
if level.name() == <имя уровня> then
level.add_pp_effector(<имя постэффекта>, <какой-либо номер>, true)
end
Имя постэффекта указывать относительно папки anims
|
function new_teleport(actor, npc, p)
db.actor:set_actor_position(vector():set(X,Y,Z),GameVertex,LevelVertex) -- Позиция "Куда переместить ГГ"
level.add_pp_effector ("teleport.ppe", 333, false) -- Прокручиваемый эффект из папки anims
end
|
26. Включаем функцию printf
1. Заходим в _g.script и ищем функцию printf(fmt,...)
2. Закоментируйте все что внутри ее
3. Дальше в самый конец добавляем:
amk_dbg.log2(fmt)
amk_dbg.log2(string.format(fmt,...))
Чтобы получилось:
function printf(fmt,...)
--[[
local is_g = 0
local result = fmt
if debug == nil then
log(string.format(fmt,...))
return
end
local info_table = debug.getinfo(2)
local script_name = string.gsub(info_table.short_src, "%.script", "")
script_name = string.gsub(script_name, "gamedata\\scripts\\", "")
if scripts_to_print[script_name] == false then return end
script_name,is_g = string.gsub(script_name, "_g", "")
if is_g == 0 then
result = script_name..":("..info_table.currentline.."):"..fmt
else
result = fmt
end
log(string.format(result,...))
]]
amk_dbg.log2(fmt)
amk_dbg.log2(string.format(fmt,...))
end
4.Создаем файл amk_dbg.script и пишем в него:
function log(fmt, ...)
local msg = string.format(fmt, ...)
local msg_no_ws = string.gsub(msg, "%s", "_")
get_console():execute("load ~~~dbg:" .. msg_no_ws)
end
function log2(msg)
local msg_no_ws = string.gsub(msg, "%s", "_")
get_console():execute("load ~~~dbg:" .. msg_no_ws)
end
Все, функция восстановлена. Теперь можно смотреть что же там нам игра пишет
|
1. Качаем эту дллку: http://ifolder.ru/21002184
• | можно кататься в ЗП на машинках |
• | добавлены консольные команды: |
o | fov - угол обзора игрока |
o | ph_timefactor - скорость течения времени при просчете физики |
• | в ПДА можно добавлять свои разделы. ГГ будет получать инфопорцию при выборе нового раздела. |
• | разблокировано выкидывание из ящиков с помощью функций drop_item и drop_item_and_teleport |
• | убран вылет "cannot find rank for ..." при выкидывании оружия, не прописанного в mp_ranks |
• | добавлены глобальные функции |
log1(string) - нормальный вывод текста в консоль вместо нерабочей log
flush1() - запись выведенного в консоль текста на диск, вместо нерабочей flush
• | * в пространство имён level добавлены функции: |
level.get_target_dist() - возвращает float - расстояние до точки, на которую смотрит камера. Это то число, которое высвечивается под прицелом.
level.get_target_obj() - возвращает game_object - объект, на который смотрит камера. Если ни на кого, то возвращает nil.
• | в класс CUIStatic возвращена возможность вращать текстуру. Для этого добавлен метод: |
SetHeading(Frect) - угол вращения в радианах передаётся в поле x объекта-аргумента.
• | для актора добавлена возможность устанавливать колбек на получение хита |
|
Сделали ее Kolmogor и Malandrinus
2. Заходим в _g.script и находим function printf(fmt,...)
3. В этой функции меняем log на log1 чтобы получилось так:
function printf(fmt,...)
local is_g = 0
local result = fmt
if debug == nil then
log1(string.format(fmt,...))
return
end
local info_table = debug.getinfo(2)
local script_name = string.gsub(info_table.short_src, "%.script", "")
script_name = string.gsub(script_name, "gamedata\\scripts\\", "")
if scripts_to_print[script_name] == false then return end
script_name,is_g = string.gsub(script_name, "_g", "")
if is_g == 0 then
result = script_name..":("..info_table.currentline.."):"..fmt
else
result = fmt
end
log1(string.format(result,...))
end
|
function mutant_sim_attack()
alife():create("chimera_normal",vector():set(116.86434936523,-3.9353849887848,176.99018859863),1167207,138)
end
|
function spawn_one ()
if not db.actor:has_info("spawn_one")
then
alife():create("NPC",vector():set(-118.155,12.919,-138.009),116155,934)
db.actor:give_info_portion("spawn_one")
end
Тут мы перед спавном проверяем: если у ГГ отсутвует поршень Spawn_one, то мы заспавним NPC и выдадим ему этот самый инфопоршень. А если у нас уже есть инфопоршень - то спавн не произойдет
|
dialogs.relocate_item_section(second_speaker, "Предмет", "in")
|
function spawn_anom(anom_name,plosh,position,level_vertex_id,game_vertex_id,powers_a,time_danger
os)
local obj = alife():create(anom_name,position,level_vertex_id,game_vertex_id)
local pac = net_packet()
obj:STATE_Write(pac)
local game_vertex_id = pac:r_u16()
local distance = pac:r_float()
local direction = pac:r_u32()
local level_vertex_id = pac:r_u32()
local object_flags = pac:r_s32()
local custom_data = pac:r_stringZ()
local story_id = pac:r_s32()
local spawn_story_id = pac:r_s32()
local shape_count = pac:r_u8()
for i=1,shape_count do
local shape_type = pac:r_u8()
if shape_type == 0 then
local center = pac:r_vec3()
local plosh = pac:r_float()
else
local box = pac:r_matrix()
end
end
local restrikror_type = pac:r_u8()
local powers = pac:r_float()
local owner_id = pac:r_s32()
local on_off_mode_enabled_time = pac:r_u32()
local on_off_mode_disabled_time = pac:r_u32()
local on_off_mode_shift_time = pac:r_u32()
local offline_interactive_radius = pac:r_float()
local artefact_spawn_places_count = pac:r_u16()
local artefact_position_offset = pac:r_s32()
local last_spawn_time_present = pac:r_u8()
if pac:r_elapsed()~= 0 then
abort("left=%d",pac:r_elapsed())
end
pac:w_begin(game_vertex_id)
pac:w_float(distance)
pac:w_u32(direction)
pac:w_u32(level_vertex_id)
pac:w_u32(object_flags)
pac:w_stringZ(custom_data)
pac:w_s32(story_id)
pac:w_s32(spawn_story_id)
pac:w_u8(1)
pac:w_u8(0)
local sphere_center = vector()
sphere_center:set(0,0,0)
pac:w_vec3(sphere_center)
pac:w_float(plosh)
pac:w_u8(restrikror_type)
if powers_a ~= nil then
powers = powers_a
end
pac:w_float(powers)
if time_dangeros == nil then
owner_id = bit_not(0)
else
owner_id = time_dangeros
end
pac:w_u32(owner_id)
pac:w_u32(on_off_mode_enabled_time)
pac:w_u32(on_off_mode_disabled_time)
pac:w_u32(on_off_mode_shift_time)
pac:w_float(offline_interactive_radius)
pac:w_u16(artefact_spawn_places_count)
pac:w_u32(artefact_position_offset)
pac:w_u8(last_spawn_time_present)
pac:r_seek(0)
obj:STATE_Read(pac,pac:w_tell())
return obj
end
|
Создать погодные настройки, привязать их к локации в game_maps_single.ltx
Через скрипт:
if level:name()=="что-то" then
if level:get_weather()~="что-то" then
level:set_weather("что-то")
end
end
|
if has_alife_info("требуемая для выдачи квеста инфа") and not has_alife_info("инфа на выдачу квеста") then
db.actor:give_info_portion("инфа на выдачу квеста")
task_manager.get_task_manager():give_task("секция квеста")
end
|
Подойти к костру вплотную и выполнить вот такой код:
for i=1,65535 do
local s = sim:object(i)
if s then
local o = level.object_by_id(s.id)
if o then
local cf = o:get_campfire()
if cf and o:position():distance_to(cact:position()) < 5 then
cf:turn_off() -- turn_on
end
end
end
end
Гаснет не мгновенно и не полностью, просто меняет партиклы на "тление угольков с лёгким дымком"
|
function respawn()
local level_vertexes={
zaton = 1844793,
jupiter = 1422445,
pripyat = 477061
}
local game_vertexes={
zaton = {0,316},
jupiter = {317,665},
pripyat = {666,856}
}
local lname= "jupiter"
local gvn,gvx,lvx = game_vertexes[lname][1], game_vertexes[lname][2], level_vertexes[lname]
for i=1,1000 do
new_lv = math.random(1,lvx)
local pos = level.vertex_position(new_lv)
local new_gv = 0
local min_dist = 100000
for a = gvn, gvx do
g1 = game_graph():vertex(a):game_point()
if g1:distance_to(pos)<min_dist then
min_dist = g1:distance_to(pos)
new_gv = a
end
end
alife():create("wpn_ak74",pos,new_lv,new_gv)
pos = level.vertex_position(new_lv)
create_anomaly("zone_mine_electric",1,new_lv,new_gv,pos)
end
end
|
В файле gulag_general.script найти:
; Строка 52-53
"use = {=is_wounded} false, {!is_squad_commander} false, {=actor_enemy} false, {=has_enemy} false, {=actor_has_weapon} false, {=dist_to_actor_le(3)} true, false\n"..
"snd_on_use = {=is_wounded} nil, {=actor_enemy} nil, {!is_squad_commander} meet_use_no_talk_leader, {=actor_has_weapon} meet_use_no_weapon, {=has_enemy} meet_use_no_fight, {=dist_to_actor_le(3)} meet_use_no_default, nil\n"..
Заменить на:
"use = {=is_wounded} false, {=actor_enemy} false, {=has_enemy} false, {=actor_has_weapon} false, {=dist_to_actor_le(3)} true, false\n"..
"snd_on_use = {=is_wounded} nil, {=actor_enemy} nil, {=actor_has_weapon} meet_use_no_weapon, {=has_enemy} meet_use_no_fight, {=dist_to_actor_le(3)} meet_use_no_default, nil\n"..
|
В файле bind_stalker.script найти строки:
--' Апдейт саундменеджера
xr_sound.update(self.object:id())
После этих строк вставить эту:
actors_sound.play_sound()
Далее создаем в той-же папке файл actors_sound.script, и в него вставляем такие строки:
function play_sound()
local snd
if db.actor:object("predmet") then snd = [[Путь_до_звука_относительно_папки_sounds]]
end
if snd then
local snd_obj = xr_sound.get_safe_sound_object(snd)
snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector(), 1.0)
end
end
|
local stobj =alife():story_object(story_id_монстра)
if stobj then
if stobj:alive() then
--' Действия, если монстр жив
else
--' ... если мёртв
end
end
|
В файле news_manager.script ищем функции relocate_money и relocate_item. После строчки
--' Играем дефолтный звук
Допишем:
xr_sound.set_sound_play(actor:id(), "pda_tips")
|
treasure_manager.get_treasure_manager():give_treasure("ИМЯ_ТАЙНИКА")
|
Включение:
function screenshot_mode_on()
level.hide_indicators_safe()
local hud = get_hud()
hud:HideActorMenu()
hud:HidePdaMenu()
end
Выключение:
function screenshot_mode_off()
level.show_indicators()
end
|
1. Актор при старте игры сразу активирует спейс рестриктор с логикой zat_a1_logic.ltx
2. В этой логике вызывается функция damage_actor_items_on_start, которая собственно и меняет состояние предметов инвентаря:
function damage_actor_items_on_start(actor, npc)
local actor = db.actor
local obj = actor:object("helm_respirator")
if obj ~= nil then
obj:set_condition(0.8)
end
obj = actor:object("stalker_outfit")
if obj ~= nil then
obj:set_condition(0.76)
end
obj = actor:object("wpn_pm_actor")
if obj ~= nil then
obj:set_condition(0.9)
end
obj = actor:object("wpn_ak74u")
if obj ~= nil then
obj:set_condition(0.7)
end
end
Соответственно для противогаза (helm_respirator), брони (stalker_outfit), пистолета (wpn_pm_actor) и автомата (wpn_ak74u) - причем сугубо конкретных
|
local news_caption = game.translate_string("st_tip")
local texture = "ui_iconsTotal_weapons"
db.actor:give_game_news(news_caption, news_text, texture, 0, 15*1000)
play_snd_at_actor([[device\pda\pda_news]])
Где:
local news_caption = game.translate_string("st_tip") - заголовок "Сообщение"
local texture = "ui_iconsTotal_weapons" - иконка сообщения
db.actor:give_game_news(news_caption, news_text, texture, 0, 15*1000) - придется поставить первый цифровой параметр (задержка перед выводом сообщения) в ноль, так как нам нужно синхронизировать звук ПДА и сообщение
play_snd_at_actor([[device\pda\pda_news]]) - вывод звука ПДА
|
Зарегистрируем нашу функцию в файле bind_stalker.script:
Ищем:
function actor_binder:use_inventory_item(obj)
после второго end функции вставляем:
if obj~=nil then
новый_скрипт.on_use_item(obj)
end
(в конце должно получиться два end)
Далее создаем новый_скрипт.script и вставляем в него такую функцию:
function on_use_item(sect)
--Тут идет описнаие переменных
local actor=db.actor
local item_name=sect:section()
local actor_pos=db.actor:position()
local active_slot=db.actor:active_slot()
local active_item=db.actor:active_item()
local pistol_in_slot=db.actor:item_in_slot(2)
local rifle_in_slot=db.actor:item_in_slot(3)
local outfit_in_slot=db.actor:item_in_slot(7)
local helm_in_slot=db.actor:item_in_slot(12)
--C переменными закончено, дальше пишем наши колбеки на предметы
if item_name=="money_10" then
dialogs.relocate_money_to_actor(first_speaker, second_speaker, 100)
elseif item_name=="money_50" then
dialogs.relocate_money_to_actor(first_speaker, second_speaker, 500)
end
end
|
в функции CSurgeManager:end_surge файла scripts\surge_manager.script, после строки self:respawn_artefacts_and_replace_anomaly_zone() добавляем вызов своей функции спавна монстров, например такой:
function spawn_monster_after_surge ()
xr_effects.create_squad(<Сквад1>,<Смарт1>)
xr_effects.create_squad(<Сквад2>,<Смарт2>)
xr_effects.create_squad(<Сквад3>,<Смарт3>)
end
|
Функция set_weapon_drop_condition(item) в файле death_manager.script
По умолчанию выпадает оружие от 0.4 (40\100) до 0.8 (((0.0..0.4)+40)/40)
|
В файле scripts\xr_effects.script, функция actor_punch, закоментировать строку
db.actor:drop_item(active_item)
|
В файле configs\ui\map_spots.xml и configs\ui\map_spots_16.xml раскомментировать строки в разделе "Отряды":
<!-- <level_map spot="alife_presentation_squad_friend_spot"/> -->
...
<!-- <level_map spot="alife_presentation_squad_neutral_spot"/> -->
...
и т.д.
Заменить в файле scripts\sim_squad_scripted.script функцию sim_squad_scripted:get_squad_props() например на такую:
function sim_squad_scripted:get_squad_props()
local t = self.player_id
if t == "bandit" then
t = "Сквад Бандитов"
elseif t == "ecolog" then
t = "Группа Экологов"
elseif t == "killer" then
t = "Сквад Наемников"
elseif t == "dolg" then
t = "ui_st_name_dolg"
elseif t == "freedom" then
t = "Сквад Свободы"
elseif t == "stalker" then
t = "Группа Сталкеров"
elseif t == "army" then
t = "Отряд Военных"
elseif t == "monolith" then
t = "Отряд Монолита"
elseif t == "zombied" then
t = "Группа Зомбированных"
end
return t
end
|
В файле scripts\surge_manager.script в функции CSurgeManager:give_surge_hide_task, комментировать строки начинающиеся с task_manager.get_task_manager():give_task
|
--Установить метку на бармена Скадовска (story_id = zat_a2_stalker_barmen).
local obj_id = get_story_object_id("zat_a2_stalker_barmen")
level.map_add_object_spot(obj_id, "green_location", "Объект")
Удалить соответственно:
level.map_remove_object_spot(obj_id, "green_location")
|
Вариант #1:
--Проверка наличия продуктов в рюкзаке Актора
function actor_has_food_to_half_zombi(first_speaker, second_speaker)
if db.actor:object("bread") ~= nil and
db.actor:object("kolbasa") ~= nil and
db.actor:object("conserva") ~= nil
then return true
end
return false
end
Вариант #2:
function actor_has_needed_item()
local item_sections = {"Предмет"}
local needed = количество одинаковых предметов, ставится цифра без знаков
local count = 0
local item_section
local function calc(temp, item)
if item:section() == item_section then
count = count + 1
end
end
for k,v in pairs(item_sections) do
item_section = v
get_story_object("actor"):iterate_inventory(calc, actor)
end
return count >= needed
end
|
В файле scripts\release_body_manager.script в функции Crelease_body:try_to_release() после строк:
if (IsStalker(release_object) or IsMonster(release_object)) and not release_object:alive() then
Добавить:
--Снять координаты
local p=vector(),lv,gv
p.x=release_object.position.x
p.y=release_object.position.y
p.z=release_object.position.z
lv=releas e_ob ject.m_level_vertex_id
gv=release_object.m_game_vertex_id
--Спавн зомби
local random_number=math.random(1,100)
if math.random(1,100) < 15 then
random_number=math.random(1,100)
if random_number < 10 then
alife():create("sim_default_zombied_1",p,lv,gv)
end
if random_number >= 10 and random_number < 30 then
alife():create("sim_default_zombied_2",p,lv,gv)
end
if random_number >= 30 and random_number < 80 then
alife():create("sim_default_zombied_3",p,lv,gv)
end
if random_number >= 80 and random_number <= 100 then
alife():create("sim_default_zombied_4",p,lv,gv)
end
end
где if math.random(1,100) < 15 - спавн зомби с вероятностью 15%.
Выбор визуала зомби осуществляется также по вероятности:
10% - sim_default_zombied_1
20% - sim_default_zombied_2
50% - sim_default_zombied_3
20% - sim_default_zombied_4
|
Надо в скрипте xr_corpse_detection.script добавить предметы в таблицу.
|
Для НПС скрипт release_body_manager.script основные параметры:
IDLE_AFTER_DEATH - время после смерти НПС, в течении которого труп не удаляется
max_distanse - максимальное расстояние между ГГ и трупом на котором тело не удаляется
self.body_max_count - количество тел которое одновременно может находится в игре
Для монстров файл monsters.ltx параметры:
corpse_remove_game_time_interval - интервал времени для удаления тел
stay_after_death_time_interval - время в течении которого труп остается
При изменении этих параметров нужна новая игра.
|
ГГ необходимо выдать следующие инфопоршни:
db.actor:give_info_portion("jup_first_meet_made")
db.actor:give_info_portion("jup_b217_welcome_faded")
db.actor:give_info_portion("jup_b217_welcome_guide_talked")
db.actor:give_info_portion("jup_b217_pp_end_in_scene")
db.actor:give_info_portion("jup_b217_welcome_tech_talked")
db.actor:give_info_portion("jup_b217_guide_welcome_end")
db.actor:give_info_portion("jup_b217_tech_welcome_end")
db.actor:give_info_portion("jup_b217_tech_instruments_start")
db.actor:give_info_portion("jup_b217_stalker_tech_met")
|
В скрипте scripts\xr_effects.script есть функция scenario_autosave можно вызвать либо из другого скрипта либо из логики рестриктора, НПС и т.п. Аргумент - имя файла сохранения.
|
Функция kill_squad в скрипте xr_effects.script
|
alife():release(alife():object(item_id),true)
|
В файле scripts\bind_campfire.script раскомментировать блок строк после строки
function campfire_binder:update(delta)
|
В файле xr_statistic.script добавить свое оружие в таблицу weapons_table, иконка оружия будет браться из ui_actor_weapons.dds согласно координат upgr_icon_x, upgr_icon_y, upgr_icon_width, upgr_icon_height из файла конфигурации ствола.
|
Файл bind_stalker.script таблица с предметами награды mutant_hunter_achievement_items
|
Убедиться что двери заспавнены как physic_door
удалить в ph_door.script функции try_to_open_door и try_to_close_door строку
if true then return {} end
|
on_timer измеряется в мс (1с = 1000мс)
on_game_timer измеряется в с
Применение on_game_timer:
on_game_timer = 36000 | %+atack%
По истечению 1 часа персонаж будет получать инфопоршень, который будет считаться сигналом к атаке
Аналог из xr_condition:
time_shift
Проверка на заданный период времени
Время задается в минутах
Параметры: (time_shift:period_min)
time_shift - периодичность срабатывания
period - период срабатывания на котором мы получаем true
Примеры:
time_period(60:10) - возвращает true каждый час на протяжении первых 10 минут
|
Файл sim_squad_scripted.script
~580 строка
Замени:
for i = 1,random_count do
local random_id = math.random(1, #random_spawn)
self:add_squad_member(random_spawn[random_id], base_spawn_position, base_lvi, base_gvi,random_id)
end
на
self:add_squad_member(random_spawn[1], base_spawn_position, base_lvi, base_gvi,random_id)
for i = 2,random_count do
local random_id = math.random(2, #random_spawn)
self:add_squad_member(random_spawn[random_id], base_spawn_position, base_lvi, base_gvi,random_id)
end
|
В файле sr_light.script
if not forced then
--' Проверка по времени суток (ночью всегда включено)
local htime = level.get_time_hours()
if htime <= 4 or htime >= 22 then
light = true
end
|
|