Сталкер полезные функции

Обновлено: 02.07.2024

Выдача поршня вставляется под строку действия.
название скрипта.название функции

Примечание, что бы выдать два одинаковых предмета пишем

function название функции (first_speaker, second_speaker)
dialogs.relocate_item_section(second_speaker, "название предмета", "in",2)
end

Если надо больше меняем цифру 2 на нужную нам.
=========================================================================
ОТБИРАЕМ ПРЕДМЕТ У АКТОРА.
=========================================================================
function название функции(first_speaker, second_speaker)
dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "название предмета")
end

размещается в файлах скрипт

выдача поршня вставляется под строку действия
название скрипта.название функции

Примечание, что бы отобрать два одинаковых предмета пишем

function название функции(first_speaker, second_speaker)
dialogs.relocate_item_section_from_actor(first_speaker, second_speaker, "название предмета",2)
end

Если надо больше меняем цифру 2 на нужную нам.
=======================================================================
СПАВНИМ ВЕЩЬ В РЮКЗАК гг
=======================================================================
function название функции()
local obj = alife():create("ВЕЩЬ", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())
end

В диалог
название скрипта.название функции

имя скрипта.название функции

function название функции(first_speaker, second_speaker)
return first_speaker:object("название предмета")

= nil or
first_speaker:object("название предмета")

= nil or
first_speaker:object("название предмета")

имя скрипта.название функции

function название функции(first_speaker, second_speaker)
return first_speaker:money() >= 2000
end

имя скрипта.название функции

<-----------Вариант два-------------->
Использовал на ТЧ, но и в ЗП работает

function название функции()
return db.actor:money()>=10000
end
в диалог

имя скрипта.название функции

название скрипта.название функции

function название функции(npc, actor)
npc:kill(actor)
end

название скрипта.название функции
===========================================================================
ПРОВЕРКА КОЛ_ВА ОДИНАКОВЫХ ПРЕДМЕТОВ
===========================================================================
function название функции(first_speaker, second_speaker)
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

function название функции(first_speaker, second_speaker)
dialogs.relocate_money_to_actor(first_speaker, second_speaker, 2000)
end

"У ГГ хорошее здоровье"

function actor_good(first_speaker, second_speaker)
if db.actor.health > 0.75 or --уровень здоровья, при котором диалог уже будет появляться(от 0 до 1)
db.actor.radiation < 0.1 or -- уровень радиации,при котором диалог уже будет появляться(от 0 до 1)
db.actor.bleeding < 0.1 then --уровень кровотечения, при котором диалог уже будет появляться(от 0 до 1)
return true
end
return false
end

"определённая группировка враждебна к ГГ"

Код
function if_enemy_to_actor(first_speaker, second_speaker)
local npc = dialogs.who_is_npc(first_speaker, second_speaker)
local actor = dialogs.who_is_actor(first_speaker, second_speaker)
return xr_conditions.is_faction_enemy_to_actor(actor, npc, )
end

если надо когда группировка не враждебна к актору, то return not
если надо когда группировка друзья,то return xr_conditions.is_faction_friend_to_actor(actor, npc, )
когда нейтралы, return xr_conditions.is_faction_neutral_to_actor(actor, npc, )

прописываем в файле info_какойто.xml

В конце диалога после которого должна появиться новая ветка
название поршня

в начале новой ветки под id прописываем
название поршня
теперь новый диалог недоступен пока мы не прочтём первый
================================================================================
==========
ПОРШЕНЬ НА ЗАПРЕТ ДИАЛОГА ЕСЛИ В ПРЕДИДУЩЕМ МЫ ПОСТАВИЛИ УСЛОВИЕ ПО КОТОРОМУ ЕГО НЕ БУДЕТ
================================================================================
==========

прописываем в файле info_какойто.xml

В конце определяющего диалога ставим
название поршня

под id квеста(диалога) который не должен появиться прописываем
название поршня
Теперь диалог не появится.
===============================================================================

function gop_stop_actor(actor, npc)
local actor = db.actor
all_money_actor = actor:money()
if actor and npc then
dialogs.relocate_money(npc, all_money_actor, "out")
end
end
------------------------------------------------------------------------------------------
============================= ==========Телепортация актора===============================
Чтобы ГГ после диалога телепортировался в нужную точку, то можно воспользоваться функцией[code]
function teleport_actor(actor, npc, p)
local point = patrol(p[1])
local look = patrol(p[2])

