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

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

@Krolevarka Позвольте вмешаться: нужен ли вообще инфо-поршень, если действие выполняется один раз на перезагрузку? Может, достаточно будет такого варианта:

Spoiler

[scripts\bind_stalker.script]
function actor_binder:update(delta)
	object_binder.update(self, delta)
(+)
	if not db.actor:alive() then
		if not death_msg then
			death_msg = true
			news_manager.send_tip(…)
		end
	end

 

 

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

Шпаргалка

Ссылка на комментарий
39 минут назад, Norman Eisenherz сказал(а):

нужен ли вообще инфо-поршень

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

2 часа назад, Krolevarka сказал(а):

В bind_stalker создал проверку жив ли actor. Если не жив, то

...То почему бы не отправить сообщение прямо оттуда? Из колбека on_death или hit...

 

@Norman Eisenherz, апдейт теребить для этого совсем не требуется. И, это более вредно, чем теребить без надобности инфопоршни.

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

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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 Попадалась где-то инфа, что колбэки hit и death для ГГ не действуют – только для NPC и мутантов. Проверил в ТЧ и ЗП: действует только death.

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

Шпаргалка

Ссылка на комментарий
1 час назад, Norman Eisenherz сказал(а):

действует только death.

Ну так этого и достаточно. Для обсуждаемой затеи.

hit, если зачем-нибудь надо и хочется, отремонтирован начиная с X-Ray Ext и далее практически везде, включая OGSR.

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

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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 Попробую. Я скриптами только недавно начал заниматься. Я и не думал, что on_death есть и у actor-а тоже.

@Norman Eisenherz У меня не сработало. Сообщение не отправилось.

@Zander_driver Я сначала подумал про All.spawn, но как я понял вы говорите про другое(Поправьте если всё-таки про All.spawn). Я не понимаю почему так важно не трогать поршни. Вообще не понял, что и как нужно тогда сделать. Если изучу скрипты в сталкере получше, то может быть пойму что вы мне написали.

Ссылка на комментарий
41 минуту назад, Krolevarka сказал(а):

Я не понимаю почему так важно не трогать поршни.

Потому что, это не требуется для обсуждаемой затеи. Вообще никаким боком.

Отвлеченный пример:

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

А Петя в курсе, что можно просто нажать на выключатель, и свет включится.

 

Вот вы меня спрашиваете - почему так важно не разбивать посуду, и не ронять мебель в доме... если хочется включить свет... Может и не важно. :pardon: Хозяин барин, как поступать в своем доме. Можно заниматься ритуалами... но без них проще.

54 минуты назад, Krolevarka сказал(а):

Вообще не понял, что и как нужно тогда сделать.

Просто отправьте свое сообщение из функции on_death в bind_stalker.script. Напишите там news_manager.send_tip(что хотите...), и... всё.

  • Полезно 1
  • Смешно 4

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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.

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

Вылетает игра с такой ошибкой:
gamedata\scripts\rx_ff.script:164: attempt to index field 'ammo' (a nil value)

Прилагаю LUA код, заранее спасибо, кто поможет решить.

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

---- AI Additions ----
---- Rulix aka Bak ----
---- 29.7.2009,06.01.2016

function printf(s, ...)
--	rx_utils.printf("ff:"..s,...)
end

ASSERTX(rx_ai.rx_ini:section_exist("ff"),"no section [ff] in rx_ini")
local forbidden_factions = rx_utils.parse_list(rx_ai.rx_ini,"ff","forbidden_factions",true)
local forbidden_npcs = rx_utils.parse_list(rx_ai.rx_ini,"ff","forbidden_npcs",true)

class "evaluator_dont_shoot" (property_evaluator)
function evaluator_dont_shoot:__init(npc,name,storage) super (nil,name)
	self.st = storage
end
function evaluator_dont_shoot:evaluate()
	local npc = self.object
	local enemy,slot = npc:best_enemy(),npc:active_slot()
	local res = false
	if enemy and (slot == 2 or slot == 1) then
		local wpn = npc:active_item()
		if wpn and not enemy:wounded() and wpn:get_ammo_in_magazine() > 0 then
			if npc:see(enemy) or rx_utils.get_weapon_state(wpn) == rx_utils.EWeaponStates.eFire then
				res,self.st.vdist = friends_on_fire_line(npc)
			end
		end
	end
	self.storage:set_property(evid_dont_shoot,res)
	return res
end

