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

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

@AndreySol, да, ты правильно понял. Мне нужно передавать состояние предыдущего противогаза - следующему при спавне.

@Artos, спасибо, учту. А что если вот таким макаром?

local obj = actor:object("helm_respirator") 
if obj ~= nil then 
   obj:set_condition(gas_cond) 
end 
Изменено пользователем ColR_iT

AWRP : Re - Load 0.2 ©

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

Akella-96 aka SvD

 

Ну тогда как-то так (с использованием модуля от Artos для работы с нет-пакетами):

объявляем глобально

helmet_spawn = level.client_spawn_manager()
function helmet_spawn_callback(cond, id, obj)     
	obj:set_condition(cond) -- устанавливаем "condition" клиентскому объекту --
end

далее, в del_antigas

 

local antigas = ActorHasItem("helm_respirator")
if antigas then
	local set_cond = antigas:condition()

	local sobj = SpawnItemInInv("helm_respirator_wo_filter")
	if sobj then
		local pk = m_netpk.get(sobj) -- запрос нет-пакета
		if pk and pk:isOk() then
			local data = pk:get() -- читаем данные из нет-пакета
	     		if data and data.upd then
				---- уст. "condition" серверному объекту ----
				data.condition = set_cond
				data.upd.condition = set_cond
				pk:set(data)
			end
		end

		----- уст. кэллбэк на выход клиентского объекта в он-лайн -----
		helmet_spawn:add(sobj.id, -1, helmet_spawn_callback, set_cond)
	end

	local se_obj = alife():object(antigas:id())
	alife():release(se_obj,true)
	awrp_cop.send_tip("Срок действия фильтра закончился.",nil,nil,5,"actor")
	if awrp_cop.has_g_timer("del_antigas") then
		awrp_cop.stop_g_timer("del_antigas")
	end
end

 
 
 
 

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

@AndreySol, огромное спасибо. А в коллбэке на юзание фильтра как эту же плюшку реализовать?

Вот сам коллбэк :

	       local antigas = ActorHasItem("helm_respirator_wo_filter")
	       local gas_cond = antigas:condition()
	       if antigas then
		  awrp_cop.g_start_timer("del_antigas",0,0,15,gas_cond)
		  awrp_cop.send_tip("Срок действия фильтра - 15 минут",nil,nil,5,"actor")
		  SpawnItemInInv("helm_respirator")
		  local se_obj = alife():object(antigas:id())
		  alife():release(se_obj,true)
	       else
		  awrp_cop.send_tip("У вас нет противогаза!",nil,nil,5,"actor")
		  SpawnItemInInv("filtr")
	       end
Изменено пользователем Akella-96 aka SvD

AWRP : Re - Load 0.2 ©

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

@AndreySol, нет смысла дублировать одно и то же разными способами. Т.е. при спавне нового предмета можно или net-пакетом установить требуемое состояние, которое и получит клиентский объект при выходе в он-лайн или коллбэком с переданным ему значением изменить в момент выхода в он-лайн.

Собственно функция (и алгоритм подмены противогаза) может быть такой (без внешних "приблуд"):

function del_antigas()
  local antigas = ActorHasItem("helm_respirator")
  if antigas then --/ проверка: имеется ли у актора "старый" противогаз 
    local item_cond = antigas:condition() --/ определяем износ противогаза
    --/ удаляем старый противогаз:
    local sobj = alife():object(antigas:id())
    if sobj then alife():release(sobj, true) end
    --/ спавним актору новый противогаз
    sobj = SpawnItemInInv("helm_respirator_wo_filter")
    --/ эта функция установит новому противогазу износ от "старого"
    local func_callback = function(item_cond, id, obj) obj:set_condition(item_cond) end
    --/ запускаем кэллбэк на выход клиентского объекта в он-лайн
    level.client_spawn_manager():add(sobj.id, -1, func_callback, item_cond)
  end
  awrp_cop.send_tip("Срок действия фильтра закончился.",nil,nil,5,"actor")
end

 

 

 

 



@Akella-96 aka SvD, в коллбэке на юзание фильтра реализовывай аналогично, вот только(!) перепрочти про АМК-таймеры и научись хотя бы ими пользоваться... Тебе требуется запустить таймер на нужное время, дав ему имя и указав функцию, которая должна сработать (в твоем случае имена совпадают 'del_antigas') .

 

 

 

  local antigas = ActorHasItem("helm_respirator_wo_filter")
  if antigas then
    awrp_cop.g_start_timer("del_antigas",0,0,15,"del_antigas") --/ проверь имена!
    awrp_cop.send_tip("Срок действия фильтра - 15 минут",nil,nil,5,"actor")
    local sobj = alife():object(antigas:id())
    if sobj then alife():release(sobj,true) end
    SpawnItemInInv("helm_respirator")
  else
    awrp_cop.send_tip("У вас нет противогаза!",nil,nil,5,"actor")
    if not ActorHasItem("filtr") then
      SpawnItemInInv("filtr")
    end
  end
Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

