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

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

@_Sk8_AsTeR_, передача аптечки раненому происходит в файле dialogs.script, функция transfer_medkit. Там же идёт проверка на отношение нпс и ГГ, и если они враги, то в xr_wounded.help_wounded запускается таймер, по истечении которого вылеченный нпс с некоторой вероятностью может снова стать враждебным к ГГ. У тебя, видимо, что-то с проверкой в dialogs.transfer_medkit не так.

Изменено пользователем naxac
  • Спасибо 1

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

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

Кажется давно есть в моде Paradise Lost вылет при загрузке сохранения, почему-то именно на уровне Кордон. Имеет вид:

[error]Expression : fatal error
[error]Function : CScriptEngine::lua_error
[error]File : E:\stalker\sources\trunk\xr_3da\xrGame\script_engine.cpp
[error]Line : 73
[error]Description : <no expression>
[error]Arguments : LUA error: ...shadow of chernobyl\gamedata\scripts\xr_logic.script:1195: attempt to index local 'obj' (a nil value)

Открываю скрипт xr_logic, нахожу строку 1195, там следующая функция:

function pstor_retrieve(obj, varname, defval)
	local npc_id = obj:id()
	
	if db.storage[npc_id].pstor ~= nil then
		local val = db.storage[npc_id].pstor[varname]
		if val ~= nil then
			return val
		end
	end
	if defval ~= nil then
		return defval
	end
	return nil
--'	abort("xr_logic: pstor_retrieve: variable '%s' does not exist", varname)
end

Ругается, на вторую строчку:

	local npc_id = obj:id()

Что же с ней не так? Какая-то ошибка в функции?

 

UPD: вот возможно похожий вылет: https://www.amk-team.ru/forum/topic/8230-cop-kovyryaemsya-v-faylah/?do=findComment&comment=1031683

Дело якобы в логике какого-то NPC.

UPD2: вот ещё: https://www.amk-team.ru/forum/topic/8806-cop-kvesty/?do=findComment&comment=369302

Тут уже вроде из-за квеста.

UPD3: ещё вариант: https://www.amk-team.ru/forum/topic/5525-soc-kovyryaemsya-v-faylah/?do=findComment&comment=855858

Вроде есть объяснение, но функция другая: 

В 21.06.2014 в 00:22, AndreySol сказал:

в скрипте xr_logic в 126-й строке локальная переменная st равна nil. Открывай в редакторе, который показывает нумерацию строк, ищи 126-ю и гляди че там за nil получился. В оригинальном ТЧ эта строка находится в ф-ции configure_schemes, значит глюк связан с гулагами\логикой НПСов.

 

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

@aka_sektor, тут можно вывести в лог имя переменной (varname) и по нему уже поискать по скриптам, откуда ноги растут.

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

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

Никто часом не пробовал создать детектор оружия для предметов находящихся в онлайне на локации? Навесить и удалить метки нетрудно, интересует функция определения объектов в онлайне. Чтобы, скажем, по классам пистолета, автомата, снайперки и так далее отображать соответствующую иконку.

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

@Капрал Хикс, в se_item.script, в on_register и on_unregister всякие предметы регистрируются в task_manager, что бы их потом искать. Вот тебе похоже туда же нужно.

 

  • Полезно 1
Ссылка на комментарий
55 минут назад, dsh сказал:

Вот тебе похоже туда же нужно.

Эх, мудрёно там :)

Однако я вспомнил, что нужное мне разбиение по классам оружия есть в скрипте динамических новостей от AMK - осталось прикрутить должным образом :)

Ссылка на комментарий
22 часа назад, Капрал Хикс сказал:

интересует функция определения объектов в онлайне.

 

21 час назад, dsh сказал:

в se_item.script

Приставка se_ означает серверный класс(серверная часть) объекта, если я не ошибаюсь. Думается, что определение объектов в он-лайне стоит сделать как-то иначе...

22 часа назад, Капрал Хикс сказал:

Чтобы, скажем, по классам пистолета, автомата, снайперки и так далее отображать соответствующую иконку.

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

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

Неверно я выразился, некорректно... Нужно отображение оружия на текущей локации. Я так понимаю, удобней всего вешать проверку на соответствие предметов классу оружия в xr_motivator.script и вызывать функцию отображения меток отсюда (подсмотрено в DMX мод для меток НПС):

Скрытый текст

function motivator_binder:net_spawn(sobject):

  local obj = alife():object(self.object:id()).w_story_id
  if obj then myscript.mark_wpn() end