local function get_vertex(npc,dist)
	local rnd1,ang = math.random(100)
	if rnd1 < 43 then
		ang = math.random(40,70)
	elseif rnd1 < 58 then
		ang = math.random(150,210)
	else
		ang = math.random(290,320)
	end
	local dir = vector_rotate_y(npc:direction(),ang)
	return npc:vertex_in_direction(npc:level_vertex_id(),dir,dist)
end

class "action_verso" (action_base)
function action_verso:__init (npc,action_name,storage) super (nil,action_name)
	self.st = storage
end
function action_verso:initialize()
	action_base.initialize(self)
	local npc = self.object
	self.is_camper = db.storage[npc:id()].script_combat_type == "camper" or db.storage[npc:id()].active_scheme == "camper" and not npc:motivation_action_manager():evaluator(xr_evaluators_id.stohe_camper_base+2):evaluate()
	if npc:path_completed() then
		npc:set_desired_position()
		npc:set_desired_direction()
	end
	npc:set_mental_state(anim.danger)
	npc:set_item(object.aim1,npc:active_item())
	local enemy = npc:best_enemy()
	if not self.is_camper then
		state_mgr.set_state(npc,"assault",nil,nil,{look_object = enemy},{animation = true})
	else
		state_mgr.set_state(npc,state_mgr.get_state(npc),nil,nil,{look_object = enemy},{animation = true})
	end
end
function action_verso:execute()
	action_base.execute(self)
	if self.is_camper then
		return
	end
	local npc = self.object
	if not self.vertex and not npc:path_completed() and npc:movement_type() ~= move.stand then
		return
	end
	if not self.vertex or npc:path_completed() or self.timer < time_global() then
		self.vertex = get_vertex(npc,self.st.vdist)
		self.timer = time_global()+800*self.st.vdist
	end
	if self.vertex then
		npc:set_dest_level_vertex_id(self.vertex)
	end
end
function action_verso:finalize()
    action_base.finalize(self)
	self.vertex = nil
	local npc = self.object
	if not npc:alive() then
		return
	end
	rx_sound.block_alarm_sound(npc)
	state_mgr.set_state(npc,"idle")
end

evid_dont_shoot = rx_ai.base_id+25
actid_dont_shoot = evid_dont_shoot

function add_to_binder(npc,ini,scheme,section,storage)
	local manager = npc:motivation_action_manager()
	if forbidden_factions[npc:character_community()] or forbidden_npcs[npc:name()] or forbidden_npcs[npc:section()] or not npc:alive() then
		manager:add_evaluator(evid_dont_shoot,property_evaluator_const(false))
		return
	end
	manager:add_evaluator(evid_dont_shoot,evaluator_dont_shoot(npc,"eva_dont_shoot",storage))
	local action = action_verso(npc,"act_dont_shoot",storage)
	action:add_precondition(world_property(stalker_ids.property_alive,true))
	action:add_precondition(world_property(xr_evaluators_id.sidor_wounded_base,false))
--	action:add_precondition(world_property(stalker_ids.property_danger_grenade,false))
	if rx_bandage then
		action:add_precondition(world_property(rx_bandage.evid_bandage,false))
	end
	if rx_gl then
		action:add_precondition(world_property(rx_gl.evid_gl_fire,false))
		action:add_precondition(world_property(rx_gl.evid_gl_reload,false))
	end
	if rx_facer then
		action:add_precondition(world_property(rx_facer.evid_facer,false))
	end
	if rx_knife then
		action:add_precondition(world_property(rx_knife.evid_knife_attack,false))
	end
	if rx_kill_wounded then
		action:add_precondition(world_property(rx_kill_wounded.evid_enemy_wounded,false))
	end
	if xrs_grenade then
		action:add_precondition(world_property(xrs_grenade.evid_crazy_grenadier,false))
		action:add_precondition(world_property(xrs_grenade.evid_aaa_grenade,false))
		action:add_precondition(world_property(xrs_grenade.evid_psyh,false))
	end
--	if blowout_scheme and blowout_scheme.evid_outside then
--		action:add_precondition(world_property(blowout_scheme.evid_outside,false))
--	end
	action:add_precondition(world_property(evid_dont_shoot,true))
	action:add_effect(world_property(evid_dont_shoot,false))
	manager:add_action(actid_dont_shoot,action)
	-- включение в планировщик
	action = manager:action(stalker_ids.action_combat_planner)
	action:add_precondition(world_property(evid_dont_shoot,false))
