| 
	
		
		
			| Модостроение. Редактирование и создание скриптов |  | 
				
			 |  | 
| denis2000 | Дата: Пн, 10.10.2011, 21:17 | Сообщение # 1 |  |  Полевой исследователь Ученые сталкеры Сообщений: 2399 | Редактирование и создание скриптов 
 Редактирование и создание скриптов на языке 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 по ссылке из шапки и соседнюю тему "Курс молодого бойца",
 возможно Ваш вопрос уже рассматривался.
 
 
 Если произошел вылет - выкладываем лог! Вопрос ставим четко, не забываем указывать версию игры, установленные моды их версии, установленные фиксы модов и подробно ваши правки. Помните чем подробнее вопрос, тем точнее ответ.
 
 "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
 (Чугунный всадник)
 
   |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |  |  |  | 
| denis2000 | Дата: Вт, 02.06.2015, 08:29 | Сообщение # 646 |  |  Полевой исследователь Ученые сталкеры Сообщений: 2399 | Цитата sergej5500 (  ) Можно ли этот параметр перенести в секцию сквада?ЗАЧЕМ!? Просто НПС получает по умолчанию хит даже если этой строки в его логике нет или даже самой логики нет: local can_hit_anomaly = true
 
 "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
 (Чугунный всадник)
 
   |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Вт, 02.06.2015, 09:45 | Сообщение # 647 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | Цитата denis2000 (  ) ЗАЧЕМ!?
 Нужно параметр, запрещающий нанесение хита неписю, прописать в секции сквада. Если он прописан в логике, то он не действует, пока неписи не заняли работы в смарте.
 
 Для этого надо поправить функцию.
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| denis2000 | Дата: Вт, 02.06.2015, 12:27 | Сообщение # 648 |  |  Полевой исследователь Ученые сталкеры Сообщений: 2399 | sergej5500, Теперь понятно. Значит пробуйте так: 
 Код local can_hit_anomaly = true  local st_npc = db.storage[ npc:id() ]
 local hit_anomaly = nil
 local squad = get_object_squad(npc)
 
 if squad ~= nil then
 hit_anomaly = utils.cfg_get_string(sim_board.squad_ltx, squad:section_name(), "hit_anomaly", npc, false, "", nil)
 end
 
 if hit_anomaly == nil then
 hit_anomaly = utils.cfg_get_string( st_npc.ini, st_npc.active_section, "hit_anomaly", npc, false, "", nil)
 end
 
 if hit_anomaly ~= nil then
 local condlist = xr_logic.parse_condlist( npc, st_npc.active_section, "hit_anomaly", hit_anomaly )
 can_hit_anomaly = xr_logic.pick_section_from_condlist( db.actor, npc, condlist ) == "true"
 end
 "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
 (Чугунный всадник)
 
   |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Сб, 06.06.2015, 13:03 | Сообщение # 649 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | Добрый день. 
 В аддоне Припять - Точка Отсчета (приквел к Время Альянса) есть функция рандомного спавна аномалий. Возникла идея сделать рандомный спавн артефактов. После выброса спавнит арты. Штук 30-50.
 
 Чтобы артефакты не размножались бесконтрольно, решил адаптировать функцию из Время Альянса (уборка оружия). Произвести чистку локации от артефактов при старте выброса.
 [cut=Функция]
 
 function add_cleaner_artefact(actor,obj)
 for i = 1,65534 do local object = alife():object(i) if object then
 if object:section_name() ~= nil then if string.find(object:section_name(),"af_cristall") or string.find(object:section_name(),"af_fireball") or string.find(object:section_name(),"af_dummy_glassbeads")
 or string.find(object:section_name(),"af_eye") or string.find(object:section_name(),"af_fire") or string.find(object:section_name(),"af_medusa")
 or string.find(object:section_name(),"af_cristall_flower") or string.find(object:section_name(),"af_night_star") or string.find(object:section_name(),"af_vyvert")
 or string.find(object:section_name(),"af_gravi") or string.find(object:section_name(),"af_gold_fish") or string.find(object:section_name(),"af_blood")
 or string.find(object:section_name(),"af_mincer_meat") or string.find(object:section_name(),"af_soul") or string.find(object:section_name(),"af_fuzz_kolobok")
 or string.find(object:section_name(),"af_baloon") or string.find(object:section_name(),"af_glass") or string.find(object:section_name(),"af_electra_sparkler")
 or string.find(object:section_name(),"af_electra_flash") or string.find(object:section_name(),"af_electra_moonlight") or string.find(object:section_name(),"af_dummy_battery")
 or string.find(object:section_name(),"af_dummy_dummy") or string.find(object:section_name(),"af_ice") or string.find(object:section_name(),"af_monolit")
 or string.find(object:section_name(),"af_geliy") or string.find(object:section_name(),"af_vaselisk") or string.find(object:section_name(),"af_dragon_eye")
 then
 local parent_id = object.parent_id if parent_id and parent_id == 65535 then
 alife():release(alife():object(object.id),true) end end end end end
 end[/cut]
 
 При тестовом запуске функции обнаружил, что она убирает артефакты, спавнящиеся в аномальных зонах оригинальной игры.
 
 Можно ли исправить функцию, чтобы она не трогала артефакты в аномальных зонах.
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| makdm | Дата: Сб, 06.06.2015, 13:59 | Сообщение # 650 |  |  Рожденный в СССР Разработчики Сообщений: 1294 | sergej5500, вот так попробуй написать функцию 
 
 Код function add_cleaner_artefact ( actor, obj ) for i = 1,65534 do
 local object = alife():object( i )
 if object then
 if object:clsid() == clsid.artefact and object.parent_id == 65535 then
 local can_delete = bind_anomaly_zone.artefact_ways_by_id[ object.id ] == nil
 if can_delete then
 alife():release( alife():object( object.id ), true )
 end
 end
 end
 end
 end
 Терпение......
 И все получится!
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Вс, 14.06.2015, 10:29 | Сообщение # 651 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | Всем добрый день. 
 Попробовал сделать в оригинальном Зове Припяти закладываемые рюкзаки, как в СГМ. Хочу использовать минимум функций из СГМ.
 
 [cut=Пробный рюкзак][test_inventory_box]:inventory_box
 $spawn 				= "devices\test_inventory box"
 story_id = test_inventory_box
 visual				= dynamics\devices\dev_rukzak\dev_rukzak.ogf
 custom_data 	= scripts\test_inventory_box_1.ltx[/cut]
 
 [cut=Логика][logic]
 active = ph_idle@enable
 
 [ph_idle@enable]
 tips = inventory_box_use
 nonscript_usable = true
 ;on_info = {=dist_to_actor_ge(15)} %=destroy_object%[/cut]
 
 [cut=Тестовая функция спавна]elseif dik==DIK_keys.DIK_F6 then
 local p=vector(),lv,gv
 p.x=db.actor:position().x+0.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("test_inventory_box",p,lv,gv) [/cut]
 
 Рюкзак спавнится. В него можно закладывать вещи. Логика рюкзака работает. При удалении от игрока он исчезает.
 
 Возникло несколько идей.
 
 1. Сделать на локации десяток рюкзаков с рандомным спавном. Можно применить функцию спавна аномалий из Припять - Точка Отсчета. Раз у рюкзака есть логика, то пусть они заполняют себя сами. Возникли вопросы.
 
 Как сделать функцию рандомного спавна предметов в рюкзак. Например, 5 предметов из списка. Функция должна быть общей для всех рюкзаков. Вызываться их логики рюкзака. И спавнить предметы именно в этот рюкзак.
 
 Как проверить, пустой ли рюкзак? Допустим, игрок его обчистил. Дальше рюкзак не нужен. Функция проверки должна вызываться из логики рюкзака.
 
 2. Возникла мысль использовать рюкзаки для спавна аномалий. Заложили мы рюкзак, отошли на 10 метров. Рюкзак исчез. На его месте заспавнилась Электра. Функция спавна аномалии должна вызываться из логики рюкзака. И спавнить аномалию в точке нахождения рюкзака.
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| makdm | Дата: Вс, 14.06.2015, 11:21 | Сообщение # 652 |  |  Рожденный в СССР Разработчики Сообщений: 1294 | sergej5500, по первому пункту ответ здесь: 
 [cut noguest=Функции и логика рюкзака]Логика рюкзака:
 
 [logic]
 active = ph_idle@spawn
 
 [ph_idle@spawn]
 on_info = ph_idle@enable %=spawn_items_in_rukzak%
 
 [ph_idle@enable]
 tips = inventory_box_use
 nonscript_usable = true
 on_info = {=dist_to_actor_ge(15) =rukzak_is_empty} %=destroy_object%
 
 Функция в xr_conditions.script
 
 function rukzak_is_empty ( actor, obj )
 return obj:is_inv_box_empty()
 end
 
 Функция в xr_effects.script
 
 function spawn_items_in_rukzak ( actor, obj )
 
 local items_table = {"предмет_1","предмет_2",............} -- здесь секции хоть 100 предметов пропишите
 
 local position 	= obj:position()
 local gv_id 	= obj:game_vertex_id()
 local lv_id 	= obj:level_vertex_id()
 local obj_id 	= obj:id()
 
 for i = 1,5 do --количество предметов проспавнится в рюкзак
 
 alife():create( items_table[ math.random( #items_table ) ], position, lv_id, gv_id, obj_id )
 
 end
 
 end[/cut]
 
 По второму пункту ответ здесь
 
 [cut noguest=Функции и логика]Логика рюкзака:
 
 [logic]
 active = ph_idle@enable
 
 [ph_idle@enable]
 tips = inventory_box_use
 nonscript_usable = true
 on_info = {=dist_to_actor_ge(10)} ph_idle@nil %=spawn_anom_and_destroy%
 
 [ph_idle@nil]
 
 Функция в xr_effects.script
 
 function spawn_anom_and_destroy ( actor, obj )
 
 local position = obj:position()
 local gv_id = obj:game_vertex_id()
 local lv_id = obj:level_vertex_id()
 local radius	= 3
 create_anomaly( "zone_witches_galantine_average", radius, position, lv_id, gv_id )
 
 local se_obj = alife():object( obj:id() )
 if se_obj then
 alife():release( se_obj, true )
 end
 end
 
 function create_anomaly( zone_name, zone_radius, position, lv, gv )
 
 ----------------------------Создаём объект-аномалию
 
 local sobj = alife():create( zone_name, position, lv, gv )
 
 local packet = net_packet()
 packet:w_begin( 0 )
 
 -------------------------------------Читаем нет-пакет
 sobj:STATE_Write( packet )
 packet:r_seek( 2 )
 
 local game_vertex_id	=	packet:r_u16()
 local distance			=	packet:r_float()
 local direct_control	=	packet:r_s32()
 local level_vertex_id	=	packet:r_s32()
 local object_flags		=	packet:r_s32()
 local custom_data		=	packet:r_stringZ()
 local story_id			=	packet:r_s32()
 local spawn_story_id	=	packet:r_s32()
 local shape_count		=	packet:r_u8()
 for i = 1,shape_count do
 local shape_type = packet:r_u8()
 if shape_type == 0 then
 local center = packet:r_vec3()
 local radius = packet:r_float()
 else
 local box = packet:r_matrix()
 end
 end
 local restrictor_type				=	packet:r_u8()
 local max_power						=	packet:r_float()
 local owner_id						=	packet:r_s32()
 local enabled_time					=	packet:r_u32()
 local disabled_time					=	packet:r_u32()
 local start_time_shift				=	packet:r_u32()
 local offline_interactive_radius	=	packet:r_float()
 local artefact_spawn_count			=	packet:r_u16()
 local artefact_position_offset		=	packet:r_s32()
 local last_spawn_time				=	packet:r_u8()
 
 ------------------------------------------Меняем данные пакета
 
 local new_center = vector():set( 0, 0, 0 )
 owner_id		=	bit_not( 0 )
 restrictor_type	= 3
 max_power = 0
 offline_interactive_radius	= 30
 artefact_spawn_count	= 32
 last_spawn_time = 0
 ------------------------------------------------Пишем в пакет
 
 packet:w_begin( 0 )
 packet:w_u16( game_vertex_id )
 packet:w_float( distance )
 packet:w_s32( direct_control )
 packet:w_s32( level_vertex_id )
 packet:w_s32( object_flags )
 packet:w_stringZ( custom_data )
 packet:w_s32( story_id )
 packet:w_s32( spawn_story_id )
 packet:w_u8( 1 )
 packet:w_u8( 0 )
 packet:w_vec3( new_center )
 packet:w_float( zone_radius )
 packet:w_u8( restrictor_type )
 packet:w_float( max_power )
 packet:w_s32( owner_id )
 packet:w_u32( enabled_time )
 packet:w_u32( disabled_time )
 packet:w_u32( start_time_shift )
 packet:w_float( offline_interactive_radius )
 packet:w_u16( artefact_spawn_count )
 packet:w_s32( artefact_position_offset )
 packet:w_u8( last_spawn_time )
 
 packet:r_seek( 2 )
 sobj:STATE_Read( packet, packet:w_tell() )
 return sobj
 end[/cut]
 
 Терпение......
 И все получится!
 
 
 Сообщение отредактировал makdm - Вс, 14.06.2015, 11:38 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Чт, 18.06.2015, 16:47 | Сообщение # 653 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | Добрый день. 
 Попробовал сделать в чистом ЗП бустер для телепортации игрока. Как в СГМ 2.2.
 
 [cut=bind_stalker]
 function actor_binder:use_inventory_item(obj)
 if(obj) then
 local s_obj = alife():object(obj:id())
 if s_obj and s_obj:section_name()=="drug_anabiotic" then
 xr_effects.disable_ui_only(db.actor, nil)
 level.add_cam_effector("camera_effects\\surge_02.anm", 10, false, "bind_stalker.anabiotic_callback")
 level.add_pp_effector("surge_fade.ppe", 11, false)
 give_info("anabiotic_in_process")
 _G.mus_vol = get_console():get_float("snd_volume_music")
 _G.amb_vol = get_console():get_float("snd_volume_eff")
 get_console():execute("snd_volume_music 0")
 get_console():execute("snd_volume_eff 0")
 end
 if s_obj and s_obj:section_name()=="gps_navigator" then
 addon_start_gui(gps_navigator.ui_esc_gps_navigator(),true) --Запускаем Gui
 end
 
 end
 end[/cut]
 
 [cut=_g]--Запуск Gui
 function addon_start_gui(gui, close_inv)
 if close_inv == true then
 gui:ShowDialog(true)
 game_hide_menu()
 level.show_weapon(false)
 else gui:ShowDialog(true)
 end
 end[/cut]
 
 [cut=gps_navigator.script]class "ui_esc_gps_navigator" (CUIScriptWnd) --Регистрация нового класса гуи-элемента от существующего класса CUIScriptWnd
 
 function ui_esc_gps_navigator:__init(owner) super() --Иницилизируем класс, добавляем отсылки к функциям
 self.owner = owner
 self:InitControls() --Отсылка к функции регистрации элементов окна
 self:InitCallBacks() --Отсылка к функции регистрации коллбеков (условий)
 end
 
 function ui_esc_gps_navigator:__finalize() --Функция завершения работы нового класса
 end
 
 function ui_esc_gps_navigator:InitControls() --Функция иницилизации элементов окна
 self:SetWndRect (Frect():set(0,0,1024,768)) --Установка стандартных размеров файла
 local xml, ctrl = CScriptXmlInit(), CUIWindow() --Задаем локальные переменные на классы
 xml:ParseFile ("ui_esc_gps_navigator.xml") --Инициализация XML-файла Gui-элемента
 self.esc_gps_navigator = xml:InitStatic("esc_gps_navigator",self) --Регистрируем само окно
 
 xml:InitStatic ("esc_gps_navigator:esc_gps_navigator_start",self.esc_gps_navigator) --Регистрация текста: заглавие
 
 self.button_escape_b1 = xml:Init3tButton ("esc_gps_navigator:btn_esc_b1",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_b1, "button_esc_b1")
 
 self.button_escape_b2 = xml:Init3tButton ("esc_gps_navigator:btn_esc_b2",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_b2, "button_esc_b2")
 
 self.button_escape_b3 = xml:Init3tButton ("esc_gps_navigator:btn_esc_b3",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_b3, "button_esc_b3")
 
 self.button_escape_b4 = xml:Init3tButton ("esc_gps_navigator:btn_esc_b4",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_b4, "button_esc_b4")
 
 self.button_escape_b5 = xml:Init3tButton ("esc_gps_navigator:btn_esc_b5",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_b5, "button_esc_b5")
 
 self.button_escape_b5 = xml:Init3tButton ("esc_gps_navigator:btn_esc_b6",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_b6, "button_esc_b6")
 
 self.button_escape_b7 = xml:Init3tButton ("esc_gps_navigator:btn_esc_b7",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_b7, "button_esc_b7")
 
 self.button_escape_b8 = xml:Init3tButton ("esc_gps_navigator:btn_esc_b8",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_b8, "button_esc_b8")
 
 self.button_escape_b9 = xml:Init3tButton ("esc_gps_navigator:btn_esc_b9",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_b9, "button_esc_b9")
 
 self.button_escape_b10 = xml:Init3tButton ("esc_gps_navigator:btn_esc_b10",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_b10, "button_esc_b10")
 
 self.button_escape_glose = xml:Init3tButton ("esc_gps_navigator:btn_esc_close",self.esc_gps_navigator) --Регистрация кнопки
 self:Register (self.button_escape_glose, "button_esc_glose")
 
 end
 
 function esc_gps_navigator:InitCallBacks() --Функци коллбеков
 self:AddCallback("button_esc_b1", ui_events.BUTTON_CLICKED, self.OnButton_esc_b1_clicked, self) --Коллбек кнопки
 self:AddCallback("button_esc_b2", ui_events.BUTTON_CLICKED, self.OnButton_esc_b2_clicked, self) --Коллбек кнопки
 self:AddCallback("button_esc_b3", ui_events.BUTTON_CLICKED, self.OnButton_esc_b3_clicked, self) --Коллбек кнопки
 self:AddCallback("button_esc_b4", ui_events.BUTTON_CLICKED, self.OnButton_esc_b4_clicked, self) --Коллбек кнопки
 self:AddCallback("button_esc_b5", ui_events.BUTTON_CLICKED, self.OnButton_esc_b5_clicked, self) --Коллбек кнопки
 self:AddCallback("button_esc_b6", ui_events.BUTTON_CLICKED, self.OnButton_esc_b6_clicked, self) --Коллбек кнопки
 self:AddCallback("button_esc_b7", ui_events.BUTTON_CLICKED, self.OnButton_esc_b7_clicked, self) --Коллбек кнопки
 self:AddCallback("button_esc_b8", ui_events.BUTTON_CLICKED, self.OnButton_esc_b8_clicked, self) --Коллбек кнопки
 self:AddCallback("button_esc_b9", ui_events.BUTTON_CLICKED, self.OnButton_esc_b9_clicked, self) --Коллбек кнопки
 self:AddCallback("button_esc_b10", ui_events.BUTTON_CLICKED, self.OnButton_esc_b10_clicked, self) --Коллбек кнопки
 self:AddCallback("button_esc_glose", ui_events.BUTTON_CLICKED, self.OnButton_esc_glose_clicked, self) --Коллбек кнопки
 end
 
 function esc_gps_navigator:OnKeyboard(dik,keyboard_action) --Функция закрытия окна по нажатию на клавиатуре "Escape"
 CUIScriptWnd.OnKeyboard(self,dik,keyboard_action) --Инициализируем нажатие кнопки на клаве
 if keyboard_action == ui_events.WINDOW_KEY_PRESSED then --Условие: если нажата кнопка на клаве
 if dik == DIK_keys.DIK_ESCAPE then --Условие: если нажата конкретно кнопка "Escape"
 self:HideDialog() --То при нажатии на кнопку - закрываем окошко
 give_object_to_actor("gps_navigator") --Выдаем обратно прыгунок
 end
 end
 return true
 end
 
 function esc_gps_navigator:OnButton_esc_b1_clicked() --Функция коллбека кнопки
 xr_effects.teleport_actor(actor,nil,{"esc_gps_navigator_1_walk","esc_gps_navigator_1_look"})
 self:HideDialog()
 end
 function esc_gps_navigator:OnButton_esc_b2_clicked() --Функция коллбека кнопки
 xr_effects.teleport_actor(actor,nil,{"esc_gps_navigator_2_walk","esc_gps_navigator_2_look"})
 self:HideDialog()
 end
 function esc_gps_navigator:OnButton_esc_b3_clicked() --Функция коллбека кнопки
 xr_effects.teleport_actor(actor,nil,{"esc_gps_navigator_3_walk","esc_gps_navigator_3_look"})
 self:HideDialog()
 end
 function esc_gps_navigator:OnButton_esc_b4_clicked() --Функция коллбека кнопки
 xr_effects.teleport_actor(actor,nil,{"esc_gps_navigator_4_walk","esc_gps_navigator_4_look"})
 self:HideDialog()
 end
 function esc_gps_navigator:OnButton_esc_b5_clicked() --Функция коллбека кнопки
 xr_effects.teleport_actor(actor,nil,{"esc_gps_navigator_5_walk","esc_gps_navigator_5_look"})
 self:HideDialog()
 end
 function esc_gps_navigator:OnButton_esc_b6_clicked() --Функция коллбека кнопки
 xr_effects.teleport_actor(actor,nil,{"esc_gps_navigator_6_walk","esc_gps_navigator_6_look"})
 self:HideDialog()
 end
 function esc_gps_navigator:OnButton_esc_b7_clicked() --Функция коллбека кнопки
 xr_effects.teleport_actor(actor,nil,{"esc_gps_navigator_7_walk","esc_gps_navigator_7_look"})
 self:HideDialog()
 end
 function esc_gps_navigator:OnButton_esc_b8_clicked() --Функция коллбека кнопки
 xr_effects.teleport_actor(actor,nil,{"esc_gps_navigator_8_walk","esc_gps_navigator_8_look"})
 self:HideDialog()
 end
 function esc_gps_navigator:OnButton_esc_b9_clicked() --Функция коллбека кнопки
 xr_effects.teleport_actor(actor,nil,{"esc_gps_navigator_9_walk","esc_gps_navigator_9_look"})
 self:HideDialog()
 end
 function esc_gps_navigator:OnButton_esc_b10_clicked() --Функция коллбека кнопки
 xr_effects.teleport_actor(actor,nil,{"esc_gps_navigator_10_walk","esc_gps_navigator_10_look"})
 self:HideDialog()
 end
 function esc_gps_navigator:OnButton_esc_glose_clicked() --Функция коллбека кнопки
 give_object_to_actor("gps_navigator") --Выдаем обратно прыгунок
 self:HideDialog()
 end
 [/cut]
 
 [cut=ui_esc_gps_navigator]<?xml version="1.0" encoding="windows-1251" ?>
 <g>
 <esc_gps_navigator x="0" y="0" width="1024" height="768" stretch="1">
 <texture x="0" y="0" width="1024" height="768">ui\ui_gps_navigator</texture>
 
 <esc_gps_navigator_start x="280" y="20" width="600" height="35">
 <text font="graffiti32" align="c">st_gps_navigator_start</text>
 </esc_gps_navigator_start>
 <btn_esc_b1 x="50" y="150" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b1_name</text>
 </btn_esc_b1>
 <btn_esc_b2 x="50" y="200" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b2_name</text>
 </btn_esc_b2>
 <btn_esc_b3 x="50" y="250" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b3_name</text>
 </btn_esc_b3>
 <btn_esc_b4 x="50" y="300" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b4_name</text>
 </btn_esc_b4>
 <btn_esc_b5 x="50" y="350" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b5_name</text>
 </btn_esc_b5>
 <btn_esc_b6 x="350" y="150" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b6_name</text>
 </btn_esc_b6>
 <btn_esc_b7 x="350" y="200" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b7_name</text>
 </btn_esc_b7>
 <btn_esc_b8 x="350" y="250" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b8_name</text>
 </btn_esc_b8>
 <btn_esc_b9 x="350" y="300" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b9_name</text>
 </btn_esc_b9>
 <btn_esc_b10 x="350" y="350" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b10_name</text>
 </btn_esc_b10>
 <btn_esc_close x="420" y="630" width="120" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">ui_mm_cancel</text>
 </btn_esc_close>
 
 </esc_gps_navigator>
 
 </g>[/cut]
 
 При таком варианте кода ничего не происходит. Бустер исчезает и все.
 
 Если написать код так.
 
 [cut=ui_esc_gps_navigator]<?xml version="1.0" encoding="windows-1251" ?>
 <g>
 <esc_gps_navigator x="0" y="0" width="1024" height="768" stretch="1">
 <texture x="0" y="0" width="1024" height="768">ui\ui_gps_navigator</texture>
 </esc_gps_navigator>
 
 <esc_gps_navigator_start x="280" y="20" width="600" height="35">
 <text font="graffiti32" align="c">st_gps_navigator_start</text>
 </esc_gps_navigator_start>
 <btn_esc_b1 x="50" y="150" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b1_name</text>
 </btn_esc_b1>
 <btn_esc_b2 x="50" y="200" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b2_name</text>
 </btn_esc_b2>
 <btn_esc_b3 x="50" y="250" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b3_name</text>
 </btn_esc_b3>
 <btn_esc_b4 x="50" y="300" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b4_name</text>
 </btn_esc_b4>
 <btn_esc_b5 x="50" y="350" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b5_name</text>
 </btn_esc_b5>
 <btn_esc_b6 x="350" y="150" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b6_name</text>
 </btn_esc_b6>
 <btn_esc_b7 x="350" y="200" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b7_name</text>
 </btn_esc_b7>
 <btn_esc_b8 x="350" y="250" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b8_name</text>
 </btn_esc_b8>
 <btn_esc_b9 x="350" y="300" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b9_name</text>
 </btn_esc_b9>
 <btn_esc_b10 x="350" y="350" width="200" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">st_esc_b10_name</text>
 </btn_esc_b10>
 <btn_esc_close x="420" y="630" width="120" height="25" stretch="1">
 <texture>ui_inGame2_Mp_bigbuttone</texture>
 <text font="letterica18">ui_mm_cancel</text>
 </btn_esc_close>
 
 </g>[/cut]
 
 Игра начинает вылетать с логами типа
 
 [cut=Логи]
 [/cut]Цитата FATAL ERROR 
 [error]Expression : xml_doc.NavigateToNode(path,index)
 [error]Function : CUIXmlInit::Init3tButton
 [error]File : D:\prog_repository\sources\trunk\xrGame\ui\UIXmlInit.cpp
 [error]Line : 355
 [error]Description : XML node not found
 [error]Argument 0 : esc_gps_navigator:btn_esc_b1
 [error]Argument 1 : ui\ui_esc_gps_navigator_16.xml
 
 stack trace:
 
 FATAL ERROR
 
 [error]Expression : xml_doc.NavigateToNode(path,index)
 [error]Function : CUIXmlInit::InitStatic
 [error]File : D:\prog_repository\sources\trunk\xrGame\ui\UIXmlInit.cpp
 [error]Line : 156
 [error]Description : XML node not found
 [error]Argument 0 : esc_gps_navigator:esc_gps_navigator_start
 [error]Argument 1 : ui\ui_esc_gps_navigator_16.xml
 
 stack trace:
 В каком месте допущена ошибка?
 
 
 Сообщение отредактировал sergej5500 - Чт, 18.06.2015, 16:55 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| denis2000 | Дата: Чт, 18.06.2015, 21:45 | Сообщение # 654 |  |  Полевой исследователь Ученые сталкеры Сообщений: 2399 | sergej5500, Первый XML естественно верный. А вот по скрипту вопрос: Класс объявляете ui_esc_gps_navigator, а методы написаны для esc_gps_navigator. 
 "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
 (Чугунный всадник)
 
   |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Вт, 23.06.2015, 21:07 | Сообщение # 655 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | Добрый вечер. 
 В аддоне Время Альянса нашел функцию рандомного спавна предметов в инвентарные ящики на локации.
 
 [cut=Функция]
 function spawn_treasure_items(items_table, count, inv_box_story_id)
 local inv_box = alife():object(get_story_object_id(inv_box_story_id))
 for i = 1,count do
 alife():create(items_table[math.random(#items_table)],inv_box.position,inv_box.m_level_vertex_id,inv_box.m_game_vertex_id,inv_box.id)
 end
 end[/cut]
 
 Как усовершенствовать эту функцию? Нужно, чтобы спавн происходил только в пустой ящик. То есть, если в ящике что-то есть, то спавн в него проходить не должен.
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| makdm | Дата: Ср, 24.06.2015, 00:51 | Сообщение # 656 |  |  Рожденный в СССР Разработчики Сообщений: 1294 | sergej5500, нужно добавить проверку: 
 
 Код function spawn_treasure_items(items_table, count, inv_box_story_id)   local inv_box = alife():object(get_story_object_id(inv_box_story_id))
 local obj_inv_box = get_story_object( inv_box_story_id )
 if obj_inv_box and obj_inv_box:is_inv_box_empty()  then
 for i = 1,count do
 alife():create(items_table[math.random(#items_table)],inv_box.position,inv_box.m_level_vertex_id,inv_box.m_game_vertex_id,inv_box.id)
 end
 end
 end
 
 Терпение......
 И все получится!
 
 
 Сообщение отредактировал makdm - Ср, 24.06.2015, 00:53 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |  |  |  | 
| avn1975 | Дата: Пн, 20.07.2015, 20:53 | Сообщение # 657 |  | Гражданский Пользователи Сообщений: 15 | как сделать выброс через реститор 
 
 Сообщение отредактировал avn1975 - Сб, 25.07.2015, 23:18 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили avn1975 за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Пн, 27.07.2015, 22:46 | Сообщение # 658 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | avn1975, 
 Для запуска выброса есть функция
 
 function start_surge(actor, npc, p)
 surge_manager.start_surge(p)
 end
 
 Вызвать её можно так:
 
 on_info = {Условие} %=start_surge%
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| avn1975 | Дата: Пт, 31.07.2015, 16:19 | Сообщение # 659 |  | Гражданский Пользователи Сообщений: 15 | как зделать при старте нпс побежали пример скрипта https://yadi.sk/d/UglbUgs2iCWrZ |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили avn1975 за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Сб, 22.08.2015, 00:08 | Сообщение # 660 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | Добрый вечер. 
 Функция для спавна аномалий по координатам.
 
 [cut=Код]
 function create_anomaly_2( zone_name, zone_radius, x, y, z, lv, gv )
 ----------------------------Создаём объект-аномалию
 local sobj = alife():create(zone_name,vector():set(x,y,z),lv,gv)
 local packet = net_packet()
 packet:w_begin(0)
 -------------------------------------Читаем нет-пакет
 sobj:STATE_Write(packet)
 packet:r_seek(2)
 local game_vertex_id = packet:r_u16()
 local distance = packet:r_float()
 local direct_control = packet:r_s32()
 local level_vertex_id = packet:r_s32()
 local object_flags = packet:r_s32()
 local custom_data = packet:r_stringZ()
 local story_id = packet:r_s32()
 local spawn_story_id = packet:r_s32()
 local shape_count = packet:r_u8()
 for i = 1,shape_count do
 local shape_type = packet:r_u8()
 if shape_type == 0 then
 local center = packet:r_vec3()
 local radius = packet:r_float()
 else
 local box = packet:r_matrix()
 end
 end
 local restrictor_type = packet:r_u8()
 local max_power = packet:r_float()
 local owner_id = packet:r_s32()
 local enabled_time = packet:r_u32()
 local disabled_time = packet:r_u32()
 local start_time_shift = packet:r_u32()
 local offline_interactive_radius = packet:r_float()
 local artefact_spawn_count = packet:r_u16()
 local artefact_position_offset = packet:r_s32()
 ------------------------------------------Меняем данные пакета
 local new_center = vector():set(0,0,0)
 owner_id = bit_not(0)
 restrictor_type = 3
 max_power = 0
 if (zone_name == "sgm_mine_trap" or zone_name == "zone_mine_field") then
 offline_interactive_radius = 225
 else
 offline_interactive_radius = 30
 end
 artefact_spawn_count = 32
 ------------------------------------------------Пишем в пакет
 packet:w_begin(0)
 packet:w_u16(game_vertex_id)
 packet:w_float(distance)
 packet:w_s32(direct_control)
 packet:w_s32(level_vertex_id)
 packet:w_s32(object_flags)
 packet:w_stringZ(custom_data)
 packet:w_s32(story_id)
 packet:w_s32(spawn_story_id)
 packet:w_u8(1)
 packet:w_u8(0)
 packet:w_vec3(new_center)
 packet:w_float(zone_radius)
 packet:w_u8(restrictor_type)
 packet:w_float(max_power)
 packet:w_s32(owner_id)
 packet:w_u32(enabled_time)
 packet:w_u32(disabled_time)
 packet:w_u32(start_time_shift)
 packet:w_float(offline_interactive_radius)
 packet:w_u16(artefact_spawn_count)
 packet:w_s32(artefact_position_offset)
 packet:r_seek(2)
 sobj:STATE_Read(packet,packet:w_tell())
 return sobj
 end[/cut]
 
 Для отдельных аномалий работает отлично. Попробовал заспавнить пачку аномалий. Штук 100. Кодом типа.
 
 [cut=Код]
 function test_anomaly_spawn()
 local anomaly = {
 "sgm_zone_mine_electric_weak",
 "sgm_zone_mine_gravitational_weak",
 "sgm_zone_mine_streem_weak",
 "sgm_zone_mine_steam_weak",
 "sgm_zone_mine_thermal_weak"
 }
 for i = 1, 100 do
 local section = anomaly[math.random(#anomaly)]
 sgm_packet.create_anomaly_2(section,4,-330.95910644531+math.random(-100,100),18.076812744141,344.20275878906+math.random(-100,100),289384,1 21)
 end
 end[/cut]
 
 Аномалии должны были заспавниться в квадрате 200 на 200 метров. Центр квадрата - Лесопилка на Затоне. Получил следующее. Аномалии заспавнились.
 
 Точка съема координат - верхнее здание Лесопилки. Тут с аномалиями все в норме.
 
   
 Спустившись вниз, увидел это. Все аномалии заспавнились на одной высоте. И оказались в воздухе.
 
   
   
 Можно ли поправить функцию так, чтобы она спавнила аномалии на AI-сетке? Корректировала высоту?
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  |