а удалять метки при уходе с локации здесь function motivator_binder:net_destroy()...

  local obj = alife():object(self.object:id()) and alife():object(self.object:id()).w_story_id
  if obj then myscript.unmark_wpn(sid,self.object:id()) end


В самом же файле myscript...

Скрытый текст

 

-Здесь задаём соответствие секции оружия определённому типу, чтобы не мучиться с классами оружия
local weapons_id = {
["base_id"]         = 0,

["wpn_pm"]         = 1,
["wpn_pb"]         = 1,
["wpn_fort"]         = 1,

["wpn_svd"]             = 2,
["wpn_gauss"]         = 2,

["wpn_val"]         = 3,
["wpn_ak74"]         = 3,
["wpn_lr300"]         = 3,

["wpn_toz34"]         = 4,
["wpn_spas12"]         = 4,

["wpn_pkm"]         = 5,

["wpn_knife"]         = 6,

["wpn_grenade_launcher"] = 7,
["wpn_rpg7"]         = 7,
["wpn_rg6"]         = 7,
["grenade_f1"]         = 7,

["wpn_flame"]         = 8
}

-здесь задаём тип метки в зависимости от типа оружия
local mark_types = {
            [0] = {mark = "NOT_USED"},
            [1] = {mark = "mark_1_pistol"},
            [2] = {mark = "mark_2_sniper"},
            [3] = {mark = "mark_3_assault"},
            [4] = {mark = "mark_4_shotgun"},
            [5] = {mark = "mark_5_heavy"},
            [6] = {mark = "mark_6_knife"},
            [7] = {mark = "mark_7_grenade"},
            [8] = {mark = "mark_8_flame"}
}


function get_weapon_type(obj)
--isweapon (проверка на то, что объект является оружием из _g.script)
    if(obj and isWeapon(obj)) then
            if weapons_id[id] then
                return weapons_id[id]
    else
            return weapons_id["base_id"]
    end
end

-собственно функция отображения меток
function mark_wpn(id)
    local obj = alife():object(self.id)
    local wp_type = get_weapon_type(obj)

        if wp_type = 1 then
                        level.map_add_object_spot(id, "mark_types[wp_type].mark", "Пистолет или ПП") -- Пистолеты и ПП

        elseif wp_type = 2 then
                        level.map_add_object_spot(id, "mark_types[wp_type].mark", "Винтовка") -- Снайперские винтовки

        elseif wp_type = 3 then
                        level.map_add_object_spot(id, "mark_types[wp_type].mark", "Автомат") -- Автоматы
               end
    end
end

function _mylog(message)
    get_console():execute("!!!ERROR!!!~~~"..message)
end
--ну и добавить функцию удаления меток...

 

P.S. Я знаю, что приведённый код имени д-ра Франкенштейна из кусков других кодов работать не будет, так как в силу недостатка знаний указал неверные аргументы и так далее, но надеюсь, более-менее внятно объяснил, чего хочу добиться в итоге с помощью более сведущих в программировании людей.

Изменено пользователем Капрал Хикс
Ссылка на комментарий
10 часов назад, Капрал Хикс сказал:

вызывать функцию отображения меток отсюда...  motivator_binder:net_spawn

Не верно. motivator_binder это клиентский класс НПСов, а метод net_spawn вызывается при выходе неписей в он-лайн. Загрузка сэйва где нить возле бара - выход в он-лайн нескольких ДЕСЯТКОВ неписей. Соответственно, вызов твоей ф-ции - эти же несколько десятков раз. Сам понимаешь, что такое делать не гоже...

11 часов назад, Капрал Хикс сказал:

Нужно отображение оружия на текущей локации.

Ну вот теперь конкретное условие. Если действие одноразовое, то можно обойтись одноразовым вызовом ф-ции, которая расставит метки. Для этого неплохим местом будет метод net_spawn, но для актера - он в любом случае выходит в он-лайн один раз. В скрипте bind_stalker, function actor_binder:net_spawn(data), где-то после db.add_actor(self.object)(это запись актера в глобальную переменную в скрипте db) добавляй свою ф-цию расстановки меток.

  • Полезно 1
Ссылка на комментарий

Откуда функцию вызывать, теперь ясно, спасибо! Саму функцию переделал, но нужна помощь, ибо застопорился под конец.

Скрытый текст