end

function set_scheme(npc,ini,scheme,section)
	local st = xr_logic.assign_storage_and_bind(npc,ini,scheme,section)
end

local disp_stor = {}
local disp_time = {}
local sini = system_ini()
local function get_weapon_dispersion(npc)
	local wpn = npc:active_item()
	if not (wpn and rx_utils.item_is_fa(wpn)) then
		return 0
	elseif (disp_time[wpn:id()] or 0) > time_global() then
		return disp_stor[wpn:id()]
	end
	local section = wpn:section()
	local base = sini:r_float(section,"fire_dispersion_base")*math.pi/180
	local condition_factor = 1 + sini:r_float(section,"fire_dispersion_condition_factor")*(1-wpn:condition())
	local silencer = 1
	if rx_utils.addon_attached(wpn,"sl") then
		local ss = rx_utils.read_from_ini(nil,section,"silencer_name","__",1)
		silencer = rx_utils.read_from_ini(nil,ss,"fire_dispersion_base_k",1)
	end
	local wm = npc:get_wm(true)
	local ammo,as = wm and wm.ammo[section]
	if ammo and ammo._c and ammo._c ~= true then
		as = ammo._c
	else
		local amt = rx_wmgr and rx_wmgr.read_wpn_params(section).amt or rx_utils.parse_list(nil,section,"ammo_class")
		as = #amt == 1 and amt[1] or amt[rx_utils.get_ammo_type(wpn)+1]
	end
	local k_disp = sini:r_float(as,"k_disp")
	local result = base*silencer*k_disp*condition_factor
	disp_stor[wpn:id()] = result
	disp_time[wpn:id()] = time_global()+50000
--	printf("get_current_dispersion[%s][%s]base %s silencer %s k_disp %s condition_factor %s","",wpn:name(),base,silencer,k_disp,condition_factor)
--	printf("get_current_dispersion[%s][%s] %s",npc:name(),wpn:name(),result)
	return result
end

local min_check_prd = 250	-- проверка друзей примерно 4 раза в секунду
function friends_on_fire_line(npc)
	local sid = npc:id()
	local st = rx_ai.get_storage(sid,"fofl")
	local tg = time_global()
	if (st.wait or 0) >= tg then
		return st.f,st.d
	end
	local enemy = npc:best_enemy()
	local npc_pos = npc:bone_position("bip01_l_finger02")
	local enemy_pos = enemy:bone_position("bip01_spine")
	if rx_knife then
		local ktrg = rx_knife.targets[enemy:id()]
		if ktrg and ktrg ~= sid then
			local hunter = level.object_by_id(ktrg)
			if hunter and npc:relation(hunter) ~= game_object.enemy and npc:see(hunter) then
				local h_dist = hunter:position():distance_to_sqr(enemy_pos)
				if h_dist < 13 and h_dist+1 < npc_pos:distance_to_sqr(enemy_pos) then
					st.f,st.d = true,5
					st.wait = tg+2000
					return true,5
				end
			end
		end
	end
	local dir_aim = enemy_pos:sub(npc_pos)
	local be_dist = dir_aim:magnitude()
	if be_dist > 3 then
		local disp = get_weapon_dispersion(npc) + 0.025	--npc:accuracy()
		local aH,aP = dir_aim:getH(),dir_aim:getP()
		for o in npc:memory_visible_objects() do
			local friend = o:object()
			if friend and friend.clsid and friend:alive() and friend:id() ~= sid then
				if IsStalker(friend) and npc:relation(friend) ~= game_object.enemy then
					local friend_dir = friend:center():sub(npc_pos)
					local friend_dist = friend_dir:magnitude()-0.5
					if friend_dist < be_dist then
						local fH,fP = friend_dir:getH(),friend_dir:getP()
						local f = disp+0.28/friend_dist
						if (aH > fH and aH-fH or fH-aH) < f and (aP > fP and aP-fP or fP-aP) < f*1.8 then
							if not friend:wounded() or (aP > fP and aP-fP or fP-aP) < f*0.5 then
								st.f = true
								st.d = math.min(25,4*be_dist/(be_dist-friend_dist))
								st.wait = tg+1500
								return true,st.d
							end
						end
					end
				end
			end
		end
	end
	st.wait = tg+min_check_prd
	st.f,st.d = false,4
    return false,4
end

 

 

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

Очень часто встречал такой скрипт:

