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

Скриптование


Svoboда

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

(изменено)

Подскажите, кто знает:

имеются некие координаты (допустим - 1,2,3), как с помощью скрипта определить level_vertex или game_vertex по ним.

 

 

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

Поделиться этим сообщением


Ссылка на сообщение
h0N0r, stalkerin.gameru.net

Ищи LVID_GVID script

 

Этот скрипт определяет позицию гг, а нужно по известным координатам на уровне определить их level_vertex или game_vertex (без участия гг, спавн или телепорт на эти координаты).

 

Поделиться этим сообщением


Ссылка на сообщение

Музафир

 

function erase_actor_inv()
   local function keep_list_itm(item)
      if (item:section() ~= "wpn_binoc"
      or item:section() ~= "device_torch"
      or item:section() ~= "device_pda"
      or item:section() ~= "bolt")
      then
         alife():release(alife():object(item:id()), true)
      end
   end
   db.actor:inventory_for_each(keep_list_itm)
end

 

  • Не нравится 1

Поделиться этим сообщением


Ссылка на сообщение
(изменено)
Romz, Некоторым спавн-объектам (нпс, смарты, аномалии, пути) нужны точные gv\lv-vertex, что и делает компилятор (xr_ai) при сборке спавна. Но из скрипта видно, что используется начальный gv и рандомный lv, и возможно именно из-за этого возникают проблемы, хотя если создавать аномалии в самом спавне (пакуя его acdc) и используя начальные gv\lv - то никаких проблем. Как пример с ошибкой, добавил с десяток смарт-коверов на янов с gv\lv = 317, 1231404 - так после смены уровня, те кто находился в них - оказывались в правом верхнем углу уровня (район аномалии "плавни"), а при переходе в онлайн - дружно бежали обратно на станцию. В тоже время, различные рестрикторы, секции physic_object и некоторые другие, данным методом нормально создаются. Возможно это зависит (чтобы точно узнать, нужно изучать исходный код игры) от стадий загрузки текущего уровня (в логе это - Сервер: Загрузка симуляции жизни... и т.д), и когда гг на одной локации, а создаёшь на другой, предполагается, что необходимые стадии выполнены (типа - Загрузка ИИ объектов... т.п). Изменено пользователем Dennis_Chikin
  • Нравится 1

Поделиться этим сообщением


Ссылка на сообщение
Понадобилось заспавнить немного лута на локе (сверх того, что расставлено через сдк), но у способа через скрипт (alife():create) есть недостаток - предмет оказывается на ближайшей аи-ноде, что делает невозможным спавнить данным методом на крышах и т.п. В сдк просто - выключил у предмета "used ai locations", и всё нормально.
 
Немного поизучал, что от чего зависит, и в итоге добавил "self:use_ai_locations(false)" в se_item.script (на примере se_eatable (ЗП) - аптечки, еда):
function se_eatable:on_register()
    ...
    self:use_ai_locations(false)
end

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

 

Поделиться этим сообщением


Ссылка на сообщение

Немного попроще, сделать спецметку в \ui\map_spots.xml,

 

<green_location_store store="1">
    <level_map spot="green_spot" pointer="quest_pointer"/>
    <mini_map spot="green_mini_spot" pointer="quest_pointer"/>
</green_location_store>

 

store="1" - сохранять ли отметку при сохранении игры (если не задано, не сохраняется), может отсутствовать.
ttl="3" - время жизни отметки (например подсветить на несколько секунд объект, и не заботиться о том, чтобы потом снять), может отсутствовать.
no_offline="1" - не показывать отметку, если объект в offline (если не задано, показывается), может отсутствовать.
hint="general_wounded" - подсказка, при наведении, может отсутствовать.


Ставить метку через map_add_object_spot(number, string, string), но нужна функция, чтобы получить секцию / профиль нпс и передать полученное в number.

Поделиться этим сообщением


Ссылка на сообщение
В 22.06.2018 в 06:15, Egor4ikModMaker сказал:

А можно полную ф-цию , я в скриптах не шарю , так что прошу помощи у вас.

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

 

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

Вот такую функцию добавь в конец xr_effects.script,


function add_spot_to_npc(actor, npc, p)
	if p[1] == nil then
		abort("Invalid parameter in function 'add_spot_to_npc', enter the profile_name!")
	end
	if p[2] == nil then
		abort("Invalid parameter in function 'add_spot_to_npc', enter the mapspot from map_spots.xml!")
	end
	if p[3] == nil then
		abort("Invalid parameter in function 'add_spot_to_npc', enter the hint!")
	end
	for a=1,65535,1 do
		local obj = alife():object(a)
		if obj and IsStalker(obj) and obj:profile_name() == p[1] then
			level.map_add_object_spot(obj.id, p[2], tostring(p[3]))
		end
	end
end

Потом её можно будет вызвать из любого другого скрипта:


function my()
	...
	xr_effects.add_spot_to_npc(nil, nil, {"bar_ecolog_professor", "blue_location", "ros_kruglov_name"})
	...