@Artos, спасибо большое. А где можно прочитать про таймеры?
А то неудобно так, каждый раз кричать "На помощь!". Да и вообще, надо расширять познания  :)

AWRP : Re - Load 0.2 ©

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

Artos

Дублирование возникло не спроста - как-то разбираясь с вопросом "заспавнить в инвентарь предмет с установкой ему требуемого состояния(condition)", обнаружил что для некоторых "инвентарных" предметов получается такая картина: если после создания предмета установить condition серверному объекту через нет-пакет, то при выходе клиентского объекта в он-лайн его condition = 100%, т.е. видимо нет синхронизации с серверным. А при сохранении и последующей загрузке уже устанавливается тот condition, что задали ранее нет-пакетом для серверного объекта. Потому и использую дублирование, т.к. оно обеспечивает "полную" установку condition и сохранение его после сохранения\загрузки.

 

P.S. Всех объектов, с которыми эксперементировал, не упомню, но точно помню что для артефактов была именно такая картина. Все это на чистом ТЧ 1.0005.

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

@AndreySol, не нужно оправдывать по сути чепуху(!). Если ты коллбэком на выход в онлайн ставишь требуемое значение состояния предмета, тем самым ПЕРЕКРЫВАЯ любые ранее заданные значения для серверного объекта, то на кой заморочка с нет-пакетами?!  :crazy:

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

Также, допускают ошибку, когда сначало спавнят предмет, например в то же инвентарь, а через некоторое время, а не сразу же в цикле спавна, net-пакетом пытаются изменить параметр(ы)... естественно, пока предмет не уйдет в оффлайн и не вернется в онлайн (вот он сэйв-лоад!) - то ничего не меняется.

Ну и, есть конечно некоторые параметры у некоторых предметов (например у КПК), которые требуют особого подхода, но тут уж именно только нет-пакетами и спавн не в инвентарь, а с последующим трансфером...

 

В общем, в данном случае с противогазами актора нет никакого смысла в дублировании net-пакетами!

 

@Akella-96 aka SvD, кратко про амк-таймеры помянул выше. Расписывать неизвестный мне  скрипт 'awrp_cop' не имею возможности и желания.

По оригиналному скрипту от амк - воспользуйся поиском по многочисленным ресурсам в сети по моддингу. А еще лучше - замени на нормальные таймеры...

А вообще, скрипт (script) - это сценарий, в котором все и описано, и тебе нужно бы почитать мануалы по Lua, чтобы читать и понимать то, что в скрипт кто-то когда-то написал и как это нужно/можно применять (раз уж используешь не свое).

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Artos

Тестовая ф-ция:

function spawn_and_set_cond()
 local ser_obj = alife():create("af_dummy_pellicle", npc:position(), npc:level_vertex_id(), 
npc:game_vertex_id(), npc:id())
 if ser_obj then
  local pk = m_netpk.get(ser_obj) -- запрос нет-пакета
  if pk and pk:isOk()then
   local data = pk:get() -- читаем данные из нет-пакета
   if data and data.upd then
    data.condition     = 0.5
    data.upd.condition = 0.5
    pk:set(data)
   end
  end
 end
end

 

 

Инвентарь ГГ пуст, вызываю эту ф-цию. Открываю инвентарь - вижу там появившийся артефакт, кликаю по нему - полоска состояния полная, т.е. condition 100%. Закрываю инвентарь, сохраняюсь и сразу загружаю сохранение, открываю инвентарь, кликаю по артефакту - теперь полоска состояния ровно на половину. Все это, как я и указывал ранее, для чистой ТЧ 1.0005. В чем Вы видите оправдывание чепухи ? Повторите у себя - неужели у Вас артефакт будет с 50% condition ?

Akella-96 aka SvD работает судя по всему с СоР, может там иначе...

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

@AndreySol, если искать себе искуственные заморочки - то их всегда можно найти!  :crazy:

Вот только зачем их искать и навешивать шоры себе же и другим?

Раз спавним актору в рюкзак, то и используем простейшее:

local sobj = alife():create("af_medusa", vector(), 0, 0, db.actor:id())
local func_callback = function(item_cond, id, obj) obj:set_condition(item_cond) end
level.client_spawn_manager():add(sobj.id, db.actor:id(), func_callback, 0.55)

 - открываем и видим покоцанную медузу...