--Здесь задаём соответствие секции оружия определённому типу, чтобы не мучиться с классами оружия
local weapons_id = {
["base_id"]         = 0,

["wpn_pm"]         = 1,
["wpn_pb"]         = 1,
["wpn_fort"]         = 1,

["wpn_svd"]             = 2,
["wpn_gauss"]         = 2,

["wpn_val"]         = 3,
["wpn_ak74"]         = 3,
["wpn_lr300"]         = 3,

["wpn_toz34"]         = 4,
["wpn_spas12"]         = 4,

["wpn_pkm"]         = 5,

["wpn_knife"]         = 6,

["wpn_grenade_launcher"] = 7,
["wpn_rpg7"]         = 7,
["wpn_rg6"]         = 7,
["grenade_f1"]         = 7,

["wpn_flame"]         = 8
}

--расстояние, ближе которого отображаются метки оружия
local dist_to_wpn = 31

--здесь задаём тип метки в зависимости от типа оружия
local mark_types = {
            [0] = {mark = "NOT_USED"},
            [1] = {mark = "mark_1_pistol"},
            [2] = {mark = "mark_2_sniper"},
            [3] = {mark = "mark_3_assault"},
            [4] = {mark = "mark_4_shotgun"},
            [5] = {mark = "mark_5_heavy"},
            [6] = {mark = "mark_6_knife"},
            [7] = {mark = "mark_7_grenade"},
            [8] = {mark = "mark_8_flame"}
}

function get_weapon_type(weapon)
    if weapon then
        local id = news_main.get_weapon_name(weapon)
          if id == nil or id == "" then _mylog("id==nil") return end
            if weapons_id[id] then
                return weapons_id[id]
            else
            return weapons_id["base_id"]
            end
    else
            return weapons_id["base_id"]
    end
end

--собственно функция отображения меток
function mark()
    for a=1,65535,1 do --подобный перебор при переходе в онлайн это чересчур, но для теста сойдёт
    local obj = alife():object(a)
        if obj then
            local posobj = obj.position
            local actorpos = db.actor:position()
            local wp_type = get_weapon_type(weapon)
            if posobj:distance_to(actorpos) < dist_to_wpn then

--а вот дальше нужна помощь с корректным навешиванием меток и окончанием функции без ошибок
                    if wp_type = 1 then
                        level.map_add_object_spot(id, "mark_types[wp_type].mark", "Пистолет или ПП") -- Пистолеты и ПП
                   end
                        elseif wp_type = 2 then
                        level.map_add_object_spot(id, "mark_types[wp_type].mark", "Винтовка") -- Снайперские винтовки
                   end
                        elseif wp_type = 3 then
                        level.map_add_object_spot(id, "mark_types[wp_type].mark", "Автомат") -- Автоматы
               end
end

function _mylog(message)
    get_console():execute("!!!ERROR!!!~~~"..message)
end

 

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

@Капрал Хикс, если нужно маркировать только онлайновые объекты, то можно написать такой небольшой биндер

	--Здесь задаём соответствие секции оружия определённому типу, чтобы не мучиться с классами оружия
	local weapons_id = {
	["base_id"]         = 0,
	["wpn_pm"]         = 1,
	["wpn_pb"]         = 1,
	["wpn_fort"]         = 1,
	["wpn_svd"]             = 2,
	["wpn_gauss"]         = 2,
	["wpn_val"]         = 3,
	["wpn_ak74"]         = 3,
	["wpn_lr300"]         = 3,
	["wpn_toz34"]         = 4,
	["wpn_spas12"]         = 4,
	["wpn_pkm"]         = 5,
	["wpn_knife"]         = 6,
	["wpn_grenade_launcher"] = 7,
	["wpn_rpg7"]         = 7,
	["wpn_rg6"]         = 7,
	["grenade_f1"]         = 7,
	["wpn_flame"]         = 8
	}
	--здесь задаём тип метки в зависимости от типа оружия
	-- поле hint задавать не обязательно: в случае его отсутствия будет выведено инвентарное имя предмета
	local mark_types = {
	            [0] = {mark = "NOT_USED", hint = nil},
	            [1] = {mark = "mark_1_pistol", hint = "Пистолет"},
	            [2] = {mark = "mark_2_sniper", hint = "Снайперская винтовка"},
	            [3] = {mark = "mark_3_assault"},
	            [4] = {mark = "mark_4_shotgun"},
	            [5] = {mark = "mark_5_heavy"},
	            [6] = {mark = "mark_6_knife"},
	            [7] = {mark = "mark_7_grenade"},
	            [8] = {mark = "mark_8_flame"}
	}
	 
	class "mark_binder" (object_binder)
	 
	function mark_binder:__init(obj)
	super(obj)
	end
	 
	function mark_binder:net_spawn(data)
	if not object_binder.net_spawn(self, data) then
	return false
	end
	 
	local section = self.object:section()
	local mark_type = weapons_id[section] or weapons_id["base_id"]
	self.spot = mark_types[mark_type].mark
	local hint = mark_types[mark_type].hint
	or game.translate_string(news_manager.get_inv_name(section))
	level.map_add_object_spot(self.object:id(), spot, hint)
	 
	return true
	end
	 
	function mark_binder:net_destroy()
	if self.spot then
	level.map_remove_object_spot(self.object:id(), self.spot)
	end
	 
	object_binder.net_destroy(self)
	end
	 
	 
	function init(obj)
	local binder = mark_binder(obj)
	obj:bind_object(binder)
	end
	