end

bar_ecolog_professor - профиль из \gameplay\character_desc_.xml
blue_location - вид метки из \ui\map_spots.xml
ros_kruglov_name - имя (если есть, но не используем при GENERATE_NAME_) из \gameplay\character_desc_.xml. Можно свой текст (типа kruglov_4udila_pret_v_anomaluu), но так игнорируются пробелы, так что, если длинная подсказка, то делаем в \text\rus\string_table_mapspots_.xml свою и используем её ид.

 

Также можно вызвать из любого файла логики (нпс, объекты):


логика рестриктора,

[logic]
active = sr_idle@start

[sr_idle@start]
on_info = {+bar_rescue_research_start} sr_idle@end %=add_spot_to_npc(bar_ecolog_professor:blue_location:ros_kruglov_name)%

[sr_idle@end]

Но всё это фигня, лучше скачай себе acdc (поставишь сид), сможешь нормально ставить метки. Ещё и сдк установи, а то сегодня метки, завтра локи править понадобиться.

 

Поделиться этим сообщением


Ссылка на сообщение

@Pug-Lover, у тебя функции (bndgcheck... fooddlt) в середине function main_menu:OnKeyboard - перемести их в конец файла.

 

@dPlayer, в ТЧ есть такая проверка (xr_conditions.script), перед барьером на складах.

function mil_actor_enemy_freedom(actor, npc)
	if relation_registry.community_goodwill("freedom", actor:id()) < -500 then
		return true
	end
	return false
end

 

  • Спасибо 1

Поделиться этим сообщением


Ссылка на сообщение

Все взрывные предметы в weapons.ltx, код выше для спавна рядом с гг, а если в инвентарь - у нужной секции can_take = true (иначе вылет) и так: alife():create("explosive_barrel", db.actor:position(), 0, 0, db.actor:id())

 

3 часа назад, AndreySol сказал:

У меня спавн этой бочки на позиции актера просто приводит к смерти ГГ. Но бочка спавнится исправно...

:biggrin: http://funkyimg.com/i/2SBo9.jpg

  • Смешно 1

Поделиться этим сообщением


Ссылка на сообщение

@DibokDibokin, есть другой вариант, не по модели, а по секции [drop_box],

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

-- тестовые функции по клавише из главного меню
function main_menu:OnKeyboard(dik, keyboard_action) --virtual function
...
	-- поставить отметку на объект с логикой drop_box (лут из коробки)
	if dik == DIK_keys.DIK_F1 then
			if (level.present() and db.actor ~= nil and db.actor:alive()) then
				local level_actor = game_graph():vertex(alife():actor().m_game_vertex_id):level_id()
				for a=1,65535,1 do
					local obj = alife():object(a)
					if obj and obj ~= nil then
						local level_obj = game_graph():vertex(obj.m_game_vertex_id):level_id()
						if level_obj == level_actor then -- отметки только на текущей карте
							local obj_name = obj:name()
							if (obj.parent_id and obj.parent_id == 65535) then
								local ini = obj:spawn_ini()
								if (obj:spawn_ini() ~= nil and obj:spawn_ini():section_exist("drop_box") == true) then
									level.map_add_object_spot(obj.id, "obj_location", tostring(obj_name))
									-- obj_location, ид метки из map_spots.xml
									--[[
                                      <obj_location>
                                          <level_map spot="obj_location_spot"/>
                                          <mini_map spot="obj_location_spot"/>
                                      </obj_location>
                                      <obj_location_spot x="0" y="0" width="4" height="4" alignment="c" stretch="1">
                                          <texture r="0" g="255" b="255">ui_minimap_point</texture>
                                      </obj_location_spot>
									]]--
								end
							end
						end
					end
				end
			end
		end
		-- удалить отметку
		if dik == DIK_keys.DIK_F2 then
			if (level.present() and db.actor ~= nil and db.actor:alive()) then
				for a=1,65535,1 do
					local obj = alife():object(a)
					if obj and obj ~= nil then
						if (obj.parent_id and obj.parent_id == 65535) then
							if (obj:spawn_ini() ~= nil and obj:spawn_ini():section_exist("drop_box") == true and level.map_has_object_spot(obj.id, "obj_location")) then
								level.map_remove_object_spot(obj.id, "obj_location", "")
							end
						end
					end
				end
			end
		end

 

 

  • Спасибо 1

Поделиться этим сообщением


Ссылка на сообщение

Можно ещё в различные схемы ставить проверки на наличие путей, так сделали в зп для волкеров (xr_walker.script):

function set_scheme
	...
	st.path_walk = utils.cfg_get_string(ini, section, "path_walk", npc, true, gulag_name)
	-- сразу проверка
	if not level.patrol_path_exists(st.path_walk) then
		abort("there is no patrol path %s", st.path_walk)
	end
	...

 

  • Полезно 2

Поделиться этим сообщением


Ссылка на сообщение

Может и мне подскажете, вот есть рабочий способ на удаление объекта:

local obj = alife():object("esc_af_medusa12345") -- после спавна, провалилась под террейн
if obj ~= nil then
	alife():release(obj, true)
end

и как мне применить (любопытства ради) на этот объект нек.эффекты типа:

local ph = obj:get_physics_shell() -- пробовал, вылет по nil (подозреваю, что пытаюсь применить методы клиент.объектов к серверным)
if (ph) then
	ph:apply_force(0,10000,0) -- пнуть по у вверх
end

или уж совсем дикие методы:

 

function drop_item_and_teleport(game_object*, vector);
function transfer_item(game_object*, game_object*);

 

В обоих случаях, методы вызываются от кого-то, как пример: актор, владеющий таким-то предметом, но когда итем бесхозный, то его парент 65535, т.е. владелец земля, и от неё как-то сделать вызовы.

Поделиться этим сообщением


Ссылка на сообщение

@Kirgudu 

пример с удалением - это, то что работает. В общем, запуск арта в атмосферу успешен:

-- вызовы из главного меню
if dik == DIK_keys.DIK_F4 then
	if (level.present() and db.actor ~= nil and db.actor:alive()) then
		-- ##########################################
		local fail_objects_tbl =
		{
			"esc_af_medusa12345",
		}
		for k, v in pairs(fail_objects_tbl) do
			local s_obj = alife():object(v)
			if s_obj then
				local c_obj = level.object_by_id(s_obj.id)
				local ph = c_obj:get_physics_shell()

				if (ph) then
					-- >100 метров по у
					ph:apply_force(0,500000,0)
				end
			end
		end
		-- ##########################################
	end
end

 

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

Поделиться этим сообщением


Ссылка на сообщение

@Norman Eisenherz 

Давно кто-то об этом писал, просто сохранил пост как ещё один баг для исправления:

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

Решил я сохранить некие данные в псторе мобов. Всё было хорошо пока я не вышел с уровня. Как только я ушёл и сразу вернулся, то обнаружил, что все мои данные благополучно потерялись. Стал смотреть в чём дело, оказалось что при переходе между уровнями, а так же при загрузке с автосейва, не вызывается функция load для байндереров мобов и неписей. Из-за чего весь их пстор обнуляется. Если учесть, что все параметры активной логики неписей и мобов хранятся именно в псторе, то его обнуление может неожиданным образом сказаться на их поведении. Например, многоэтапная логика сбросится в своё начало.

Последовательность вызова функций binder-ов мобов и неписей.
При загрузке обычного сейва:
reload
reinit
load
xr_logic.pstor_load_all
mob_net_spawn
При смене уровня:
reload
reinit
mob_net_spawn

Просматривая историю правок script_binder.cpp:

Раньше было так:

void CScriptBinder::Load			(LPCSTR section)
{
	inherited::Load			(section);
}

Забавно, но в день дурака (1.04.04) разрабы изменили на это:
void CScriptBinder::Load			(LPCSTR section)
{
}

 

Поделиться этим сообщением


Ссылка на сообщение

@Norman Eisenherz 

Затестил скрипт с переменной, она тру после первого юза / сейвлоада, но сбрасывается в false при смене уровня. Если добавить в se_monster.script:

function se_monster:keep_saved_data_anyway()
	return true
end

то будет сохранение.

 

К примеру, если подобный блок удалить в se_zones.script для se_restrictor, то их логика будет сбрасываться на начало после смены уровня.

; test sr
[logic]
active = sr_idle@1

[sr_idle@1]
on_info = {+ai4_sr_to_2} sr_idle@2 %=send_tip(SR_to_section_2)%

[sr_idle@2]
on_info = {+ai4_sr_to_3} sr_idle@3 %=send_tip(SR_to_section_3)%
on_game_timer = 50 | {-ai4_sr_to_3} %+ai4_sr_to_3%

[sr_idle@3]
  • Нравится 1
  • Полезно 2

Поделиться этим сообщением


Ссылка на сообщение

@Norman Eisenherz 

Насчёт ограничений, есть исходники ориг. ТЧ: https://github.com/mortany/xray

xrServer_Object_Base.cpp,

//client object custom data serialization SAVE

u16 client_data_size = (u16)client_data.size();

 

 

Поделиться этим сообщением


Ссылка на сообщение
14 часов назад, Norman Eisenherz сказал:

Не знаю, насколько это подходит…

Мне напомнило о том самом алайфе, без смартов и прочего, где ии более живой и без принудительного склероза.

Поделиться этим сообщением


Ссылка на сообщение
19 часов назад, Labadal сказал:

умирают они не сразу после выдачи поршня

В логике любого объекта, хитануть на 1000 урона кого-то с сидом 100:
=hit_npc(100:bip01_spine1:1000:0)

 

В логике убиваемого, path_name - путь, от которого будет урон:
=hit_npc(path_name:bip01_spine1:1000:0)

  • Полезно 1

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

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

AMK-Team.ru

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