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

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

@FonSwong,


 

Можно ли скриптом собрать смарты на локации и узнать их координаты?

Смотря что ты подразумеваеш под смартами.

Если рестриктор определенной формы (шейп) назначаемый смарту то координаты узнать, скорее всего можно.

Ну а если координаты работ и путей смарта то

 

6) Работы могут находиться на разных уровнях.
7) Скриптовая зона СТ теперь не используется для захвата персонажей.
8) Симуляция заключается в миграции персонажей между разными СТ.

http://stalkerin.gameru.net/wiki/index.php?title=%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0_%D0%BB%D0%BE%D0%B3%D0%B8%D0%BA%D0%B8._%D0%A7%D0%B0%D1%81%D1%82%D1%8C_4#3.11.3._.D0.9D.D0.BE.D0.B2.D1.8B.D0.B5_.D0.BE.D1.81.D0.BE.D0.B1.D0.B5.D0.BD.D0.BD.D0.BE.D1.81.D1.82.D0.B8_.D1.81.D0.BC.D0.B0.D1.80.D1.82.D1.82.D0.B5.D1.80.D1.80.D0.B5.D0.B9.D0.BD.D0.BE.D0.B2

 

PS. Не заблуждайтесь

Радиус смарта используеться только в СДК для визуализации.

И ни на что не влияет.

Главное что бы от нуля отличался :P .

PSS.  Распакуйте алл спавн  и измените радиус любого смарта (шейпы тойсть формы).

Типа тест хоть на 00000000000.1

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

Вот тебе бабушка и Юрьев день.

 

@AKKK1, данные любых поинтов ты можешь узнать где угодно. Вот например я сделал дамп барного пути на Кордоне:

 

 

[27.10.16 22:06:45.551] { ----- id table: 2CEA00B0 -----
[27.10.16 22:06:45.551]     [0] =
[27.10.16 22:06:45.551]         { ----- id table: 2CEA0100 -----
[27.10.16 22:06:45.551]             ["gv"] = [1180],
[27.10.16 22:06:45.551]             ["name"] = ["wp00"],
[27.10.16 22:06:45.551]             ["ln"] = ["l05_bar"],
[27.10.16 22:06:45.551]             ["index"] = [0],
[27.10.16 22:06:45.551]             ["lv"] = [42114],
[27.10.16 22:06:45.551]             ["data"] =
[27.10.16 22:06:45.551]                 { ----- id table: 2CEA03A8 -----
[27.10.16 22:06:45.551]                     ["flags"] = <*flags[16/32]>,
[27.10.16 22:06:45.551]                     ["wp00"] = ["true"],
[27.10.16 22:06:45.551]                 },
[27.10.16 22:06:45.551]             ["pos"] = <*vector[x=161.396,y=0.18,z=7285]>,
[27.10.16 22:06:45.551]         },
[27.10.16 22:06:45.551]     ["pathname"] = ["bar_arena_guard_walk"],
[27.10.16 22:06:45.551] }

 

 

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

 

Еще есть у юзеров SDK забава подгонять респавнер для ящиков по миллиметрам. Прямо говорить, ящикам нужен другой подход, респавнеры (для ящиков) в том виде, в каком они есть совершенно не нужны. Сиды оставим, сидом мы ассоциируем смарту ящик, как смарт там разрождается у нас, так мы в этот ящик и суем барахло, откуда дровишки? А прямо из кастом даты ящика.

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

@Карлан,

Извени забыл добавить что

 

Ну а если координаты работ и путей смарта то

Тоже можно только другим способом.

И да я не разу не скриптер.

Еще раз радиус

(размер) абсолютно не важен.

Шейп это и есть сфера или бокс.

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

Я просто сделал так:

local gg = game_graph():vertex(smart.m_game_vertex_id)
local lvid = gg:level_vertex_id()
local pos = level.vertex_position(lvid)
Изменено пользователем FonSwong
Ссылка на комментарий

в ЗП есть лаконичный метод:

а как он работает? Мне надо название визуала использовать как ключ в таблице.

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

уже разобрался, все в порядке.
Ссылка на комментарий

@Sla-Sla, я вот как-то так делаю:

 ['stalker_zombie8'] = {'$outfit|stalker_zombi', 37, 48},
    local visual = string.split(npc:get_visual_name(), '\\');
    visual = drop_outfit_base[visual[3]]; local section = visual[1]
Ссылка на комментарий

В чём проблема?

 

 

function Get_Smarts()
	local t = {}
	for k, v in pairs(db.smart_terrain_by_id) do
		local smart = alife():object(k)
		if smart and smart:clsid() == clsid.smart_terrain then
			local gg = game_graph():vertex(smart.m_game_vertex_id)
			local lvl = alife():level_name(gg:level_id())
			local lvid = gg:level_vertex_id()
			local pos = level.vertex_position(lvid)
			if not t[lvl] then
				t[lvl] = {}
			end
			table.insert(t[lvl], pos)
		end
	end
	return t
end

 

 

Но на смарте с id 12871 почему-то скрипт зависает при попытке получения level.vertex_position(lvid)

http://imgdepo.com/id/i9875518

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

@FonSwong, а не проще позицию получать непосредственно из объекта?

local pos = smart.position

фунуция level.vertex_position возвращает позицию вертекса на текущей локации. Зависает, т.к., видимо, передаваемого в нее вертекса нет на уровне.

 

Изменено пользователем naxac
  • Полезно 1

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

naxac.gif

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

@naxac, дык спрашивал какие параметры можно из смарта достать, сам не догадался и не подсказал никто :)

 

 

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

Вот так узнаю кол-во левел вертиксов на уровне:

 

 

function Get_Levels_Vertexes()
	local LevelsVertexes = {}
	local i = 0
	local graph = game_graph()
	while graph:valid_vertex_id(i) do
		local v = graph:vertex(i)
		local ln = alife():level_name(v:level_id())
		if not LevelsVertexes[ln] then
			LevelsVertexes[ln] = v:level_vertex_id()
		elseif v:level_vertex_id() > LevelsVertexes[ln] then
			LevelsVertexes[ln] = v:level_vertex_id()
		end
		i = i+1
	end
	return t
end 

 

 

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

@Sla-Sla, сделай функцию для серверного объекта, в нет-пакет же пишется визуал. Класс CSE_Visual, там, как это принято здесь говорить, все интуитивно понятно.

 

@FonSwong, тебе уже ответили, потому-что функция только для текущего левел графа, и доступна только при загруженном уровне, что логично.

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

В ОП-2 есть код для проверки зависшей логики вертушек и физ. объектов:

 

  -- сообщение по побившейся логике физобъектов и вертолетов
  local s_ini = obj:spawn_ini()
  if not st.ini_filename and s_ini and logic_not_empty(obj, s_ini) then
if obj:clsid() == clsid.script_phys or obj:clsid() == clsid.script_heli
-- or ((IAmAStalker[obj:clsid()] or IAmAMonster[obj:clsid()]) and obj:alive())
then
abort("У объекта "..obj:name().." повисла логика. Удалите созданное только что сохранение и переиграйте с предыдущего.")
if not amk.has_timer("no_save") and not db.debug then
amk.start_timer("no_save", 5)
-- amk.start_timer("zonedocs_gg_kill",3,0)
end
end
  end
...


-- у объекта есть "непустая" логика
function logic_not_empty(npc, ini)
return ini:section_exist("logic") and (
ini:line_exist("logic", "cfg") or (ini:line_exist("logic", "active") and ini:r_string("logic", "active") ~= "nil")
)
end

 

 

Добавил код для проверки спейс-рестрикторов

if obj:clsid() == clsid.script_phys or obj:clsid() == clsid.script_heli or obj:clsid() == clsid.script_restr

Сообщения приходят, в лог тоже пишется:

0404948001478001698.jpg 0411819001478002154.png

А меня терзают смутные сомнения - правильно ли я написал и работает ли код для спейс-рестрикторов...

Зы. почему спрашиваю - некоторые рестрикторы (в логе они есть) не отрабатывают свою логику. Побилась?

И если побилась, то в чем может быть причина?

AMD Athlon II X2 250, NVIDIA GTS 450, RAM 8.0 GB, WIN 7/64  правки Золотой Шар

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

Уважаемые скриптеры, просьба прокомментировать следующий код (что делает и в каком случае вызывается). Предположительно, что делает - очищает хранилище актора: так ли это.

 

function actor_binder:save(packet)


local pk1 = fake_net_packet.fake_net_packet()
  self:save_old(pk1)
  --get_console():execute("Packet_size_is_"..pk1:w_tell())
  if pk1:w_tell()>7500 then
     ogsm_debug.clean_pstor()
  end
  self:save_old(packet)
end

 

  • Нравится 1

Сталкер - наше всё!

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

@AndrewMor,я не скриптер, но:

Получаем размер хранилища. Выводим его в консоль. Если оно привышает определенный размер, то очищаем его.

З.ы. Не пинайте если не так.

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

Практически так и есть, но дополню.

Вызывается при любом сохранении (это ответ на выделенный жирным вопрос). Если в функциях self:save_old() и ogsm_debug.clean_pstor() содержится то, что можно предположить (OGSM для ТЧ нет под рукой), служит в качестве своеобразного контроля переполнения pstor актора во избежание появления битых сейвов. А именно: производится запись pstor (или что там делает save_old()) в чистый net-пакет, проверяется его размер, если всё в порядке, тогда pstor пишется в net-пакет сейва как есть, если же превышен допустимый для ТЧ максимум - предварительно очищается.

Типичный "предохранитель" того времени, когда ещё не умели создавать кастомные объекты для сохранения большого объёма данных.

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

 

 

кастомные объекты для сохранения большого объёма данных.

А поподробнее можно про это?

  • Нравится 1

Не соответствует правилам.

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

@CRAZY_STALKER666, например se_stor от , который сохраняет данные как раз в таких объектах. Подробную информацию можно найти в постах автора модуля.

Если не ошибаюсь, @Malandrinus тоже делал подобный модуль.

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

 

 

Вызывается при любом сохранении

Включая и автосейв? Или просто сейвы, в т.ч. и квик?

 

 

 

Если в функциях self:save_old() и ogsm_debug.clean_pstor() содержится то, что можно предположить (OGSM для ТЧ нет под рукой

 

function actor_binder:save_old(packet)



  local save_treasure_manager = true

  printf("actor_binder:save(): self.object:name()='%s'", self.object:name())
  object_binder.save(self, packet)

  --' Сохраняем уровень сложности
  if save_treasure_manager == true then
  packet:w_u8(level.get_game_difficulty() + 128)
  else
    packet:w_u8(level.get_game_difficulty())
  end

  --' Сохраняем данные об отключенном вводе
  if self.st.disable_input_time == nil then
  packet:w_bool(false)
  else
    packer:w_bool(true)
    utils.w_CTime(packet, self.st.disable_input_time)
  end

  xr_logic.pstor_save_all(self.object, packet)
  self.weather_manager:save(packet)

  sr_psy_antenna.save( packet )

  if save_treasure_manager == true then
    treasure_manager.save(packet)
  end

  task_manager.save(packet)
  self.actor_detector:save(packet)
end

 

 

-- Экстренная очистка хранилища актора
function clean_pstor()
   for k,v in pairs(ogsm_anomaly.loc) do
     if k ~= level.name() then
      amk.del_variable("an"..ogsm_anomaly.loc[k])
     end
  end

 for i=1,100 do
   amk.del_variable("rt"..i)
   amk.del_variable("rt"..i.."d")
   amk.del_variable("rt"..i.."p")
   amk.del_variable("gt"..i)
   amk.del_variable("gt"..i.."d")
   amk.del_variable("gt"..i.."p")
 end
 

 amk.del_variable("rfx")
 amk.del_variable("blt")
 amk.del_variable("drnk")
 amk.del_variable("slp")
 amk.del_variable("nrg")
 amk.del_variable("smn")
 

 amk.del_variable("aem_team1")
 amk.del_variable("aem_team2")
 amk.del_variable("aem_cr")
 amk.del_variable("aem_cm")
 amk.del_variable("aem_rt")
 amk.del_variable("aem_ct")

 amk.del_variable("aem_lt")
 amk.del_variable("aem_nt")
 amk.del_variable("aem_it")
 amk.del_variable("aem_mt")
 amk.del_variable("aem_mk")

 for i=1,5 do
   amk.del_variable("snd"..i)
 end

 for i=1,65535 do
   local obj = alife():object(i)
   if obj and (obj:name()=="esc_tutorial_dead_novice" or
obj:name()=="val_lager_bandits_borov" or
obj:name()=="rostok_stalker") then
     alife():release(obj, true)
   end
 end

 db.actor:give_info_portion("val_actor_has_borov_key")

--amk.g_start_timer("bl1",0, 9+math.random(-1,1), 0)
--amk.g_start_timer("rsp",0, 5+math.random(-1,1), 0)

 get_console():execute("Actor_storage_has_been_successfully_cleaned!")
end

 

 

И еще вопрос: отчего может переполняться хранилище?

  • Спасибо 1

Сталкер - наше всё!

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

Включая и автосейв?

При любом сохранении.

 

Разумеется, хранилище может переполняться от того, что туда пишется слишком много данных. Максимальный размер net-пакета (в том числе актора) в ТЧ равен 8192 байта, в ЧН/ЗП вдвое больше. Обрати внимание на содержимое скопированной тобой функции save_old(): в net-пакет актора что-то пишут менеджеры погоды, тайников и заданий, радара и детектора. Много? Без детального изучения неизвестно. Плюс запись текущих настроек. Плюс pstor, то есть хранилище, в которое пихали данные все, кому не лень. Посмотри в твоей же clean_pstor(): из pstor вычищаются аномалии, таймеры, прочие служебные переменные - на всё это нужно место в net-пакете актора. А сколько в твоём моде других, неучтённых здесь мест использования штатных функций записи/чтения xr_logic.pstor_store() и xr_logic.pstor_retrieve()? То-то и оно. Увлёкся, записал лишнее - опаньки, вышли за 8 килобайт.

 

Потому и начали придумывать альтернативные варианты. Подробнее о разных скриптовых способах записи данных можно прочитать здесь: http://www.amk-team.ru/forum/topic/6185-skriptovanie/page-209#entry694323

Изменено пользователем Kirgudu
  • Спасибо 3
Ссылка на комментарий

 

 

таймеры,

А можно про таймеры подробнее? В смысле, в какой момент начинается заполнение пакета: при первом вызове таймера или как-то раньше/в другое время?

  • Спасибо 1

Сталкер - наше всё!

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

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

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

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

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

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

Войти

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

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

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