Ну а для твоей заморочки могу посоветовать - а подумай ка и ответь, а твой артефакт вообще то вышел в онлайн в полном смысле? Тебя не смущает то, что предмет, попав сразу же в рюкзак, так и не был полностью "увиден" игрою?! Вот и не переданы параметры от серверного клиентскому.
Или можно отправить твоего перса (раз это не актор), вместе со всем своим хабаром в оффлайн и обратно - и будет смена состояния предмета.
Ну а если актор и если уж хочешь заморачиваться с нет-пакетами, то спавни рядом с актором и транфери предмет по тому же коллбэку выхода в онлайн, без set_condition - и получишь то же самое!
Суть: не нужно пытаться микроскопом забивать гвозди, когда для этого имеется молоток.
 
Ну а по "работает с CoP" - это ясно из контекста, но таймеры - они и в африке таймеры. ;-)
Изменено пользователем Artos
  • Нравится 2

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Подскажите как в тч (амк) будет выглядеть задание sid для тайника при спавне, пробывал так:

function rukzak_spawn()
local sobj = alife():create("habar_ruck",vector():set(-215,-22.5,-125),39266,59)
local tbl = amk.get_invbox_data(sobj)
tbl.sid = 97125
amk.set_invbox_data(tbl,sobj)
end

но помоему sid не задается

 

Тайник нужно вывести в онлай и обратно, для того чтобы стори_айди заработал.

ColR_iT

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

S.T.A.L.K.E.R 1.004, Народная..Солянка от 19.04.10, дополнение 14.08.10, патч 3.09.10, DMX 1.3.5, Saruman addon 1.1

Vkontakte

Добавление нового транспорта в сталкер

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

Имеем диалог, генерируемый скриптовой функцией, т.е. в xml-файле тег init_func
функция такого вида

function generate_dyn_dialog(dlg)
---// получение ряда данных из других скриптов
main_generator(dlg,<аргументы>)
end

где main_generator - собственно функция, занимающаяся формированием диалога. Формирование происходит в момент обращения ГГ к неписю, у которого в профиле записан диалог ссылающийся на нее. Вопрос собственно вот в чем: как мне в этот момент узнать и передать в функцию main_generator - ID непися, к которому произошло обращение. Для получения его клиентского объекта, и также для чтения его pstor.

 

Пробовал таким образом:

bind_stalker.script

---// коллбек на юзание объекта
function actor_binder:OnUseObject(obj, who)
if obj then
    local section = obj:section()
if section then
    if ltx:line_exist(section, "script_by_used") then
    local func = ltx:r_string(section, "script_by_used")
    local flist = used.re()
    flist[func](obj)
    end
end
end
end

в секции конфига [stalker] добавляется строка

script_by_used = start_custom_dialog

used.script имеет функцию

function re()
return funtable
end

funtable - таблица имеющая ключи в виде строк, и значения в виде функций.

В ней есть такая:

    start_custom_dialog = function(obj)
        if obj then
            local id = obj:id()
            dialogs_global.Set_remote_speaker_id(id)
            ---// передача ID объекта туда, откуда он может быть получен функцией main_generator
        end
    end,

Но, проблема в том что коллбек юзания объекта не вызывается при нажатии F на живом НПС с которым можно вести диалог. Пока писал, родилась другая идея - поставить этому НПС старт-диалог, отличный от дефолтного, и в нем, получив 1 и 2 собеседников, выяснять его ID и передавать куда следует. Но опять же нет уверенности что сработает, что происходит раньше - выполнение action-тегов старт-диалога, или обращение к main_generator-у для генерации прочих диалогов которые должны стать доступны следом. Если второе, то я опять не успеваю узнать ID непися... как то так.

 

 

Заранее благодарю за советы по делу.

 

Upd. Метод старт-диалога сработал. Пост на усмотрение модератора.

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

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

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

@Zander_driver, не знаю, имеет ли это значение в этом конкретном случае, но напомню, что диалог таким образом формируется не просто в момент вызова этой функции generate_dyn_dialog, а строго при первом вызове этой функции. При всех последующих вызовах вплоть до выхода из программы (т.е. в том числе и после загрузки другого сейва) будет использоваться уже сформированный диалог. Я об этом расписывал подробнее здесь (там в примечаниях под спойлером). Это так на всякий случай напоминаю, поскольку этот факт является причиной ошибок, когда люди ожидают динамического формирования диалога всякий раз, а он на самом деле не меняется.

 

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

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

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

 

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

ColR_iT, а не подскажешь как его перевести в оффлайн(я думаю ты именно это имел ввиду) и обратно? 

S.T.A.L.K.E.R 1.004, Народная..Солянка от 19.04.10, дополнение 14.08.10, патч 3.09.10, DMX 1.3.5, Saruman addon 1.1

Vkontakte

Добавление нового транспорта в сталкер

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

Об этом я в курсе. более того, если верить моим тестам, функция generate_dyn_dialog вызывается лишь при первом обращении к данному нпс. Потом и диалог заново не формируется, и сама функция - не вызывается. Однако у меня эта функция используется для разных диалогов, имеющих разные id в xml-файле. таким образом, движок не считает что это один и тот же диалог. И вызывает мою функцию тогда когда требуется. плата за это - несколько большая ресурсоемкость... но что поделать.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

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