function название скрипта(actor, npc)                                            
    npc:force_set_goodwill(-5000, actor)
end

Знающие люди сказали, что в ТЧ глобально нет такой функции. Однако встречал данный скрипт и здесь:

http://stalkerin.gameru.net/wiki/index.php?title=Полезные_методы_и_функции

И здесь:

https://stalker-modding.at.ua/publ/stati_stalker_modding_at_ua/sbornik_gotovykh_skriptov/1-1-0-1

Я решил использовать её у себя в игре, но происходил вылет:

 

FATAL ERROR
 
[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: ...obyl\gamedata\scripts\volk_2_dialog_after_hit.script:14: attempt to call method 'force_set_goodwill' (a nil value)

 

Если этот скрипт все-таки нельзя использовать, то как можно изменить отношение персонажа к актеру и наоборот, чтобы использовались показатели из файла game_relations?

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

@Rod_K поищи "goodwill" в lua_help.script. Там есть два метода для изменения отношения через клиентский объект. Если сам не найдешь - обращайся сюда.

 

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

Или туда

 

  • Нравится 2
  • Согласен 1

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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.

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

@dsh Спасибо, "set_goodwill" сработала. Только я предполагал, что нпс станет другом/врагом при условии, если значение будет составлять 5000 и -5000 соответственно, но, как выяснилось, достаточно перейти в положительное\отрицательное исчисление, чтобы изменить отношение нпс к актору. Как можно изменить эти значения, чтобы именно со значения 5000 нпс стал дружить с актором? В game_relations такого конкретно что-то не заметил.

 

И, впоследствии, реально будет прописать условия в скриптах, типо если показатель отношения нпс к актору сосавляет, допустим, 2500, то выдается поршень о начале нового диалога?

Ссылка на комментарий
23 minutes ago, Rod_K said:

В game_relations такого конкретно что-то не заметил.

Именно там. Сходу сейчас вспомнить не могу, там указываются величины отношений для друг/враг. И к тому же не забывай, финальное отношение - это сумма нескольких компонентов: отношение с группировкой, персональное отношение, репутация и чего там ещё есть. Поэтому то, что ты выставишь -5000, не означает, что он станет врагом, если у актора 9000 с его группировкой, т.к. финальное отношение станет 4000.

 

23 minutes ago, Rod_K said:

типо если показатель отношения нпс к актору сосавляет, допустим, 2500, то выдается поршень о начале нового диалога?

В оригинальном движке, наверное, только как-то на апдейте ловить, а в x-ray extensions и других, если не ошибаюсь, был какой-то коллбек на эту тему.

Изменено пользователем dsh
  • Спасибо 1
Ссылка на комментарий
15 часов назад, Rod_K сказал(а):

если показатель отношения нпс к актору сосавляет, допустим, 2500, то выдается поршень

Можно эту проверку для диалога сделать прекондишеном.

  • Согласен 2

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

naxac.gif

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

Позвольте простой вопрос. Вот есть скрипт: bind_stalker.script

В нём функция-обработчик колбека: function stalker_binder:use_callback(obj, who) 

Задача: вызвать обработчик для моего объекта myobj вручную: 

Что-то вроде того: myobj:bind_stalker.stalker_binder:use_callback(myobj, db.actor)

Пробовал запись в разных комбинация, но всегда краш. Есть ли такая возможность?

 

 

Ссылка на комментарий
Только что, dsh сказал(а):

если я нигде не напутал.

Это вызовет метод в биндере myobj. Если у него конечно, есть биндер, что совсем не факт.

1 час назад, phalcor сказал(а):

Задача: вызвать обработчик для моего объекта myobj вручную: 

Что такое "обработчик" в данном случае. И причем тут биндер ГГ - пока остается загадкой. Что сделать-то хотел? Простыми словами, по-русски.

  • Нравится 2

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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.

Ссылка на комментарий
3 часа назад, dsh сказал(а):

myobj:object_binder():use_callback()

Не сработало, вылет: attempt to call method 'object_binder' (a nil value)

2 часа назад, Zander_driver сказал(а):

Что сделать-то хотел?

Есть недоступный трупик сталкера. Я хочу сымитировать нажатие кнопки "F" (использовать) на этом трупике - а точнее, чтобы выполнились все те действия, которые выполнились бы при реальном нажатии кнопки "F" на трупике - выдача секрета, зомби-удар и прочее. 

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

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

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

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

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

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

Войти

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

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

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