| 
	
		
		
			| Модостроение. Редактирование и создание скриптов |  | 
				
			 |  | 
| 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 за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Сб, 16.05.2015, 14:05 | Сообщение # 631 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | makdm, 
 Попробовал использовать функции, предложенные тут.
 
 if has_alife_info("opt_deactivate_minetrap") then
 self.object:disable_mine()
 else
 self.object:enable_mine()
 end
 end
 
 Получил жука:
 
 в Припяти\gamedata\scripts\bind_anomaly_field.script:56: attempt to call method 'enable_mine'
 
 Почему enable_anomaly из этого скрипта вызвать можно, а enable_mine нет?
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| makdm | Дата: Сб, 16.05.2015, 14:16 | Сообщение # 632 |  |  Рожденный в СССР Разработчики Сообщений: 1294 | Цитата sergej5500 (  ) Почему enable_anomaly из этого скрипта вызвать можно, а enable_mine нет?Я вам выше написал решение вашей проблемы.
 
 А вылет потому что вы путаете функции файла xr_effects.script и методы движка.
 
 Терпение......
 И все получится!
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Сб, 16.05.2015, 15:59 | Сообщение # 633 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | makdm, 
 Спасибо за помощь. Пока решил опробовать вариант с полным перебором объектов.
 
 Сделал функции.
 
 [cut=bind_anomaly_field]function anomaly_field_binder:update(delta)
 if string.find(self.object:section(),"sgm_mine_trap") ~= nil then
 if has_alife_info("opt_deactivate_minetrap") and dont_has_alife_info("sgm_mine_trap_disable") then
 disable_sgm_mine_trap() give_info("sgm_mine_trap_disable")
 end
 if dont_has_alife_info("opt_deactivate_minetrap") and has_alife_info("sgm_mine_trap_disable") then
 enable_sgm_mine_trap() disable_info("sgm_mine_trap_disable")
 end
 end
 object_binder.update(self, delta)
 sgm_modules.module_anomaly_field(self.object)
 if (time_global()-self.last_update<10000) then
 return
 end
 self.last_update = time_global()
 end
 
 function disable_sgm_mine_trap(find_string)
 for a=1,65534 do
 local obj = alife():object(a)
 if obj then
 if obj:section_name()~=nil and string.find(self.object:section(),"sgm_mine_trap") ~= nil then
 obj:disable_anomaly()
 end
 end
 end
 end
 
 function enable_sgm_mine_trap(find_string)
 for a=1,65534 do
 local obj = alife():object(a)
 if obj then
 if obj:section_name()~=nil and string.find(self.object:section(),"sgm_mine_trap") ~= nil then
 obj:enable_anomaly()
 end
 end
 end
 end[/cut]
 
 После выдачи инфопорции получил вылет на строке string.find(self.object:section(),"sgm_mine_trap") ~= nil
 
 Лог: attempt to index global 'self' (a nil value)
 
 Почему функция вылетела? Эта функция работает.
 
 [cut=disable_mine]function disable_mine(actor, npc, p)
 local mine = db.zone_by_name[p[1]]
 if mine == nil then
 return
 end
 mine:disable_anomaly()
 end[/cut]
 
 
 Сообщение отредактировал sergej5500 - Сб, 16.05.2015, 16:00 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| makdm | Дата: Сб, 16.05.2015, 17:16 | Сообщение # 634 |  |  Рожденный в СССР Разработчики Сообщений: 1294 | Цитата sergej5500 (  ) Пока решил опробовать вариант с полным перебором объектов.Функция написана неправильно.
 sergej5500, я же объяснил вам, что после того, как вы выключите аномалию, она будет удалена движком.
 Вот как вы её затем включите, если её уже нет в игре? Вы что включать будете?
 Поэтому то , что вы написали в биндере уже не имеет смысла.
 
 Терпение......
 И все получится!
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Сб, 16.05.2015, 17:45 | Сообщение # 635 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | Цитата makdm (  ) я же объяснил вам, что после того, как вы выключите аномалию, она будет удалена движком
 Задача имеет решение. Для отдельных мин. Ваш пост.
 
 Только что проверил на тестовых минах.
 
 [cut=Рестриктор][logic]
 active = sr_idle@start
 
 [sr_idle@start]
 on_info = {+opt_deactivate_minetrap} sr_idle@control %=disable_mine(esc_sgm_mine_trap_1) =disable_mine(esc_sgm_mine_trap_2)%
 
 [sr_idle@control]
 on_info = {-opt_deactivate_minetrap} sr_idle@start %=enable_mine(esc_sgm_mine_trap_1) =enable_mine(esc_sgm_mine_trap_2)% [/cut]
 
 [cut=xr_effects]
 
 function disable_mine(actor, npc, p)
 local mine = db.zone_by_name[p[1]]
 if mine == nil then
 return
 end
 mine:disable_anomaly()
 end
 
 function enable_mine(actor, npc, p)
 local mine = db.zone_by_name[p[1]]
 if mine == nil then
 return
 end
 mine:enable_anomaly()
 end[/cut]
 
 Мины отключаются и включаются. При отключенной опции кабаны подрываются. При включенной они свободно ходят по минам.
 
 Если эти функции применимы к отдельным минам, то наверно, можно отключить их оптом, проверив название секции объекта.
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| makdm | Дата: Вс, 17.05.2015, 12:00 | Сообщение # 636 |  |  Рожденный в СССР Разработчики Сообщений: 1294 | sergej5500, возможно я ошибся, так как проверял только клиентский класс мин. Тогда напишите функции так:
 
 function disable_sgm_mine_trap(actor, npc)
 for k,v in pairs( db.zone_by_name ) do
 if v and string.find(v:section(),"sgm_mine_trap") ~= nil then
 v:disable_anomaly()
 end
 end
 end
 
 function enable_sgm_mine_trap(actor, npc)
 for k,v in pairs( db.zone_by_name ) do
 if v and string.find(v:section(),"sgm_mine_trap") ~= nil then
 v:enable_anomaly()
 end
 end
 end
 
 Терпение......
 И все получится!
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Вс, 17.05.2015, 22:14 | Сообщение # 637 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | makdm, 
 Спасибо за помощь. Функции, предложенные Вами, не сработали.
 
 Провел несколько экспериментов. Для начала попробовал включать и отключать мины через рестриктор. Функция и логика в моем предыдущем посту. Поставил на локации 21 мину. Попробовал отключить их оптом. Мины пропали. Совсем.
 Меня это озадачило. Стал выяснять, почему вчера работало, а сегодня нет. Выяснил опытным путем, что больше 2-х мин таким образом отключить нельзя.
 
 Решил заменить мины на обычные Электры. Возникла мысль сделать Электру с партиклом взрыва. Раз с минами ничего не выходит. Заменил в рестрикторе disable_mine на disable_anomaly. И получил жука. Оказалось, что аномалии нужен СТОРИ-ИД, чтобы отключиться. Добавил СТОРИ-ИД. Электры дружно отключились. Потом дружно включились.
 
 Вернул мины на место. Прописал им СТОРИ-ИД. В основе функции лежит команда disable_anomaly. Теперь мины отлично включаются и отключаются через рестриктор. Сбоев пока не видно.
 
 [cut=Функции]
 function enable_anomaly(actor, npc, p)
 if p[1] == nil then
 abort("Story id for enable_anomaly function is not set")
 end
 
 local obj = get_story_object(p[1])
 if not obj then
 abort("There is no object with story_id %s for enable_anomaly function", tostring(p[1]))
 end
 obj:enable_anomaly()
 end
 
 function disable_anomaly(actor, npc, p)
 if p[1] == nil then
 abort("Story id for disable_anomaly function is not set")
 end
 
 local obj = get_story_object(p[1])
 if not obj then
 abort("There is no object with story_id %s for disable_anomaly function", tostring(p[1]))
 end
 obj:disable_anomaly()
 end
 
 function disable_mine(actor, npc, p)
 --local mine = db.zone_by_name[p[1]]
 local mine = get_story_object(p[1])
 if mine == nil then
 return
 end
 mine:disable_anomaly()
 end
 
 function enable_mine(actor, npc, p)
 --local mine = db.zone_by_name[p[1]]
 local mine = get_story_object(p[1])
 if mine == nil then
 return
 end
 mine:enable_anomaly()
 end
 [/cut]
 
 Возникло несколько вопросов.
 
 1. Можно ли переделать функции отключения аномалий, чтобы они не требовали СТОРИ-ИД?
 2. Как отключить все мины разом через скрипт?
 
 [cut=Функция для сканера мин]
 
 function submodule_anomaly_control(object)
 if find_in_string(object:section(),"_mine_field") == false then return end
 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(),"_mine_field") and distance_between(object,db.actor)<=100
 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")
 end
 if find_in_string(object:section(),"_mine_field") and distance_between(object,db.actor)>100 then
 remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap)
 end
 --if check_seconds(3) and distance_between(object,db.actor)<=15 then remove_object_by_id(object:id()) end
 else
 if find_in_string(object:section(),"_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")
 end
 if find_in_string(object:section(),"_mine_field") and distance_between(object,db.actor)>50 then
 remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap)
 end
 --if check_seconds(6) and distance_between(object,db.actor)<=10 then remove_object_by_id(object:id()) end
 end
 else
 if find_in_string(object:section(),"_mine_field") then
 remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap)
 end
 end
 end[/cut]
 
 Можно ли вместо полного удаления мины из игры командой remove_object_by_id(object:id()) отключить её?
 После удаления игрока на 50 метров включить её? Как нужно переделать скрипт?
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| makdm | Дата: Пн, 18.05.2015, 00:41 | Сообщение # 638 |  |  Рожденный в СССР Разработчики Сообщений: 1294 | Цитата sergej5500 (  ) Функции, предложенные Вами, не сработали. Значит всё-таки я был прав, когда написал вам, что включить мины обратно не получится.
 Решение проблемы здесь
 
 http://sigerous.ru/forum/17-2820-1373937-16-1431774077
 
 Терпение......
 И все получится!
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Пн, 18.05.2015, 22:59 | Сообщение # 639 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | Добрый вечер. 
 В СГМ есть функция спавна аномалий.
 
 [cut=Функция]
 function create_anomaly(zone_name,zone_radius,lv,gv,init_data)
 local sobj=alife():create(zone_name,level.vertex_position(lv),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 cse_alife_object__unk1_f32=packet:r_float()
 local cse_alife_object__unk2_u32=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 cse_alife_object__unk3_u32=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 cse_alife_custom_zone__unk1_f32=packet:r_float()
 local cse_alife_custom_zone__unk2_u32=packet:r_s32()
 local on_off_mode_enabled_time=packet:r_s32()
 local on_off_mode_disabled_time=packet:r_s32()
 local on_off_mode_shift_time=packet:r_s32()
 local offline_interactive_radius=packet:r_float()
 local artefact_spawn_places_count=packet:r_u16()
 local cse_alife_anomalous_zone__unk1_u32=packet:r_s32()
 local last_spawn_time_present=packet:r_u8()
 packet:w_u16(game_vertex_id)
 packet:w_float(cse_alife_object__unk1_f32)
 packet:w_s32(cse_alife_object__unk2_u32)
 packet:w_s32(level_vertex_id)
 packet:w_s32(object_flags)
 if init_data~=nil then
 custom_data=init_data
 end
 packet:w_stringZ(custom_data)
 packet:w_s32(story_id)
 packet:w_s32(cse_alife_object__unk3_u32)
 packet:w_u8(1)
 packet:w_u8(0)
 local sphere_center=vector()
 sphere_center:set(0, 0, 0)
 packet:w_vec3(sphere_center)
 radius=zone_radius
 packet:w_float(radius)
 packet:w_u8(restrictor_type)
 packet:w_float(cse_alife_custom_zone__unk1_f32)
 cse_alife_custom_zone__unk2_u32=bit_not(0)
 packet:w_s32(cse_alife_custom_zone__unk2_u32)
 packet:w_s32(on_off_mode_enabled_time)
 packet:w_s32(on_off_mode_disabled_time)
 packet:w_s32(on_off_mode_shift_time)
 packet:w_float(offline_interactive_radius)
 packet:w_u16(artefact_spawn_places_count)
 packet:w_s32(cse_alife_anomalous_zone__unk1_u32)
 sobj:STATE_Read(packet, packet:w_tell()-packet:r_tell())
 return sobj
 end[/cut]
 
 Вызывается командой типа
 
 sgm_packet.create_anomaly("zone_mine_electric_weak",4,220659,1691)
 
 Электры спавнятся отлично. При попытке заспавнить мину zone_mine_field получаю жука.
 
 [cut=Лог]
 
 FATAL ERROR
 
 [error]Expression : assertion failed
 [error]Function : CCustomZone::CalcDistanceTo
 [error]File : D:\prog_repository\sources\trunk\xrGame\CustomZone.cpp
 [error]Line : 1469
 [error]Description : nearest_s
 
 
 stack trace:[/cut]
 
 Можно ли избавиться от вылета? Чем мина для этой функции хуже Электры?
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| makdm | Дата: Вт, 19.05.2015, 16:41 | Сообщение # 640 |  |  Рожденный в СССР Разработчики Сообщений: 1294 | Цитата sergej5500 (  ) При попытке заспавнить мину zone_mine_field получаю жука. Потому что функция написана по принципу: " Вроде как работает - ну и ладно".
 
 Правильная функция для спавна аномалий - сфер.
 
 [cut noguest=Функция спавна аномалий-сфер]function create_anomaly( zone_name, zone_radius, lv, gv )
 
 ----------------------------Создаём объект-аномалию
 
 local position = level.vertex_position( lv )
 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 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
 
 ------------------------------------------------Пишем в пакет
 
 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]
 
 Терпение......
 И все получится!
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |  |  |  | 
| makdm | Дата: Вс, 31.05.2015, 12:24 | Сообщение # 641 |  |  Рожденный в СССР Разработчики Сообщений: 1294 | Цитата sergej5500 (  ) Где я допустил ошибку? Переменную sobj нужно объявить, как локальную до выполнения оператора IF
 
 local sobj = nil
 
 if type(x) == "string" then
 local ptr = patrol(x)
 sobj = alife():create(zone_name,ptr:point(0),ptr:level_vertex_id(0),ptr:game_vertex_id(0))
 elseif z==nil and lv==nil and gv==nil then
 sobj = alife():create(zone_name,level.vertex_position(x),x,y)
 else
 sobj = alife():create(zone_name,vector():set(x,y,z),lv,gv)
 end
 
 Терпение......
 И все получится!
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Вс, 31.05.2015, 15:35 | Сообщение # 642 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | Добрый день. 
 Попробовал сделать рандомный спавн аномалий с помощью функции
 
 [cut=Функция]function esc_sgm_anomaly_zone_spawn()
 local section_table = {"sgm_zone_mine_electric_weak","sgm_zone_mine_gravitational_weak"}
 local point_table = {"esc_sgm_zone_mine_1","esc_sgm_zone_mine_2","esc_sgm_zone_mine_3","esc_sgm_zone_mine_4","esc_sgm_zone_mine_5"}
 for i = 1, #point_table do
 sgm_packet.create_anomaly(section_table[math.random(#section_table)],4,point_table[i])
 end
 end[/cut]
 
 В алл.спавн прописал 5 спавн-пойнтов. Функция работает. Аномалии рандомно спавнятся.
 
 Возник вопрос насчет таблицы point_table. 5 точек в неё вбить несложно. Если их будет 100, то строка будет длинной и в ней легко сделать ошибку. Можно ли переделать функцию, чтобы указать только первую и последнюю точки.
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  | 
| denis2000 | Дата: Вс, 31.05.2015, 16:57 | Сообщение # 643 |  |  Полевой исследователь Ученые сталкеры Сообщений: 2399 | Цитата sergej5500 (  ) Можно ... указать только первую и последнюю точки.Нет, ведь вам нужны все точки, не важно как они называются.
 Таблицу можно писать и не в одну строчку - с этим проблем нет.
 В крайнем случае возможно переделать скрипт так, чтобы названия точек брались и конфигурационного файла ltx.
 
 "Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
 (Чугунный всадник)
 
   |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |  |  |  | 
| makdm | Дата: Вс, 31.05.2015, 23:11 | Сообщение # 644 |  |  Рожденный в СССР Разработчики Сообщений: 1294 | sergej5500, при всём уважении, но не нужно изобретать велосипед. В моде Припять. Точка Отсчёта сделаны динамические аномалии, которых 500 штук на локации.
 С началом выброса эти аномалии рассасываются, а по окончании выброса появляются вновь на локации. Причём меняются не только сами аномалии, но и меняется их месторасположение.
 Никаких точек spawn_point при этом не нужно.
 Как это сделано, можете посмотреть в файле xrs_random_anomaly.script
 Функция control_random_anomaly
 
 Терпение......
 И все получится!
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |  |  |  | 
| sergej5500 | Дата: Вт, 02.06.2015, 00:10 | Сообщение # 645 |  |  Полевой Исследователь Ученые сталкеры Сообщений: 3793 | makdm, 
 Спасибо за помощь. Функцию адаптировал для своих нужд. Возник такой вопрос. В вашей функции проверка уяхвимости непися к аномалиеям осуществляется кодом:
 
 [cut=Код]					local can_hit_anomaly = true
 local st_npc = db.storage[ npc:id() ]
 local hit_anomaly = utils.cfg_get_string( st_npc.ini, st_npc.active_section, "hit_anomaly", npc, false, "", nil)
 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[/cut]
 
 Параметр прописывается в логике НПС. Можно ли этот параметр перенести в секцию сквада? И если непись относится к определенному скваду, у которого прописан параметр, то его не трогать.
 |  |  |  |   
  
 | Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |  |  |  |