Сталкер тч.

Подскажите почему не меняется отношение групировки к актору.

relation_registry.set_community_goodwill ("stalker", db.actor:id(), 0)

 

 

 

-- Если игрок выбрал групировку "Бандиты" или "Свобода"(в начале игры)
-- делаем нетральными долг и других участников бара.
-- условия ГГ должен снять или надеть броню любой другой групировки
local bComOut = false

function bar_dolg_fix()
    local actor_community = db.actor:character_community()
    local actor_outfit = db.actor:item_in_slot(6)
    local lev = level.name()
	
    if lev == "l05_bar" then
        if not bComOut then
            if actor_community=="actor_bandit" or actor_community=="bandit" then
		if actor_outfit == nil or(actor_outfit and not string.find(actor_outfit:section(),"bandit_") and not string.find(actor_outfit:section(),"svoboda_"))then
                    relation_registry.set_community_goodwill ("stalker", db.actor:id(), 0)
		    relation_registry.set_community_goodwill ("dolg", db.actor:id(), 0)
		    relation_registry.set_community_goodwill ("stranger", db.actor:id(), 0)
		    bComOut = true
		    --log1("Меняем отношение групировок")
		end	
	    elseif actor_community=="actor_freedom" or actor_community=="freedom" then
		if actor_outfit == nil or(actor_outfit and not string.find(actor_outfit:section(),"svoboda_") and not string.find(actor_outfit:section(),"bandit_"))then
                    relation_registry.set_community_goodwill ("dolg", db.actor:id(), 0)
		    bComOut = true
		    --log1("Меняем отношение групировок")
		end	
            end 			
	end
    else		
	if bComOut then
	    if actor_community=="actor_bandit" or actor_community=="bandit" then
                relation_registry.set_community_goodwill ("stalker", db.actor:id(), -5000)
		relation_registry.set_community_goodwill ("dolg", db.actor:id(), -5000)
		relation_registry.set_community_goodwill ("stranger", db.actor:id(), -5000)
		bComOut = false
		--log1("Возвращаем отношение групировок")
	    elseif actor_community=="actor_freedom" or actor_community=="freedom" then
                relation_registry.set_community_goodwill ("dolg", db.actor:id(), -5000)
		bComOut = false
		--log1("Возвращаем отношение групировок")
	    end			
	end
    end 
	
end

 

 

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

Stalkersof

Попробуй так:

game_relations.set_factions_community(p[1], p[2], p[3])

p[1], p[2] - группировки

p[3] - отношение(enemy, neutral, friend)

 

P.S. Попробуй во втором параметре записать "actor"  :)

Изменено пользователем Старлей
  • Не нравится 1
Ссылка на комментарий

Старлей. Может ошибаюсь но вроде нет в тч game_relations.set_factions_community(p[1], p[2], p[3])

А так пробывал

relation_registry.set_community_goodwill ("stalker", db.actor:id(), 0)

relation_registry.set_community_goodwill ("stalker", "actor", 0)

Но есть такое дежавю что работало. Не пойму чего ему не хватает, log1 в консоль пишет скрипт выполняется. Не меняются отношения групировок и все :)

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

@Saruman, а с чего ты решил что "но помоему sid не задается", Если ты не покорежил функции net-пакетов, то все прекрасно задается.

И, при установке SID'а в момент спавна объекта не требуются манипуляции с off-on-лайнами, т.е. значение заданное параметру доступно сразу (для клиентского объекта - по выходу его в онлайн).

 

Только особенность проверки свеже-добавленного SIDa в базе движка имеет нюанс и не стОит использовать alife():story_object(SID) до перезапуска игры или манипуляций с off-on-лайнами.

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

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

Artos просто у меня там функция другая использует этот тайник, сам тайник спаунится вначале игры, после разговора с нпс запускается та функция и если нет сида этого тайника то она не срабатывает, но если перед этим перезагрузиться то она прекрасно работает

функция actor:transfer_item(obj, box)

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

S.T.A.L.K.E.R 1.004, Народная..Солянка от 19.04.10, дополнение 14.08.10, патч 3.09.10, DMX 1.3.5, Saruman addon 1.1

Vkontakte

Добавление нового транспорта в сталкер

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

@Saruman, следует все же различать собственно  наличие сида у объекта и наличие этого сида в базе алайфа  (в игре).

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

Вообще, немало и других способов "искать" требуемый объект в игре... чем тебе (для ТЧ) тот же поиск заспавненного объекта по имени не подходит alife():object("my_obj_name") ? Может и не так "красив" как по сиду, но не менее эффективен и дает тот же результат. ;-)

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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

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

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

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

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

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

Войти

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

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

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