И всем нужным секциям в конфигах вписать параметр

script_binding = название_скрипта.init

  • Нравится 1
  • Полезно 2

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

Ссылка на комментарий
В 21.06.2019 в 03:47, naxac сказал:

то можно написать такой небольшой биндер

Попробовал... Поймал вылет:

Скрытый текст

FATAL ERROR
[error]Expression    : error handler is invoked!
[error]Function      : invalid_parameter_handler
[error]File          : E:\stalker\sources\trunk\xrCore\xrDebugNew.cpp
[error]Line          : 804
[error]Description   : 
stack trace:

Справочник вылетов говорит о том, что... Данный вылет бывает когда у какого либо из объектов установлено некорректное значение (читал, сам не получал его) Или же если данный вылет происходит при вызове класса, то проблема в том что в методе __init() класса прописано super()

Оно так и есть в скрипте...

function mark_binder:__init(obj)
    super(obj)
end

Хм. Что теперь?

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

@Капрал Хикс, прошу прощения, с телефона писал

вот тут:

level.map_add_object_spot(self.object:id(), spot, hint)

нужно заменить spot на self.spot.

  • Полезно 1

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

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

Благодарствую! Скрипт работает и даже слишком хорошо. :rofl2: В общем, заспавненные мною на землю тестовые Абаканы исправно отображаются метками на карте. Однако при подборе в инвентарь метка вешается и на ГГ и, кроме того, одна метка остаётся висеть на пустом месте (но там, возможно, автомат провалился под землю, ещё проверю). Наверное, стоит прописать исключения для оружия в инвентаре ГГ и у неписей, однако надо ещё придумать, как сделать это.

Изменено пользователем Капрал Хикс
Ссылка на комментарий
6 часов назад, Капрал Хикс сказал:

при подборе в инвентарь метка вешается и на ГГ

Наверно есть необходимость дополнить код условием:

if not self.object:parent() then

level.map_add_object_spot(self.object:id(), self.spot, hint)

else

level.map_remove_object_spot(self.object:id(), self.spot)

end

 

Изменено пользователем gam
  • Спасибо 1
Ссылка на комментарий
11 часов назад, Капрал Хикс сказал:

Наверное, стоит прописать исключения для оружия в инвентаре ГГ и у неписей, однако надо ещё придумать, как сделать это.

Пока на ум приходит только обработка для ГГ и НПСов кэллбэка on_item_take, который срабатывает при появлении в инвентаре последних какого либо предмета - проверять, стоит ли на появившемся объекте известная нам метка и снимать её.

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

@AndreySol

Если я верно понял Вашу реализацию, то как мне представляется - это выглядит таким образом:
gamedata\scripts:
создаем собственный файл скрипта и внутри пишем код функций.
Как пример, af_detect.script:

Скрытый текст


lv_arts = {}
table_art = {}

-- Артефакты
table_art["af_medusa"] = true
table_art["af_cristall_flower"] = true
table_art["af_night_star"] = true
table_art["af_vyvert"] = true
table_art["af_gravi"] = true
table_art["af_gold_fish"] = true
table_art["af_blood"] = true
table_art["af_mincer_meat"] = true
table_art["af_soul"] = true
table_art["af_electra_sparkler"] = true
table_art["af_electra_flash"] = true
table_art["af_electra_moonlight"] = true
table_art["af_rusty_thorn"] = true
table_art["af_rusty_kristall"] = true
table_art["af_rusty_sea-urchin"] = true
table_art["af_ameba_slime"] = true
table_art["af_ameba_slug"] = true
table_art["af_ameba_mica"] = true
table_art["af_drops"] = true
table_art["af_fireball"] = true
table_art["af_cristall"] = true
table_art["af_dummy_glassbeads"] = true
table_art["af_dummy_pellicle"] = true
table_art["af_dummy_battery"] = true
table_art["af_dummy_dummy"] = true
table_art["af_dummy_spring"] = true
table_art["af_fuzz_kolobok"] = true

function checklvl_art()
    for id=1, 65534 do
        local sobj = alife():object(id)
        if sobj then
            if table_art[sobj:section_name()] then
                lv_arts[id] = {}
                lv_arts[id].metka = nil
            end
        end
    end
end

function update()
    local detector
    local activated = db.actor:object("detector_simple")
    if activated then
        local section = activated:section()
        if section then
            detector = section
        else
            detector = nil
        end
    else
        detector = nil
    end
    this.iteratetable_art(detector)
end

-- итерация артов
function iteratetable_art(det_type)
    for k,v in pairs(lv_arts) do
        local sobj = alife():object(k)
        if sobj then
            if det_type == "detector_simple" then
                if not v.metka then
                    if game_graph():vertex(sobj.m_game_vertex_id):level_id() == alife():level_id() then
                        if sobj.parent_id == 65535 then
                            local ini, section = system_ini(), sobj:section_name()
                            if ini and section and ini:section_exist(section) then
                                if not sobj.is_day_night then
                                    level.map_add_object_spot(k, "artefact_location", "артефакт: " .. game.translate_string(ini:r_string(section, "inv_name")))
                                    lv_arts[k].metka = true
                                else
                                    if sobj.online or utils.electro_art_enabled() then
                                        level.map_add_object_spot(k, "artefact_location", "артефакт: " .. game.translate_string(ini:r_string(section, "inv_name")))
                                        lv_arts[k].metka = true
                                    end
                                end
                            end
                        else
                            if v.metka then
                                level.map_remove_object_spot(k, v.metka)
                                lv_arts[k].metka = nil
                            end
                        end
                    end
                end
            end
        else
            lv_arts[k] = nil
        end
    end
end


 


Заполнение таблицы (af_detect.lv_arts = {}) на загрузке в bind_stalker.script: function actor_binder:net_spawn(data). Код: if af_detect then af_detect.checklvl_art()

Но вот далее рассматривать function actor_binder:on_item_take(obj) возможно не совсем корректно, а как-то использовать:

function actor_binder:update(delta) просто стандартным вызовом af_detect.update(). Имхо конечно.

Изменено пользователем W.A.S.P.
спойлер
Добавлено  Опричник,

Длинные тексты пожалуйста под спойлер. Выделить текст и нажать на панели инструментов кнопку с глазом.

  • Полезно 1
Ссылка на комментарий

Здрасьте.

 

ТЧ 1.0006, счетчик лечебных предметов на HUD: статики не скрываются при использовании оптического прицела.

Пробовал добавлять проверку на текущее значение точности – без эффекта.

            if ui_on() or db.actor:accuracy()*1000 < 1 then
                st:Show(false)

 

Как правильно проверить активный оптический прицел?

https://drive.google.com/open?id=1F4OSvmH9l2UBxYgTOAgi0rfUMvQz3yi4

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

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

@Norman Eisenherz, код из солянки:





В amk.get_weapon_data читается нетпакет активной пушки ГГ, чтобы узнать, установлен ли на ней прицел, а в rx_utils.get_addon_status читается значение scope_status из конфига пушки, чтобы проверить, есть ли на ней несъёмный прицел.


    local accuracy = math_ceil(db.actor:accuracy()*1000)

    if accuracy == 1 then

        if not scopeUsed then

            local item = db.actor:active_item()

            if item then

                --get_console():execute("load ~#I#: db.actor:active_item():section()="..tostring(item:section()))

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

                    scopeUsed = true

                elseif IAmAWeapon[item:clsid()] then

                    local t = amk.get_weapon_data(alife():object(item:id()))

                    scopeUsed = (bit_and(t.addon_flags, 1) == 1 or rx_utils.get_addon_status(item, "sc") == 1)

                    --amk.dump_table(t)

                end

            end

        end

    else

        scopeUsed = false

    end

 

  • Полезно 1

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

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

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

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

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

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

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

Войти

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

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

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

AMK-Team.ru

×
×
  • Создать...