db.actor:set_actor_position(point:point(0))
local dir = look:point(0):sub(point:point(0))
db.actor:set_actor_direction(-dir:getH())
end
Это функция есть в файле xr_effects.script. Как она работает? Как-то так (кусочек файла sr_cutscene.script):

По всей видимости можно вместо фигурных скобочек указывать нужные координаты класса вектор.

А можно просто воспользоваться функцие set_actor_position и set_actor_direction по отдельности. Первую- для установки позиции, вторая - для установки взгляда. Здесь вызов идет вот-так:

, а если проще, то можно писать просто координаты.
Эти функции работают ТОЛЬКО в пределах уровня на котором находиться ГГ.
---------------------------------------------------------------------------------------------------------

"Функции"
"Спавн НПС(или предмета)"
Код
function spawn_x14 ()
alife():create("Секция",vector():set(-7.32,-34.48,13.18),1542,2799)
end
---------------------------------------------
"Проверка на взятие предмета и выдача инфопоршня"
Функции типа "Проверка на взятие предмета. " я лично использую в квестах тегами
Код
<function_complete>файл.функция</function_complete>
Код
function search_weapon_complete1(actor, npc)
if db.actor

= nil then
return db.actor:object("wpn_vintorez")

= nil then
iTimer = time_global()+last --/ взводим таймер на остаток времени last
else
iTimer = time_global() + 7*1000 --/ взводим таймер например 7 сек.
end
end

=nil then
local hours = math.floor(last/3600000)
local minutes = math.floor(last/60000 - hours*60)
local seconds = math.floor(last/1000 - hours*3600 - minutes*60)
local text = string.format("%02d:%02d:%02d",hours,minutes,seconds) -- выводим время в формате 00:00:00
--local text=string.format("%.f",last/1000)
st:wnd():SetTextST(text)
end
else
if hud:GetCustomStatic("hud_timer")

[sr_idle]
on_actor_inside = %+esc_on_talk% ;Выдача поршня
;Или так(Выбрать одно):
on_actor_inside = %=on_talk%" ;Функция
Если выбрали поршень, то создаем его:
Код
<info_portion >
<action>СКРИПТ.on_talk</action>
</info_portion>
Вызываем функцию и видим диалог:
Код
function on_talk()
local npc = level_object_by_sid(006)
db.actor:run_talk_dialog(npc)
end
---------------------------------------------
"Делаем некоторых НПС бессмертными"
Код
function immotral()
local npc1 = level_object_by_sid(006) --волк
local npc2 = level_object_by_sid(092) --проводник
local npc3 = level_object_by_sid(032)-- кузнецов
local npc4= level_object_by_sid(100) --Серый
if npc1 then npc1.health = 1 end
if npc2 then npc2.health = 1 end
if npc3 then npc3.health = 1 end
if npc4 then npc4.health = 1 end
endВ голову дохнут.
---------------------------------------------
"Отправляем НПС в другую группировку(например Волка)"
Код
function name()
local npc = level_object_by_sid(006)
npc:set_character_community("имя группировки", 0, 0)
end
Если разговариваем с самим Волком, то вызываем эту функцию:
Код
function name(actor, npc)
npc:set_character_community("имя группировки", 0, 0)
end
---------------------------------------------
"Удалим предмет из игры (или сталкера из игры(Удалим Волка))"
Код
function dell_kluk_final()
local se_obj = alife():object("esc_wolf")
if se_obj then
alife():release(se_obj, true)
end
end
---------------------------------------------
"При вызове происходит использование антирада"
Код
function do_something()
local item = db.actor:object("antirad")
if antirad then
db.actor:eat(item)
end
end
Должно быть так:
Код
function do_something()
local item = db.actor:object("antirad")
if item then
db.actor:eat(item)
end
end
---------------------------------------------
"Проверка:Какой костюм одет(не одет)(например, Экзоскелет)"
Надет ли костюм
Код
function check_outfit()
local outfit = db.actor:item_in_slot(6)
if outfit:section() == "exo_outfit" then --/Если в 6 слоте присутствует "exo_outfit" тогда
return true --/"exo_outfit" одет
else
return false --/"exo_outfit" не одет
end
end
Не надет ли костюм
Код
function check_outfit()
local outfit = db.actor:item_in_slot(6)
if outfit:section() == "exo_outfit" then --/Если в 6 слоте присутствует "exo_outfit" тогда
return true --/"exo_outfit" не одет
else
return false --/"exo_outfit" одет
end
end
---------------------------------------------
"Наносим хит предмету"
Код
function hit_nanesti()
for a=1,65635,1 do
local obj=level.object_by_id(a)
if obj and string.find(obj:name(),"ПРЕДМЕТ") then
local h = hit ();
h.power = 10000;
h.direction = vector():set (0, 0, 0);
h.impulse = 0;
h.draftsman = obj;
h.type = hit.explosion;
obj:hit (h);
end
end
end
---------------------------------------------
"Проверяет, находится ли, например, Волк на локации Кордон"
Код
function rest()
local npc = level_object_by_sid(006) --волк
if npc and level.name() == "l01_escape" then
return true
else
return false
end
end
---------------------------------------------
"Проверка:Например на Кордоне находится ГГ или нет"
Код
function go_to_marsh_complete()
if level_name == "l01escape" then
return true
else
return false
end
end
---------------------------------------------
Еще функции (Для ТЧ).

Код
function kill_stalker(actor, npc)
npc:kill(npc)
end

"Как, через скрипт, сделать НПС врагом?"

Код
function enemy(actor, npc)
npc:set_relation (game_object.enemy, db.actor)
end

"Как создать функцию вызова звукового сигнала и проиграть ее в голове ГГ?"

"Еще один способ спавна НПС (или предмета)."

Код
function НАЗВАНИЕ_create()
local x=
local y=
local z=
local level_vertex=
local game_vertex_id=
alife():create("НАЗВАНИЕ",vector():set(x,y,z),level_vertex,game_vertex_id)
end

"Как запустить много функций одной связкой?"

Например:
Код
function all_spawn()
НАЗВАНИЕ_create()
any_sound()
end

function НАЗВАНИЕ_create()
local x=
local y=
local z=
local level_vertex=
local game_vertex_id=
alife():create("НАЗВАНИЕ",vector():set(x,y,z),level_vertex,game_vertex_id)
end

Frankenshtayn , Но опять же таки. Функцию придется ставить на апдейт. В то время, как рестриктор можно спавнить в самый последний момент, да и после отработки которого (если прописан nil) - ресурсы на проверку тратится не будут.
Более упрощенный способ:

Со знаками можно поэкспериментировать




Так маленький примерчик: Когда юзаем дверь у Сидора, дверь открывается и отзывается инфопоршн

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

; cse_shape properties
shapes = shape0
shape0:type = box
shape0:axis_x = 2.64159965515137,0,0
shape0:axis_y = 0,2.22759985923767,0
shape0:axis_z = 0,0,2.64159965515137
shape0:offset = 0,0,0

; cse_alife_space_restrictor properties
restrictor_type = 3

nil, нет, значит рестриктор многоразового использования.

Собственно, логика двери:

Это, что бы проверять наличие НЕСКОЛЬКИХ и РАЗНЫХ предметов в рюкзаке ГГ

Это, что бы отдавать в НУЖНОМ количестве НУЖНЫЕ предметы.
Вставляется в скриптовый файл и оформляется по типу:

Есть ли ДВЕ ammo_gauss - проверка

= false
end
Проверка на количество разных предметов

Отдача "этих" предметов без появления их в "торговле" оппонента - тупое отбирание их у ГГ.


ЗЫ. Ещё раз НАСТОЯТЕЛЬНО - эти "универсалки" должны "лежать" в конкретном скриптовом файле и все ссылки на них должны ТАК-ЖЕ "обзываться" по соответствию.





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

Создаем новый файл, например all_txt.script и пишем в него таблицу со всеми нужными текстами:

Ниже таблицы, пишем незатейливую ф-ию, которая будет возвращать нашу таблицу:

ВАЖНО! Имя функции и имя таблицы в файле, обязательно должны быть разными!

Затем в другом файле, где юзаем наши тексты объявляем нашу таблицу:




Следует уточнить, что "удаление" должно производиться вне "видения" ГГ
Не соглашусь, Саша. Удалять можно хоть стоя рядом, а вот то что я упустил, и что действительно важно: эту функцию нельзя вызывать из диалога с НПС которого пытаемся удалить.






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

Не стоит воспринимать мои же "мысли и знания", как "что-то этакое". Пробуйте, это работает. Я сужу не, как спец и программер, а как "представитель группировки от сохи" А ОНО и в правду, "работает". Есть куча литературы по языку ЛУА, там много полезного, хотя и полно "дезинформации" - я только после года "возни" и отмахиваний от "первоисточников" всё же ОПЯТЬ прихожу к выводу, что УЧИТЬСЯ надо сначала "азбуке", а потом уже "терзать" внешние эффекты. Ну. У нас же всегда - "хочется быстрее и всего". А когда "влезешь", то захочется "ещё больше". А ТАМ, извините, ЗНАТЬ надо и НИкТО не подскажет - "сам плавай".






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




Однако я пока не видел нормальной вменяемой ф-ии на перевод.
Если я правильно помню, то возможность перевода НПС в оффлайн через отдельное поле логики появилась только в ЗП. В логике это выглядит так:

Т.е. здесь видно, что поддерживается кондлист и выполнение "эффектов".
Соответственно в xr_logic.script появилась и часть кода, обрабатывающая это поле:

В ТЧ или ЧН такой поддержки нет, но наверное можно и сделать, я не знаю…. А можно поступить проще, ну например перевести НПС в оффлайн по ранению:

И в конце логики секцию хита:

Чтобы он действительно туда пошел, открываем xr_effects.script и добавляем туда функцию:


Всё. Запускаем игру, получаем от Волка ПМ, стреляем в ногу (главное ранить, а не убить) и Волк исчез, только метка осталась. Таким образом можно переводить НПС в оффлайн с любой секции его логики.





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

Хм, а если по сиду? Без прописки логики?

Надо будет попробовать завтра.








Удаление любого онлайнового/оффлайнового объекта из игры. Во время удаления можно хоть плясать рядом с ним:

Само удаление, например нескольких сталкеров/монстров:

remove_obj - ф-ия в которую передаем данные для удаления.

Если же удаляем кого то одного - цикл и таблица не нужны.




Удаление любого онлайнового/оффлайнового объекта из игры. Во время удаления можно хоть плясать рядом с ним:

Ф-ия которая будет все делать:
Код
function remove_obj(name)
local obj
for a=1,65535 do
obj = alife():object(a)
if obj and string.find(obj:name(),name) then
alife():release(obj, true)
end
end
end

Само удаление, например нескольких сталкеров/монстров:
Код
function remove_freaks()
local tbl_remove = < "bloodsucker_1", "bloodsucker_2">
for _, v in pairs (tbl_remove) do
remove_obj(v)
end
end

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

class "spawner" (CUIScriptWnd)

function spawner:__init(owner,action) super()
self.action = action
self.owner = owner
self:InitControls()
self:InitCallBacks()
end
function spawner:__finalize() end

function spawner:InitControls()
-- здесь определяем координаты левого верхнего угла и ширину-высоту
self:Init(50,50,550,450)

-- файл-описатель наших элементов
local xml = CScriptXmlInit()
xml:ParseFile("ui_boooz.xml")

-- видео на заднем плане
xml:InitStatic("back_video", self)

-- рамка
xml:InitStatic("background", self)

-- кнопки
self:Register(xml:Init3tButton("caption", self),"caption")
self:Register(xml:Init3tButton("btn_1", self),"btn_1")
-- кнопка выхода
self:Register(xml:Init3tButton("btn_quit", self),"btn_quit")
self:Register(xml:InitEditBox("edit_box", self), "edit_box")

local caption = self:GetButton("caption")
local btn_1 = self:GetButton("btn_1")
if self.action == "spawn" then
caption:SetText("Секция желаемого объекта, количество")
btn_1:SetText("Spawn!")
elseif self.action == "info" then
caption:SetText("Инфа для добавления")
btn_1:SetText("Дать инфу!")
elseif self.action == "find" then
caption:SetText("Часть имени объекта для поиска")
btn_1:SetText("Искать!")
elseif self.action == "remove" then
caption:SetText("Часть имени объекта для удаления")
btn_1:SetText("KKND!")
end
end

function spawner:InitCallBacks()
-- тут интерактивные элементы, при определенном действии выполняется заданная ф-ия
self:AddCallback("btn_1", ui_events.BUTTON_CLICKED, self.dots1, self)
self:AddCallback("btn_quit", ui_events.BUTTON_CLICKED, self.on_quit, self)
end

function spawner:OnKeyboard(dik, keyboard_action)
CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)
if keyboard_action == ui_events.WINDOW_KEY_PRESSED then
-- на выход повесим Esc
if dik == DIK_keys.DIK_ESCAPE then
self:on_quit()
end
if dik == DIK_keys.DIK_RETURN then
self:dots1()
end
end
return true
end

function show_actor_position()
if level.present() and (db.actor

function spawner:spawn(text)
local type = text
local vid, gvid
local a = vector()
a = db.actor:position()
a.z = a.z + 2
a.y = a.y + 0.5
vid = db.actor:level_vertex_id()
gvid = db.actor:game_vertex_id()

local n = 1
local sf = string.find(text,",")
if sf then
n = string.sub(text,sf+1)+0
if n==nil then
n = 0
elseif n>999 then
n = 999
end
type = string.sub(text,1,sf-1)
end

if not system_ini():section_exist(type) then
amk.send_tip("Секция "..type.." не существует!","Cheat: Spawner",0,10,"gen_info")
return false
end

for i=1,n do
alife():create(type,vector():set(a.x-1+math.random()*2,a.y,a.z-1+math.random()*2),vid,gvid,65535)
end

amk.send_tip("Создал "..type.." в количестве "..n.." штук.","Cheat: Spawner",0,10,"gen_info")
return true
end

function spawner:remove_all (name)
local obj
local n=0
for a=1,65535 do
obj = alife():object(a)
if obj and string.find(obj:name(),name) then
alife():release(obj,true)
n = n+1
end
end
amk.send_tip("Удалено "..n.." объектов.","Cheat: Clear",0,10,"gen_info")
end

function spawner:find_closest (type)
if level.present() and (db.actor

= 0then
level.map_remove_object_spot(a,"cheat_item")
-- amk:remove_spot_from_map(a,type)
end
if obj and string.find(obj:name(),type) then
dist = obj.position:distance_to(db.actor:position())
if dist < min then
min = dist
closest = a
end
end
end
if closest>0 then
obj = alife():object(closest)
local map = alife():level_name(game_graph():vertex(obj.m_game_vertex_id):level_id())
local text = obj:name().."; уровень ; уровень cheat_item",string.format(obj:name().." Id:"..game.translate_string(closest)))
if map == level.name() then
local p1 = db.actor:position()
local p2 = obj.position
dist = obj.position:distance_to(db.actor:position())
local dx = p2.x - p1.x
local dy = p2.y - p1.y
local dz = p2.z - p1.z
text = string.format("%s; расстояние=%.2fм; dX=%.2f, dY=%.2f, dZ=%.2f", text, dist, dx,dy,dz)
get_console():execute(string.format("%s; расстояние=%.2fм; dX=%.2f, dY=%.2f, dZ=%.2f", text, dist, dx,dy,dz))
--amk:add_spot_on_map(closest,type,obj:name().." id:"..closest)
end
amk.send_tip(text,"Cheat: Find Object",0,30,"gen_info")
return true
else
amk.send_tip(type.." не найден!","Cheat: Find Object",0,10,"gen_info")
return false
end
get_console():execute("flush")
else return false
end
end

function set_npc_health(obj, health)
if (obj and health <=2) then
if (_g.IsStalker(obj)) then
local tbl = amk.read_stalker_params(obj)
tbl.health = health
tbl.updhealth = health
amk.write_stalker_params(tbl, obj)
end
end
end

--[[function spawner:add_map_spot(id)
--local obj = alife():object(id)
--if obj then --and string.find(obj:name(),name) then
level.map_add_object_spot_ser(id,"cheat_item",obj:name())
--local d = 0
--local h = 0
--local m = 1
--amk:g_start_timer("DMSC",0,0,3,id)--,spawner:del_map_spot(id))
--end
end
function spawner:del_map_spot(id)
level.map_remove_object_spot(id,"cheat_item")
end]]

function deadman_to_life()
for a=1,10000,1 do
local obj=alife():object(a)
if (obj and IsStalker(obj) and not obj:alive()) then
local posobj=obj.position
local actorpos=db.actor:position()
if (posobj:distance_to(actorpos) < 2) then
set_npc_health(obj, 1)
end
end
end
end

function spawner:dots1()
local text = self:GetEditBox("edit_box"):GetText()
if text

= "" then
if self.action == "spawn" then
self:spawn(text)
elseif self.action == "info" then
db.actor:give_info_portion(text)
amk.send_tip(text.." добавлено.","Cheat: Add Info",0,15,"gen_info")
elseif self.action == "find" then
self:find_closest(text)
elseif self.action == "remove" then
self:remove_all(text)
end
end
self:on_quit()
end

function spawner:on_quit()
self:GetHolder():start_stop_menu (self,true)
end

Читайте также: