Войти на сайт Регистрация Лента форума Пользователи Правила сайта Поиск по форуму
Модератор форума: denis2000, FantomICW  
Модостроение. Редактирование и создание скриптов
denis2000Дата: Пн, 10.10.2011, 21:17 | Сообщение # 1
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Редактирование и создание скриптов

Редактирование и создание скриптов на языке LUA

Если у вас появились вопросы по применению скриптов в игре. Задавайте их в этой теме - умные головы,
модосторители и просто разбирающиеся в программировании люди вам ответят.


Много интересного материала здесь (wiki), Lua_help.script, Help из SDK 0.7

Сборник модостроения ЗП v10.10.11 (автор: XOBAH): *.CHM, *.HTML
[cut noguest=Если у вас не открывается файл CHM]Если у вас не открывается файл:
1. Запустите [Пуск]=>[Выполнить] (либо хот-кей [WIN]+[R])
2. Введите команду (без кавычек) "regsvr32 %windir%\system32\hhctrl.ocx"
3. Если вылезло окно об успешном завершении вы все сделали правильно и можете перезагружать компьютер (а может и не надо)
Также: файлы МОГУТ не открываться если в пути к файлу есть: символы кириллицы, "_", "#"
Также: есть не стандартные программы-просмоторщики CHM файлов. Например: FBReader[/cut]

[cut=Где найти лог игры после вылета]Что такое LOG ошибки, и как мне его найти?
Это система отладки происходивших вылетов, которая подается игрой в форме текста, хотя не всегда.
Для того чтоб найти LOG необходимо зайти вот сюда:

В Win хр лог находится:

C:\Documents and Settings\All Users\Документы\S.T.A.L.K.E.R. - Зов Припяти\logs

Затем открываете первый файл в формате TXT, и в нем отбираете с низу 25 строчек. После кидаете эти 25 строчек в сообщение на форум.

В Win7 лог находится C:\Users\Public\Documents\S.T.A.L.K.E.R. - Зов Припяти\logs

Путь к папке с логом можно найти открыв файл fsgame.ltx который находится в корневой директории ЗП, за это отвечает строка:
...
$app_data_root$ = true | false| $fs_root$| users\
(тут мы указываем что папка пользователя, будет хранится рядом с Fsgame.ltx)
...
$logs$ = true| false| $app_data_root$| logs\
(а тут мы указываем что в папке пользователя, в подпапке Logs будут храниться наши логи)
...
[/cut][cut=Получение более подробной информации о вылете (ХОВАН)]
Открываем файл _g.script и ищем такую функцию: function abort(fmt, ...)
Там есть заккомментированная строчка "--error_log(reason)", ее и надо расскомментировать, должно получиться вот так:
Code
function abort(fmt, ...)
                             local reason = string.format(fmt, ...)
                             error_log(reason)
end

Вот для примера два одинаковых вылета, первый с функцией по умолчанию, второй - с поправленной функцией

Первый:
Code
Expression    : !m_error_code
Function      : raii_guard::~raii_guard
File          : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp
Line          : 748
Description   : ....a.l.k.e.r. - Зов Припяти\gamedata\scripts\_g.script:478: bad argument #2 to 'format' (string expected, got nil)

Второй:
Code
Expression    : 0
Function      : ErrorLog
File          : D:\prog_repository\sources\trunk\xrServerEntities\script_engine_script.cpp
Line          : 49
Description   : 'Attempt to read a non-existant string field 'path_walk' in section 'walker@mechanic'

[/cut]


Перед тем, как задать вопрос в этой теме, прочтите все предыдущие страницы,
статьи в wiki по ссылке из шапки и соседнюю тему "Курс молодого бойца",
возможно Ваш вопрос уже рассматривался.


Если произошел вылет - выкладываем лог! Вопрос ставим четко, не забываем указывать версию игры, установленные моды их версии, установленные фиксы модов и подробно ваши правки.
Помните чем подробнее вопрос, тем точнее ответ.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
sergej5500Дата: Вс, 20.04.2014, 01:50 | Сообщение # 481
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

denis2000,
После подстановки функции в xr_conditions получил лог.
[cut=Лог]
FATAL ERROR

[error]Expression : !m_error_code
[error]Function : raii_guard::~raii_guard
[error]File : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp
[error]Line : 748
[error]Description : ... 1\Зов Припяти\gamedata\scripts\xr_conditions.script:876: attempt to index local 'k' (a number value)

stack trace:[/cut]

Подправил. denis2000

Добавлено (20.04.2014, 01:50)
---------------------------------------------
Добрый вечер. Возник такой вопрос. В КМБ рассматривается тема "Спавн нового НПС".

Для спавна используется код типа.
[cut=Код]function rasvet_add_pursue_stalker_1_spawn(actor,npc)
local p=vector(),lv,gv
p.x=db.actor:position().x+5
p.y=db.actor:position().y
p.z=db.actor:position().z
lv=db.actor:level_vertex_id()
gv=db.actor:game_vertex_id()
alife():create("rasvet_add_pursue_stalker_1",p,lv,gv)
end[/cut]

Мне этот код потребовался для спавна сталкеров, грабящих ГГ. Рестриктор через определенное время проверяет позицию ГГ и если тот далеко от базы (Скадовска), то с вероятностью 1% спавнит этих НПС. Недостаток метода очевиден. Неписи спавнятся рядом с ГГ. Если их спавнить на большой дистанции от ГГ, то возможны глюки. ГГ в момент срабатывания рестриктора может быть где угодно. Код должен быть универсальным. Если игрок окажется на границе локации, то НПС могут заспавниться за забором и потом пройти его насквозь. Вариант "убрать изображение" в момент спавна нежелателен.

Поэтому есть вопрос. Можно ли переделать код таким образом, чтобы НПС спавнился в 100-130 метрах от ГГ в направлении центра локации (точки 0,0,0)? Если можно, то как это сделать?

 
makdmДата: Вс, 20.04.2014, 13:41 | Сообщение # 482
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

sergej5500, достаточно вспомнить школьную геометрию, а именно Теорему Пифагора.
Координату Y можно игнорить, так как Двигало сам поставит НПС на AI-сетку.

Вот так можно сделать

[cut noguest]

function spawn_npc_dist_from_actor( actor, obj, p )
--' p[1] - секция кого спаунить
--' p[2] - расстояние до ГГ, на котором спаунить ( по умолчанию 130 метров )
-- вызываем из логики рестриктора, расположенного в центре локации
if p[ 1 ] == nil then return end
local section = tostring( p[ 1 ] )
local distance
if p[ 2 ] then
distance = tonumber( p[ 2 ] )
else
distance = 130
end
-- Вычисляем расстояние до ГГ и коэффициент вычисления координат НПС, которого спауним.
local obj_position = obj:position()
local actor_position = db.actor:position()

-- 5 класс школы - теорема Пифагора

local dist_x = actor_position.x-obj_position.x
local dist_z = actor_position.z-obj_position.z
local dist_to_actor = math.sqrt( ( dist_x )^2 + ( dist_z )^2 )
local npc_dist = dist_to_actor - distance
local koeff = dist_to_actor/npc_dist

-- Высисляем координаты появления НПС. Причем координаты направлены от ГГ внутрь локации к рестриктору.
local npc_position = vector():set( 0, 0, 0 )
npc_position.x = obj_position.x + dist_x/koeff
npc_position.z = obj_position.z + dist_z/koeff

-- спавним нпс и телепортируем на вычисленные координаты.
local sobj_npc = alife():create( section, obj_position, obj:level_vertex_id(), obj:game_vertex_id() )
sobj_npc.position = npc_position
end
[/cut]


Терпение......
И все получится!


Сообщение отредактировал makdm - Вс, 20.04.2014, 14:03
 
sergej5500Дата: Пн, 28.04.2014, 18:18 | Сообщение # 483
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый день. В теме СГМ пользователи жалуются на такой вылет. Мне он тоже встречался несколько раз.
[cut=Лог]
FATAL ERROR

[error]Expression : !m_error_code
[error]Function : raii_guard::~raii_guard
[error]File : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp
[error]Line : 748
[error]Description : e:\call of pripyat\gamedata\scripts\xr_walker.script:120: deoptimization failed

stack trace: [/cut]

Функция в xr_walker, на которую жалуется игра.

[cut=Функция]function action_walker_activity:execute()
action_base.execute(self)

self.move_mgr:update()

-- Определяем, в каком мы кемпе.
local camp = sr_camp.get_current_camp(self.object:position())
if camp ~= nil and self.st.use_camp == true then
self.camp = camp
self.camp:register_npc(self.object:id())
self.in_camp = true
else
if self.in_camp == true then
self.camp:unregister_npc(self.object:id())
self.in_camp = nil
end
end

if not self.in_camp and self.st.sound_idle ~= nil then
xr_sound.set_sound_play(self.object:id(), self.st.sound_idle)
end
if sgm_flags.table_mod_schemes[self.object:id()].update==nil then
self:check_logic_condlists(self.object,self.st.saved_ini,self.st.saved_section)
sgm_flags.table_mod_schemes[self.object:id()].update=time_global()+1000
end
if sgm_flags.table_mod_schemes[self.object:id()].update~=nil then
if time_global()>=sgm_flags.table_mod_schemes[self.object:id()].update then
sgm_flags.table_mod_schemes[self.object:id()].update=nil
end
end
local npc=self.object
local npc_id=npc:id()
local scheme_param=sgm_flags.table_mod_schemes[npc_id]
if scheme_param.approach_info~=nil and scheme_param.approach_info[1]~=nil and scheme_param.approach_info[2]~=nil and dont_has_alife_info(scheme_param.approach_info[1]) then
local dist_type="<="
if scheme_param.approach_info[3]~=nil then dist_type=scheme_param.approach_info[3] end
if dist_type=="<=" and distance_between(db.actor,npc)<=tonumber(scheme_param.approach_info[2]) then give_info(scheme_param.approach_info[1])
elseif dist_type==">=" and distance_between(db.actor,npc)>=tonumber(scheme_param.approach_info[2]) then give_info(scheme_param.approach_info[1])
elseif dist_type=="<" and distance_between(db.actor,npc)<tonumber(scheme_param.approach_info[2]) then give_info(scheme_param.approach_info[1])
elseif dist_type==">" and distance_between(db.actor,npc)>tonumber(scheme_param.approach_info[2]) then give_info(scheme_param.approach_info[1])
elseif dist_type=="=" and distance_between(db.actor,npc)==tonumber(scheme_param.approach_info[2]) then give_info(scheme_param.approach_info[1])
end
end
if scheme_param.precond_timer~=nil then
if scheme_param.precond_timer=="true" then
if sgm_flags.table_mod_schemes[npc_id.."precond_start"]==0 then
sgm_flags.table_mod_schemes[npc_id.."precond_start"]=time_global()
end
local p_timer=time_global()-sgm_flags.table_mod_schemes[npc_id.."precond_start"]
if exists(scheme_param.precond_action) and tonumber(scheme_param.precond_action[1])~=0 and p_timer>tonumber(scheme_param.precond_action[1]) then
sgm_functions.execute_condlist(npc,self.st.saved_section,scheme_param.precond_action[2])
sgm_flags.table_mod_schemes[npc_id.."precond_start"]=0
end
else
if sgm_flags.table_mod_schemes[npc_id.."precond_start"]~=0 then
sgm_flags.table_mod_schemes[npc_id.."precond_start"]=0
end --- 120 строка
end
end
self:check_avail_speak(npc,scheme_param)
end[/cut]

Можно ли решить проблему вылета?
 
NIVДата: Вс, 04.05.2014, 20:46 | Сообщение # 484
Полевой исследователь
Ученые сталкеры
Сообщений: 167
Награды: 4
Репутация: [ 180 ]

Подскажите, пожалуйста, функцию для сохранения (и для загрузки) массива из N элементов (целых чисел) в методе save (или load) биндера.

Изменяем реальность S.T.A.L.K.E.R. CoP: "Цена Новых Исследований" / "New Investigations' Value"
 
denis2000Дата: Вс, 04.05.2014, 21:09 | Сообщение # 485
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

NIV, В bind_stalker.script есть необходимый код, для массива с непоследовательной индексацией элементов:
[cut]
Код
local n = 0
     for k,v in pairs(db.script_ids) do
      n = n + 1
     end
     packet:w_u8(n)
     for k,v in pairs (db.script_ids) do
      packet:w_u16(k)
      packet:w_stringZ(v)
     end

Код
n = reader:r_u8()
     for i = 1,n do
      db.script_ids[reader:r_u16()] = reader:r_stringZ()
     end
[/cut]
В массиве с последовательной индексацией код можно упростить.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
NIVДата: Чт, 08.05.2014, 14:52 | Сообщение # 486
Полевой исследователь
Ученые сталкеры
Сообщений: 167
Награды: 4
Репутация: [ 180 ]

denis2000, спасибо за совет, но пока разобраться до конца не получилось.

Правильно ли я понял, что вместо db.script_ids нужно указывать свою переменную-массив? Может ли она располагаться в произвольном файле, или лучше в db? У меня индексация последовательная - лучше использовать for i = 1, max?


Изменяем реальность S.T.A.L.K.E.R. CoP: "Цена Новых Исследований" / "New Investigations' Value"
 
sergej5500Дата: Чт, 08.05.2014, 16:39 | Сообщение # 487
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый день.

Заспавнил вертолет.

[cut=Секция][9370]

; cse_abstract properties
section_name = helicopter
name = rasvet_add_test_heli_1
position = -117.901756286621, 55.6206550598145, 476.79248046875
direction = 0, 0, 0
id = 65535
version = 128
script_version = 12
spawn_id = 9831

; cse_alife_object properties
game_vertex_id = 131
level_vertex_id = 705820
object_flags = 0xffffffb2
custom_data = <<END
[story_object]
story_id = rasvet_add_test_heli_1
[logic]
cfg = scripts\rasvet_addon\rasvet_add_test_heli_1.ltx
END

; cse_visual properties
visual_name = dynamics\vehicles\mi24\veh_mi24_u_01

; cse_motion properties

; cse_ph_skeleton properties
skeleton_name = idle

; cse_alife_helicopter properties
cse_alife_helicopter__unk1_sz = idle
engine_sound = vehicles\helicopter\helicopter

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;[/cut]

Каким образом этот вертолет заспавнить через нет-пакет? Просьба привести конкретный пример кода. Что и в каких файлах прописывать?
 
denis2000Дата: Чт, 08.05.2014, 19:50 | Сообщение # 488
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата NIV ()
Правильно ли я понял, что вместо db.script_ids нужно указывать свою переменную-массив?

Да конечно. Вместо нее ваша переменная-массив.
Цитата NIV ()
Может ли она располагаться в произвольном файле, или лучше в db?

Она может распологаться в любом файле скрипта, главное чтобы была заявлена как глобальная переменная.
Цитата NIV ()
У меня индексация последовательная - лучше использовать for i = 1, max?

Естественно, если индексация последовательная-сплошная, то такая конструкция предпочтительнее.

sergej5500, Обычно вертолет спавниться в начале игры (через all.spawn) за пределами локации с выключенным звуком двигателя и отключенным оружием, а при выдачи некой инфопорции активируется.
Можно спавнить и через скрипт, даже видел этот код, но хоть убей не помню где, может в АМК?


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
FantomICWДата: Чт, 08.05.2014, 20:09 | Сообщение # 489
Лидер «Свободы»
Свобода
Сообщений: 4438
Награды: 44
Репутация: [ 1340 ]

Цитата denis2000 ()
может в АМК?

Я вспомнил про статью на инсайде:
[cut=Функция]
Код
function create_heli()
  local position = db.actor:position()
  position.y = position.y + 50
  local obj = alife():create("helicopter",
    position, db.actor:level_vertex_id(), db.actor:game_vertex_id())
  local packet = net_packet()
  obj:STATE_Write(packet, 60)

  -- свойства cse_alife_object
  local game_vertex_id = packet:r_u16()
  local cse_alife_object__unk1_f32 = packet:r_float()
  local cse_alife_object__unk2_u32 = packet:r_u32()
  local level_vertex_id = packet:r_u32()
  local object_flags = packet:r_u32()
  local custom_data = packet:r_stringZ()
  local story_id = packet:r_u32()
  local cse_alife_object__unk3_u32 = packet:r_u32()

  -- свойства cse_visual
  local model_visual = packet:r_stringZ()
  local cse_visual__unk1_u8 = packet:r_u8()

  -- свойства cse_motion
  local motion_name = packet:r_stringZ()

  -- свойства cse_ph_skeleton
  local skeleton_name = packet:r_stringZ()
  local cse_ph_skeleton__unk1_u8 = packet:r_u8()
  local cse_ph_skeleton__unk2_u16 = packet:r_u16()

  -- свойства cse_alife_helicopter
  local cse_alife_helicopter__unk1_sz = packet:r_stringZ()
  local engine_sound = packet:r_stringZ()

  -- теперь заполняем нужные параметры
  -- свойства cse_alife_object
  packet:w_begin(game_vertex_id)
  packet:w_float(cse_alife_object__unk1_f32)
  packet:w_u32(cse_alife_object__unk2_u32)
  packet:w_u32(level_vertex_id)
  object_flags = bit_not(5)    -- ~5 = 0xfffffffa
  packet:w_u32(object_flags)
  packet:w_stringZ(custom_data)
  packet:w_u32(story_id)
  packet:w_u32(cse_alife_object__unk3_u32)

  -- свойства cse_visual
  packet:w_stringZ(model_visual)
  packet:w_u8(cse_visual__unk1_u8)

  -- свойства cse_motion
--    motion_name = "helicopter\\aaa.anm"    -- можно не определять
  packet:w_stringZ(motion_name)

  -- свойства cse_ph_skeleton
  skeleton_name = "idle"
  packet:w_stringZ(skeleton_name)
  packet:w_u8(cse_ph_skeleton__unk1_u8)
  packet:w_u16(cse_ph_skeleton__unk2_u16)

  -- свойства cse_alife_helicopter
  cse_alife_helicopter__unk1_sz = "idle"
  engine_sound = "alexmx\\helicopter"
  packet:w_stringZ(cse_alife_helicopter__unk1_sz)
  packet:w_stringZ(engine_sound)

  -- считываем скорректированные параметры
  packet:r_seek(0)
  obj:STATE_Read(packet, packet:w_tell())
end
[/cut]
Статья вот.
Там внизу прямая ссылка на пример.



 
NIVДата: Сб, 10.05.2014, 07:28 | Сообщение # 490
Полевой исследователь
Ученые сталкеры
Сообщений: 167
Награды: 4
Репутация: [ 180 ]

По поводу сохранения переменных - обнаружил неожиданную (для меня) вещь, что методы save, load не работают в классе, который принадлежит графическому окну (CUIScriptWnd). При сохранении происходил вылет, указывающий на то, что значения не определены.[cut=Инизиализация класса]
Код
class "ui_puzzle" (CUIScriptWnd)

function ui_puzzle:__init(owner) super()
   self.owner = owner
   self:InitControls()
   self:InitCallBacks()
   self:SetTexture()
end
[/cut]
Если же создать отдельный класс [cut=(инициалицазия)]
Код
class "niv_puzzle"

function niv_puzzle:__init()
end
[/cut], то ЭТИ же методы save, load отлично работают. Почему так происходит? Сохраняемая переменная глобальная и ни одному классу не принадлежит.
P.S. На основании вышеизложенного организовал графическое окно, в котором можно "собирать" документ, разорванный на части. Посмотреть, как выглядит, можно здесь . Промежуточные сохранения поддерживаются!


Изменяем реальность S.T.A.L.K.E.R. CoP: "Цена Новых Исследований" / "New Investigations' Value"

Сообщение отредактировал NIV - Сб, 10.05.2014, 07:30
 
makdmДата: Сб, 10.05.2014, 23:11 | Сообщение # 491
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

NIV, я, честно говоря, не очень силён в GUI скриптах, но тем не менее можно проанализировать.
В COP есть такая фишка, как место для сна для ГГ.
После того, как вы выбрали время ( передвинули ползунок ), до которого должен спать ГГ, вы можете выйти из тутора, сохраниться, а затем загрузиться или перейти на другую локацию, НО после того, как вы снова подойдёте к месту сна у вас снова появится окно ГУИ с последними данными о передвинутом ползунке, указывающим на время сна ГГ. Т.е. все последние ваши "телодвижения" по передвижению ползунка автоматом сохраняются в сейве игры.
Т.е. движок сам автоматом сохраняет текущее положение "маркера". Как это работает в движке - я не знаю. Но вам советую просто перенять эту схему.
P.S. Возможно кто-то, из более "продвинутых"коллег в GUI окнах, подскажет вам решение проблемы.


Терпение......
И все получится!


Сообщение отредактировал makdm - Сб, 10.05.2014, 23:21
 
sergej5500Дата: Вс, 11.05.2014, 00:37 | Сообщение # 492
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый вечер. Заинтересовал такой момент.

В СГМ есть фишка - сканер растяжек. Отмечает на карте расположение мин. За маркеры мин отвечают две функции в sgm_modules.

[cut=Функции]function submodule_mines_control(object)
if check_seconds(2) and dont_has_alife_info("opt_deactivate_minetrap") and r_mod_params("bool","create_mines_permition",true)==true then
if find_in_string(read_string("minetraps_config","levels","misc\\config_minetraps.ltx"),level.name()) then
for k,v in pairs(sgm_flags.table_mod_mineraps[level.name()]) do
if object~=nil and object:alive() and get_story_object_id(v)~=nil and level.object_by_id(get_story_object_id(v))~=nil and distance_between(level.object_by_id(get_story_object_id(v)),object)<=r_mod_params("number","mine_traps_radius",4.0) then
if sgm_functions.ReadAvoidMines(object:section())==false then
remove_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap)
detonate_explosive_charge(get_story_object_id(v),false)
unregister_story_id(v)
end
end
if db.actor:object("minetrap_detector") or db.actor:object("minetrap_elite_detector") then
if get_story_object_id(v)~=nil then
if db.actor:object("minetrap_elite_detector") then
if level.object_by_id(get_story_object_id(v))~=nil and distance_between(level.object_by_id(get_story_object_id(v)),db.actor)<=145 and level.map_has_object_spot(get_story_object_id(v),sgm_flags.spot_ground_trap)==0 then
play_snd_at_actor([[ambient\special\marsh_beep_1]])
add_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap,"st_minetrap_name")
elseif level.object_by_id(get_story_object_id(v))~=nil and distance_between(level.object_by_id(get_story_object_id(v)),db.actor)>145 then
remove_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap)
end
else
if level.object_by_id(get_story_object_id(v))~=nil and distance_between(level.object_by_id(get_story_object_id(v)),db.actor)<=50 and level.map_has_object_spot(get_story_object_id(v),sgm_flags.spot_ground_trap)==0 then
play_snd_at_actor([[ambient\special\marsh_beep_1]])
add_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap,"st_minetrap_name")
elseif level.object_by_id(get_story_object_id(v))~=nil and distance_between(level.object_by_id(get_story_object_id(v)),db.actor)>50 then
remove_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap)
end
end
end
else
if get_story_object_id(v)~=nil and alife():object(get_story_object_id(v)) then
remove_spot_on_map(get_story_object_id(v),sgm_flags.spot_ground_trap)
end
end
end
end
end
end.

function submodule_anomaly_control(object)
if check_seconds(2) then
if db.actor~=nil and (db.actor:object("minetrap_detector") or db.actor:object("minetrap_elite_detector")) then
if db.actor:object("minetrap_elite_detector") then
if find_in_string(object:section(),"zone_mine_field") and distance_between(object,db.actor)<=145 and level.map_has_object_spot(object:id(),sgm_flags.spot_ground_trap)==0 then
play_snd_at_actor([[ambient\special\marsh_beep_1]])
add_spot_on_map(object:id(),sgm_flags.spot_ground_trap,"st_mine_field_name")
elseif find_in_string(object:section(),"zone_mine_field") and distance_between(object,db.actor)>145 then
remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap)
end
else
if find_in_string(object:section(),"zone_mine_field") and distance_between(object,db.actor)<=50 and level.map_has_object_spot(object:id(),sgm_flags.spot_ground_trap)==0 then
play_snd_at_actor([[ambient\special\marsh_beep_1]])
add_spot_on_map(object:id(),sgm_flags.spot_ground_trap,"st_mine_field_name")
elseif find_in_string(object:section(),"zone_mine_field") and distance_between(object,db.actor)>50 then
remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap)
end
end
else
if find_in_string(object:section(),"zone_mine_field") then
remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap)
end
end
end
if sgm_flags.bool_show_anomalies==true and find_out_string(object:section(),"radioactive") and distance_between(object,db.actor)<=10 and level.map_has_object_spot(object:id(),sgm_flags.spot_hero_rucksack)==0 then
level.map_add_object_spot_ser(object:id(),sgm_flags.spot_hero_rucksack,object:name())
debug_to_file("anomaly_fields_in_radius.txt",object:name())
end
end
[/cut]

Первая ф-ия отвечает на СГМ-мины. Вторая за мины из оригинальной игры (возле вертолета на Юпитере). К работе первой ф-ии претензий нет. Маркеры ставятся. При удалении игрока от мины они убираются. Вторая ф-ия маркеры ставит. Но удалять маркеры при удалении игрока от мин не спешит.

[cut=Скрины]

[/cut]

Последний скрин сделан возле моста. От минного поля примерно 200 метров. Мины отлично видны на карте. После съемки скрина отправился на Янов. Мины у вертолета были видны и там. Сделал сейв. Загрузился. Мины все равно отображаются на карте. Помог только уход на Затон. После визита на Затон и возвращения на Янов мины с карты пропали.

Можно ли подправить ф-ию, чтобы она работала корректно.
 
denis2000Дата: Вс, 11.05.2014, 15:45 | Сообщение # 493
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

sergej5500, В этом скрипте целая группа нестыковок и недочетов:
1. Функция вызывается из биндера аномальноых полей с передачей объекта для обработки, но в секции самой мины (а точнее аномалии мина) есть строка offline_interactive_radius = 30, которая говорит о том что объект уходит в офлайн уже на дистанции в 30 метров! А значит биндер никак не может передать этот объект на дистанции от него ГГ 50 и уж тем более в 145 метров.
2. В самой функции есть условие обработки if check_seconds(2) then, а это значит что объект обрабатывается далеко не так часто как необходимо и в результате условие снятия метки очень легко проскочить (ведь это всего 5 метров! 150-145)


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
NIVДата: Чт, 05.06.2014, 21:40 | Сообщение # 494
Полевой исследователь
Ученые сталкеры
Сообщений: 167
Награды: 4
Репутация: [ 180 ]

Здравствуйте! В файлах jup_b16_active_N.ltx встречается конструкция типа
Код
on_actor_inside = {=jup_b16_is_zone_active и т.д...
, причем
Код
function jup_b16_is_zone_active(actor, npc)
  return has_alife_info(npc:name())
end

Не могу понять, наличие какого инфопоршня проверяется в этой функции?


Изменяем реальность S.T.A.L.K.E.R. CoP: "Цена Новых Исследований" / "New Investigations' Value"
 
denis2000Дата: Пт, 06.06.2014, 00:25 | Сообщение # 495
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата NIV ()
Не могу понять, наличие какого инфопоршня проверяется в этой функции?

Проверяется наличие инфопорции совпадающее с названием секции рестриктора.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
Поиск: