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

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

_Призрак_, насколько помню в ЗП появились энергетики повышающие грузоподъемность, так что можно по-извращаться с ними.

 

P.S. Мутно, но реализуемо. :)

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

gruber

Имя ремарки можно задавать любое...

Ах да, у меня ремарк пропущен, но с такой логикой всё равно вылет тот же.

[logic]
active = remark@raketa

[remark@raketa]
sniper = true

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

А нет всё работает вылет был не из-за этого.

Как всегда моя невнимательность, спасибо.

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

Возможно ли сделать строй солдат которые отдают честь и ходят по "прямоугольнику"?

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

Изменено пользователем ФеНиКс
87728-stalker.gif
Ссылка на комментарий

Значит только в ЗП .......

Создал новую фичу

Основной скрипт

function nyss()
local itemslot = db.actor:item_in_slot(10)
if itemslot == "chasbI" then 
myne.show_time()
db.actor:give_info_portion("vivod")
if itemslot ~= "chasbI" and db.actor:has_info("vivod") then 
myne.ybiraem()
db.actor:disable_info_portion("vivod")
end 
end

текст myne.show_time()

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

текст myne.ybiraem()

function ybiraem()
get_hud():RemoveCustomStatic("hud_time_static")
get_hud():RemoveCustomStatic("hud_show_time")
end

Собственно - когда на поясе предмет, выводится часы когда предмет снимается часы тоже снимаются но на практике :

Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp
Line          : 73
Description   : <no expression>
Arguments     : LUA error: ...ow of chernobyl\gamedata\scripts\bind_stalker.script:216: attempt to index global 'aktivacii' (a nil value)

 

Что нитак? луа чекер сказал что всё нормально, но нет. Вылет

 

p/s/ aktivacii - название скрипта

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

Проверяем наличие предмета на поясе!

Автор: singapur22

Хотя и не совсем в тему :russian_ru:

Исправлено!

Достаточно долго бытовало мнение, что определить предмет на поясе невозможно. Теоретически так оно и есть, так как слот belt нигде не отслеживается. Но благодаря ПЫСам, которые наконец соизволили объяснить, пусть не прямой, а косвеный, но всётаки способ определения нахождения предмета на поясе. Давайте сначала разберём как мы это будем делать, чтобы в дальнейшем не было глупых вопросов.

Итак, мы имеем инвентарь актора. Чтобы определить список всего инвентаря, который имеется у актора в наличии, нужно использовать метод db.actor:inventory_for_each(ScanInventory)

Где ScanInventory --имя функции которая вызывается для каждого объекта инвентаря.

Спросите, и как же мы определим какие предметы из них на поясе, а какие нет?! Вот это я щас и попытаюсь описать. Массив инвентаря актора состоит из нескольких субмассивов, которые запрашиваются в фиксированном порядке. А порядок здесь такой:

1. Массив рюкзака.

2. Массив пояса.

3. Первый слот.

4. Второй слот.

и т. д.

 

Чтобы при итерации всего списка инвентаря выудить именно массив пояса, нужно определить последний элемент в массиве рюкзака и ближайший элемент в одном из слотов. Предметы находящиеся между ними и будут являться предметами навешанными на пояс belt.

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

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

Тоесть порядок действий такой:

1. Спавним предмет-разделитель в инвентарь актора.

2. Производим итерацию предметов инвентаря.

3. Как только итератор дойдёт до предмета-разделителя включаем ключ добавления инвентаря во внешнюю таблицу.

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

5. По мере добавления, производим проверку на нахождение онных в одном из слотов. И как только один из них окажется предметом находящемся в слоте, завершаем пополнение таблицы.

После всех этих действий, внешняя таблица будет содержать только список предметов находящихся на поясе.

 

Вот собственно и весь принцип.

Итак создаём в скриптах новый файл с именем bind_belt.script, и вставляем в него код:

belt = {} --//внешняя таблица пояса

 

local separator = nil --//переменная для сохранения userdata разделителя

local del_separator = false --//ключь удаления разделителя

local start_add_belt = false --//ключь начала заполнения таблицы db.belt

local stop_update = false

local start_function = true

 

--основная функция итерации инвентаря

--(привязана к функции update() в файле bind_stalker.script)

function IterateInventory()

if stop_update then return end

 

--//удаление всех случайно-сохранённых разделителей

if start_function then

db.actor:inventory_for_each(function(item)

if item:section() == "separator" then

alife():release(item, true)

end

end)

separator = nil

del_separator = false

start_function = false

end

 

--//удаление разделителя (третий цикл)

if del_separator and separator then

this.DeleteSeparator()

stop_update = true

return

end

 

--//итерация инвентаря (второй цикл)

if separator then

db.belt = {}

db.actor:inventory_for_each(ScanInventory)

del_separator = true

start_add_belt = false

else

 

--//спавн разделителя (первый цикл)

separator = alife():create("separator", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())

end

end

 

--функция удаления разделителя

function DeleteSeparator()

alife():release(separator, true)

separator = nil

del_separator = false

end

 

--функция сканирования инвентаря

function ScanInventory(item)

local section = item:section()

 

if start_add_belt and not DetermineSlot(item:id()) then

if not db.belt[section] then

db.belt[section] = 1

else

db.belt[section] = db.belt[section] + 1

end

end

 

if item:section() == "separator" then

start_add_belt = true

end

end

 

--функция определения привязки объекта к одному из слотов

function DetermineSlot(item_id)

for i=0, 12 do

local obj = db.actor:item_in_slot( i )

if obj and obj:id() == item_id then

return true

end

end

return false

end

 

--функция запуска обновления таблицы при закрытии инвентаря

--(привязана к колбэку info_callback() в файле bind_stalker.script)

function InventoryInfo(info)

if info == "ui_inventory" or info == "ui_car_body" or info == "ui_trade" then

if separator then

this.DeleteSeparator()

end

elseif info == "ui_inventory_hide" or info == "ui_car_body_hide" or info == "ui_trade_hide" then

stop_update = false

end

end

 

--функция запуска обновления таблицы при потере предмета

--(привязана к колбэку on_item_drop() в файле bind_stalker.script)

function Drop(obj)

if obj:section() ~= "separator" then

stop_update = false

end

end

Создаём объект в конфигах (файл config/misc/items.ltx) с именем секции [separator]:

[separator]:identity_immunities
GroupControlSection    = spawn_group
discovery_dependency =
$spawn = ""
$prefetch = 32
class     = II_BANDG
cform     = skeleton
visual     = equipments\item_bandage.ogf
description     =  
inv_name            =  
inv_name_short      =  
inv_weight           = 0
inv_grid_width     = 0
inv_grid_height     = 0
inv_grid_x     = 0
inv_grid_y     = 0
eat_health = 0
eat_satiety = 0
eat_power = 0
eat_radiation = 0
wounds_heal_perc = 0
eat_portions_num = 1
cost    = 0
animation_slot  = 4

Затем в файле bind_stalker.script производим пропись всех нужных привязок функций:

 

1. Функция actor_binder:info_callback(npc, info_id):

вписываем в конец тела функции: bind_belt.InventoryInfo(info_id)

 

2. Функция actor_binder:on_item_drop(obj)

вписываем в конец тела функции: bind_belt.Drop(obj)

 

3. Функция actor_binder:update(delta)

вписываем в конец тела функции: bind_belt.IterateInventory()

 

Вот собственно и всё.

Этого не знаю, знаю просто где ответ есть. В скриптах не бум-бум.

Изменено пользователем amik
  • Не нравится 1

Мой архив

Сталкером не занимаюсь.

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

TRAMP14

И чего изобретать велосипед?

 

--*******скрипт отслеживания предметов на поясе by Tolusha*************************************************

belt = {}
belt_status = false

local need_update = true
local inventory_open = false
local separator_spawned = false
local separator = "separator"

local debug = false
local flag

--// на апдейт
function inventory_update()

    if (need_update == false) then return end

    if debug == true and belt_status == true then get_console():execute("belt_status=false") end
    belt_status = false

    -- Спавним разделяющий елемент
    if (separator_spawned == false) then
        alife():create(separator,
            db.actor:position(),
            db.actor:level_vertex_id(),
            db.actor:game_vertex_id(),
            db.actor:id())
        separator_spawned = true
        if debug == true then get_console():execute("separator_spawned") end
        return
    end

    belt = {}
    flag = 0

    -- Сканируем инвентарь
    db.actor:inventory_for_each(scan_inv)
    need_update = false

    -- Удаляем разделяющий елемент
    db.actor:inventory_for_each(del_separator)
    separator_spawned = false

    if debug == true and belt_status == false then get_console():execute("belt_status=true") end
    belt_status = true

    if debug == true then
        for i,k in pairs(belt) do
            get_console():execute(i.."="..k)
        end
    end
end

-- Перебор предметов инвентаря
function scan_inv(item)
    local section = item:section()

    if section == separator then
        flag = 1
        return
    end

    if flag == 1 then
        if slot_item(item) ~= nil then
            flag = 2
        else
            insert_to_table(belt, section)
        end
    end
end

-- Добавление в таблицу
function insert_to_table(tbl, section)
    if tbl[section] == nil then
        tbl[section] = 1
    else
        tbl[section] = tbl[section] + 1
    end
end

-- Удаление разделяющего предмета
function del_separator(item)
    if item:section() == separator then
        alife():release(alife():object(item:id()), true)
        if debug == true then get_console():execute("separator_removed") end
    end
end

-- Определение налечия предмета в одном из слотов
function slot_item(item)
    for i=0,12 do
        local obj = db.actor:item_in_slot(i)
        if obj and item:id() == obj:id() then
            return i
        end
    end

    return nil
end

--на take 
function on_item_take(item)
    if item and item:section() == separator then return end

    if (inventory_open == false) then
        if (separator_spawned == true) then
            db.actor:inventory_for_each(del_separator)
            separator_spawned = false
        end

        need_update = true
        if debug == true then get_console():execute("item_take") end
    end
end

-- на drop
function on_item_drop(item)
    if item and item:section() == separator then return end

    if (inventory_open == false) then
        if (separator_spawned == true) then
            db.actor:inventory_for_each(del_separator)
            separator_spawned = false
        end

        need_update = true
        if debug == true then get_console():execute("item_drop") end
    end
end

-- на info_callback
function on_inventory_info(info_id)
    if info_id == "ui_inventory" then
        inventory_open = true
        if debug == true then get_console():execute("inventory_open") end

    elseif info_id == "ui_inventory_hide" then
        inventory_open = false
        need_update = true
        if debug == true then get_console():execute("inventory_close") end
    end
end

--********************************************************************************
****************************




--//--служебная функция для получения отформатированой строки  игровой даты или  игрового времени
function GetTimeOrDate(arg)
-- передаем аргументы из числа  "Y", "M", "D", h"", "m", "s", "ms" - по одной штуке - смотря какое значение  текущего игрового времени или даты  хотим получить
local  t = {
["Y"] = game.CTime.DateToYear,      --/  2012                  год      
["M"] = game.CTime.DateToMonth,     --/    01/2012           месяц
["D"] = game.CTime.DateToDay,       --/   01/01/2012    день \месяц\год 
["h"] = game.CTime.TimeToHours,     --/   23                    час
["m"] = game.CTime.TimeToMinutes,   --/   23:59               часы\минуты
["s"] = game.CTime.TimeToSeconds,   --/   23:59:59         часы\минуты\секунды
["ms"]= game.CTime.TimeToMilisecs } --/ 23:59:59:999   часы\минуты\секунды\миллисекунды
    if t[arg] then
        if arg ==string.lower(arg) then
         return game.get_game_time():timeToString(t[arg])
         else
         return game.get_game_time():dateToString(t[arg])
        end
    else 
    return ""
    end 
end 

local hud = get_hud()

function TimerStatic()
local text= ""
local cs = hud:GetCustomStatic("hud_timer")
        if cs == nil then
        hud:AddCustomStatic("hud_timer", true)
        cs = hud:GetCustomStatic("hud_timer")
    end
        
    local D = GetTimeOrDate("D")
    local m = GetTimeOrDate("m")
        text = D.."\\n"..m
    if cs ~= nil then
        cs:wnd():SetText(text)
    end
end 


-- на апдейт
function AddHud()
if  belt and next(belt) and belt["af_blood"] then --если предмет на поясе
TimerStatic() -- выводим статик
else
--// если сняли 
local cs = hud:GetCustomStatic("hud_timer")
--то если статик есть на худе
if  cs then
--//убираем
hud:RemoveCustomStatic("hud_timer")
        end 
    end 
end

 

--[[

"hud_timer" - это уже имеющийся статик в ui_custom_msgs - я него только шриф поменял на более подходящий:

"graffiti32"на "graffiti22"

 

--]]

 

и будут вот такие симпатичные часы

98edea755dd6b454e8137e8f32bf9988.jpeg

 

Ссылка на комментарий
"hud_timer" - это уже имеющийся статик в ui_custom_msgs - я него только шриф поменял на более подходящий:

"graffiti32"на "graffiti22

Заинтересовало - где можно найти списочек всех графити с визуальными примерами?

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

TRAMP14

Примеров таких нет.

Вот список (возможно неполный) из lua help движковых функций которые возвращают шрифты

GetFontGraffiti32Russian()

GetFontSmall()

GetFontGraffiti50Russian()

GetFontDI()

GetFontLetterica16Russian()

GetFontLetterica25()

GetFontGraffiti22Russian()

GetFontGraffiti19Russian()

GetFontGraffiti22Russian()

GetFontGraffiti19Russian()

GetFontLetterica16Russian()

GetFontLetterica18Russian()

GetFontMedium()

 

Их наименования в xml конфигах смотри сам. Как они выглядят - покажет простой тест в игре.

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

ФеНиКс, сделать можно! Синхронизировать сложно, хотя...

И что тебе не понятно по точкам путей?

Вот давай разберемся!

[mil_freedom_sniper_defense_look3]

points = p0,p1,p2 здесь пишем все точки, которые будут у нас в нашем пути, т.е. здесь три

p0:name = wp00 первая точка пути. wp00 - это имя пути. Здесь можно задавать флаги, такие как: a - анимация передвижения в эту точку, p - вероятность остановиться в этой точке, sig - установить сигнал по прибытию в точку

p0:flags = 0x1

p0:position = -20.9435977935791,-9.3701057434082,-42.9284133911133

p0:game_vertex_id = 1592

p0:level_vertex_id = 286124

p0:links = p1(1) следующая точка пути

 

p1:name = wp01

p1:flags = 0x1

p1:position = -13.237771987915,-8.33596229553223,-11.7740716934204

p1:game_vertex_id = 1593

p1:level_vertex_id = 293730

p1:links = p2(1)

 

p2:name = wp02

p2:flags = 0x1

p2:position = -1.6784291267395,-8.71416282653809,-7.24800872802734

p2:game_vertex_id = 1585

p2:level_vertex_id = 306093

Точки нужно задавать заранее в all.spawn, динамически, на сколько мне известно - нельзя. Про flags точно не знаю, поэтому сказать не могу, абы не запутать.

Ссылка на комментарий
Disord, глянь, вот тут про смарттерейны не только с чем, но и как их жевать :) >>Click Me<< там пять частей, но почитать стоит. ;)
Ссылка на комментарий

Где у меня ошибка со скриптовым постэффектом? Метод process не вызывается почему-то.

Вот вызов:

local ppe=recovery_effect(max_restored_health-db.actor.health)
ppe:start()

-- Постэффект
class "recovery_effect" (effector)
function recovery_effect:__init(add_health) super()
    self.params = effector_params()
    self.params.blur=0
    self.params.gray=0
    self.params.dual=duality(0,0)
    self.params.noise=noise(0,0,0)
    self.params.color_add=color(0,0,0)
    self.params.color_base=color(0,0,0)
    self.params.color_gray=color(0,0,0)
    
    self.max_add=add_health                                    -- Максимальная яркость
    self.time_start=time_global()                            -- Время начала
    self.time_in=self.time_start+add_health*1.5*1000        -- Время максимального осветления
    self.time_white_scr=self.time_in+add_health*2.5*1000    -- Время начала сброса осветления
    self.time_out=self.time_white_scr+add_health*0.75*1000    -- Время конца
    
    self.time_start_in=self.time_in-self.time_start
    self.time_white_scr_out=self.time_out-self.time_white_scr
    self.pi2=math.pi/2
end

function recovery_effect:process(pp)
    local time=time_global()
    msg("!")
    if time<self.time_in then
        local color_add_cur=self.max_add*math.cos(self.pi2*(self.time_in-time)/self.time_start_in)
        self.params.color_base=color(color_add_cur,color_add_cur,color_add_cur)
    elseif time<self.time_white_scr then
        self.params.color_base=colol(self.max_add,self.max_add,self.max_add)
    elseif time<self.time_out then
        local color_add_cur=self.max_add*math.sin(self.pi2*(self.time_out-time)/(self.time_white_scr_out))
        self.params.color_base=color(color_add_cur,color_add_cur,color_add_cur)
    end
    effector.process(self,pp)
    pp:assign(self.params)
    return true
end

function recovery_effect:finished()
    return self.time_out<time_global()
end

 

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

IQDDD,

super() вызывается с аргументами, второй - время действия постэффекта. Может в этом проблема.

 

А зачем тебе вообще этот скриптовый постэффект? Ничего же не даёт по сравнению с движковым.

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

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

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

IQDDD,

А если время действия постэффекта заранее неизвестно?

запусти заново. Не знаю на самом деле. Поэкспериментируй и расскажи нам, тогда это будет известно =)

Там есть ещё возвращаемое значение из process. Может быть при определённой комбинации параметров при создании эффекта это может являться сигналом к окончанию проигрывания. Но это только предположение.

 

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

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

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

Expression : vertex || show_restrictions(m_object)

Function : CPatrolPathManager::select_point

File : E:\stalker\sources\trunk\xr_3da\xrGame\patrol_path_manager.cpp

Line : 155

Description : any vertex in patrol path [gar_bandit_post_walk1] in inaccessible for object [gar_bandit_post_7]

 

 

 

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

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

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

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

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

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

Войти

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

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

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