Модостроение. Редактирование и создание скриптов
|
|
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 | Дата: Пн, 04.05.2015, 20:57 | Сообщение # 616 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Сахар, Варианты: 1. Объект в оффлайне 2. Неверно назначен стори_ид 3. Объект в принципе не подразумевает назначение стори_ид
Сахар, Вообще судя по всему вы принципиально делаете это не правильно, зачем function mine_boom(actor, npc, p) если уже есть function barrel_explode (actor , npc , p). Посмотрите ее применение!
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
Сахар | Дата: Вт, 05.05.2015, 11:31 | Сообщение # 617 |
Гражданский
Пользователи
Сообщений: 2
| Дело было в классе аномалий. Достаточно сделать так Код [zone_mine_simulator]:zone_mine_field class = [i][b]ZS_MBALD[/b][/i] $spawn = "zones\caxap\zone_mine_simulator" Цитата denis2000 ( ) зачем function mine_boom(actor, npc, p) если уже есть function barrel_explode (actor , npc , p). А по чему бы нет? Я согласен что можно сделать Код %=barrel_explode(sid) =disable_anomaly(sid)% Но видь запустить всё одной функцией удобней.
Добавлено (05.05.2015, 11:31) --------------------------------------------- Попробовал написать ещё одну функцию. Код function crete_sms(actor, npc, p) local text = p[1] local icon = p[2] local period = p[3] local sound = sound_object(p[4]) if text == nil then text = "not_text_sms" end if period == nil then period = 5000 end if sound == nil then sound = "device\\pda\\pda_news" end news_manager.send_tip(db.actor,text,0,icon,period,nil) sound:play(db.actor,0,sound_object.s2d) end При вызове функций нечего не происходит.
|
|
|
Эти 0 пользователя(ей) поблагодарили Сахар за это полезное сообщение: |
|
|
denis2000 | Дата: Вт, 05.05.2015, 12:11 | Сообщение # 618 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Сахар, 1. news_manager.send_tip уже имеет вывод звука. 2. sound = sound_object("device\\pda\\pda_news") 3. Как вызываете функцию? 4. Совершенно не уверен, что строка типа "device\\pda\\pda_news" будет передана на вход вашей функции!
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
Сахар | Дата: Вт, 05.05.2015, 12:52 | Сообщение # 619 |
Гражданский
Пользователи
Сообщений: 2
| Цитата denis2000 ( ) Как вызываете функцию? Через рескриптор Код %=crete_sms(new_level_map_spot_found)%
|
|
|
Эти 0 пользователя(ей) поблагодарили Сахар за это полезное сообщение: |
|
|
denis2000 | Дата: Вт, 05.05.2015, 15:00 | Сообщение # 620 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Сахар, Правильная функция: xr_effects.script Код function crete_sms(actor, npc, p) local text = "not_text_sms" local icon = nil local period = 5000 local sound = "default" if p[1] then text = p[1] end if p[2] then icon = p[2] end
if p[3] and type(p[3]) == "number" then period = p[3] end if p[4] then sound = p[4] end news_manager.send_tip(db.actor,text,0,icon,period,nil,sound) end news_manager.script Код tips_sounds = { default = "pda_tips", alarm = "pda_alarm", news = "pda_news", task = "pda_task", }
function send_tip(actor, news_id, timeout, sender, showtime, sender_id, sound_id) if news_id == nil then return false end
-- printf("try to send tips for [%s]", tostring(sender_id)) if sender_id ~= nil then local sim = alife() if sim ~= nil then local npc = sim:object(get_story_object_id(sender_id)) if npc ~= nil then if npc.online then --в онлайне проверяем на раненность if xr_wounded.is_heavy_wounded_by_id(npc.id) then printf("[PDA]Cannot send tips [%s], sender is heavy wounded", tostring(news_id)) return false end end -- в других случаях только на смерть if npc:alive() == 1 then printf("[PDA]Cannot send tips [%s], sender is dead", tostring(news_id)) return false end end end end
if timeout == nil then timeout = 0 end if showtime == nil then showtime = 5000 end
local sound_theme = tips_sounds["default"] if sound_id and tips_sounds[sound_id] then sound_theme = tips_sounds[sound_id] end xr_sound.set_sound_play(actor:id(), sound_theme)
local texture = "ui_iconsTotal_grouping" if sender ~= nil then if type(sender) == "string" then if tips_icons[sender] then texture = tips_icons[sender] end elseif is_npc_stalker(sender:clsid()) then texture = sender:character_icon() end end local news_caption = game.translate_string("st_tip") local news_text = game.translate_string(news_id)
actor:give_game_news(news_caption, news_text, texture, timeout*1000, showtime, 0)
return true end
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
Сахар | Дата: Вс, 10.05.2015, 16:43 | Сообщение # 621 |
Гражданский
Пользователи
Сообщений: 2
| Всем привет. Прочитал статью на ап-про под названием " Динамическое подключение/отключение функций." решил попробовать. Код local rewards = { {"bandage", 6, "vodka", 4,}, {"medkit", 2, "vodka", 4,}, {"antirad", 3, "vodka", 4,}, {"helm_protective",}, {"drug_antidot", 2, "medkit_army", 2}, {"drug_antidot", 2, "medkit", 2}, }
function start() xr_s.register_callback("update", start, nil) --здесь записываем функцию в колбек local reward = rewards[math.random(#rewards)] for item = 1, #reward, 2 do alife():create(reward[item], db.actor:position(), 0, 0, db.actor:id()) xr_s.unregister_callback ("update", start) --здесь удаляем. end end Итог спавн бесконечен.
|
|
|
Эти 0 пользователя(ей) поблагодарили Сахар за это полезное сообщение: |
|
|
denis2000 | Дата: Пн, 11.05.2015, 09:48 | Сообщение # 622 |
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
| Сахар, Откуда функция start вызвана?
"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..." (Чугунный всадник)
|
|
|
Эти 0 пользователя(ей) поблагодарили denis2000 за это полезное сообщение: |
|
|
Сахар | Дата: Пн, 11.05.2015, 10:31 | Сообщение # 623 |
Гражданский
Пользователи
Сообщений: 2
| denis2000, Из bind_stalker.script
|
|
|
Эти 0 пользователя(ей) поблагодарили Сахар за это полезное сообщение: |
|
|
makdm | Дата: Чт, 14.05.2015, 09:50 | Сообщение # 624 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, вот это попробуй вставить вместо функции submodule_anomaly_control
[cut noguest=Переделанная функция]function submodule_anomaly_control(object)
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
if find_in_string(object:section(),"_mine_field") == nil and find_in_string(object:section(),"sgm_mine_trap") == nil 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 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 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 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 distance_between(object,db.actor)>50 then remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap) end if check_seconds(5) and distance_between(object,db.actor)<=10 then remove_object_by_id(object:id()) end end else
remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap)
end end[/cut]
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
sergej5500 | Дата: Чт, 14.05.2015, 17:28 | Сообщение # 625 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| makdm,
Спасибо за совет. Но предложенная функция результата не дала. Сигнал пищит все время. Мины удаляются вместе с прочими аномалиями.
Если я пишу код так:
if check_seconds(1) and find_in_string(object:section(),"_mine_field") and find_in_string(object:section(),"sgm_mine_trap") and distance_between(object,db.actor)<=15 then remove_object_by_id(object:id()) end
то функция не работает. Мины и аномалии остаются на местах.
Если пишу так:
if check_seconds(1) and find_in_string(object:section(),"_mine_field") ~= nil and find_in_string(object:section(),"sgm_mine_trap") ~= nil and distance_between(object,db.actor)<=15 then remove_object_by_id(object:id()) end
то кроме мин быстро зачищаются ближайшие аномалии.
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Чт, 14.05.2015, 20:08 | Сообщение # 626 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, дело в том, что у Николая функция find_in_string написана ...как бы это помягче сказать... неправильно. В LUA есть стандартная функция и зачем нужна была его самодеятельность - я не понял. Моя ошибка, что не проверил.
В функции, которую я вам написал вместо
if find_in_string(object:section(),"_mine_field") == nil and find_in_string(object:section(),"sgm_mine_trap") == nil then return end
Нужно написать
if find_in_string(object:section(),"_mine_field") == false and find_in_string(object:section(),"sgm_mine_trap") == false then return end
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
sergej5500 | Дата: Пт, 15.05.2015, 10:55 | Сообщение # 627 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| makdm,
Спасибо за помощь. Функция работает отлично. Встала следующая задача.
В СГМ есть опция "Обесточить мины-ловушки". В моем случае это аномалии.
[sgm_mine_trap]:zone_mine_field $spawn = "zones\sgm_mine_trap" max_start_power = 20.0
После получения инфопорции opt_deactivate_minetrap все мины должны быть отключены. После сброса инфопорции все мины должны быть включены. Выключиться и включиться они должны одновременно на всех локациях. Я пока не знаю, сколько мин будет в момент переключения опции. Сколько мин игрок успеет удалить. Это нельзя предсказать. Часть мин расставлю в алл.спавн. Есть идея доспавнивать мины через скрипт в процессе игры.
Можно ли сделать функцию, проверяющую все объекты в игре? Если у объекта секционное имя sgm_mine_trap, то применить к нему отключение (включение мины)?
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Пт, 15.05.2015, 18:38 | Сообщение # 628 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, в файле gamedata\scripts\bind_anomaly_field.script в методе UPDATE пишешь:
if string.find( self.object:section() , "sgm_mine_trap" ) ~= nil then if has_alife_info("opt_deactivate_minetrap") then self.object:disable_anomaly() else self.object:enable_anomaly() end end
Терпение...... И все получится!
Сообщение отредактировал makdm - Пт, 15.05.2015, 18:39 |
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
sergej5500 | Дата: Сб, 16.05.2015, 00:53 | Сообщение # 629 |
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
| makdm Попробовал Вашу функцию. Получил такие результаты. [cut=Функция установки меток мин на карту] function submodule_anomaly_control(object) if find_in_string(object:section(),"_mine_field") == false and find_in_string(object:section(),"sgm_mine_trap") == 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 dont_has_alife_info("opt_deactivate_minetrap") then if find_in_string(object:section(),"sgm_mine_trap") 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_minetrap_name") end end 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(),"sgm_mine_trap") and distance_between(object,db.actor)>100) or has_alife_info("opt_deactivate_minetrap") then remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap) 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 dont_has_alife_info("opt_deactivate_minetrap") then if find_in_string(object:section(),"sgm_mine_trap") 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_minetrap_name") end end 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(),"sgm_mine_trap") and distance_between(object,db.actor)>50) or has_alife_info("opt_deactivate_minetrap") then remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap) 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") or find_in_string(object:section(),"sgm_mine_trap") then remove_spot_on_map(object:id(),sgm_flags.spot_ground_trap) end end end[/cut]
Функция работает отлично. Маркер оперативно ставится и удаляется. При включении опции "обесточить мины" маркер удаляется. При отключении опции маркер восстанавливается. Можно сделать вывод, что функция не врет. При кидании болтов в мину слышны металлические удары.
[cut=Функция update] function anomaly_field_binder:update(delta) if string.find(self.object:section(),"sgm_mine_trap") ~= nil then if has_alife_info("opt_deactivate_minetrap") then self.object:disable_anomaly() else self.object:enable_anomaly() 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 [/cut]
После добавления Вашего кода мина отключается сразу. Спавнил на мине тестового кабана. При наличии Вашего кода и отключенной опции кабан спавнится с металлическим звуком (удар болта по железу) и идет гулять по локации. Если кода в функции нет, то сразу после спавна кабана следует детонация. Дальше - больше. Включил опцию. Маркер пропал. Новый кабан заспавнился без металлического звука. Отключил опцию. Маркер не появился. Можно сделать вывод, что аномалия (мина) пропала. При кидании болтов ничего не слышно.
Единственное отличие моих мин от мин из оригинала, то что они многоразовые. Как Электры. Это нужно, чтобы случайные кабаны не разминировали минные заграждения.
|
|
|
Эти 0 пользователя(ей) поблагодарили sergej5500 за это полезное сообщение: |
|
|
makdm | Дата: Сб, 16.05.2015, 14:01 | Сообщение # 630 |
Рожденный в СССР
Разработчики
Сообщений: 1294
| sergej5500, всё оказалось не так всё просто, как с обычными аномалиями. Дело в том, что если к мине-аномалии применить метод disable_anomaly(), то движок просто тупо удаляет ёё и включить снова мину-аномалию методом enable_anomaly() уже нельзя, так как объекта нет в игре - он удалён.
Предлагаю сделать включающиеся и отключающиеся мины, путём спавна их на локации и удаления с локации. После удаления мин и если понадобится снова включить опцию, то произвести повторный спавн всех аномалий. И так до бесконечности можно делать: спавнить-удалять. Можно делать скриптом путём перебора всех объектов игры, но я предлагаю сделать следующим образом, используя all.spawn.
[cut noguest=Много букв]Делать будем для трёх мин на локации. Затем по аналогии можешь делать хоть для 1000.
1. Сделаем так, чтобы мине-аномалии можно было присвоить метку story_id Для этого открываем файл gamedata\scripts\class_registrator.script Дописываем в него: cs_register(object_factory, "CMosquitoBald","se_zones.se_zone_mine_field","Z_MBALD","zone_mbald") Затем открываем( если нет - берёшь из ресурсов игры) файл gamedata\scripts\se_zones.script и в самый конец файла пишешь:
class "se_zone_mine_field" (cse_anomalous_zone) function se_zone_mine_field:__init (section) super (section) end
function se_zone_mine_field:on_register() cse_anomalous_zone.on_register(self) story_objects.check_spawn_ini_for_story_id(self) end
function se_zone_mine_field:on_unregister() unregister_story_object_by_id(self.id) cse_anomalous_zone.on_unregister( self ) end
Всё теперь мине-аномалии можно присвоить story_id
2. В all.spawn прописываем три мины и присваиваем метку секции с помощью spawn_story_id, а также story_id
[10020]
; cse_abstract properties section_name = zone_mine_field name = mine_1 position = -281.488617,-0.506008,-295.421783 direction = 0, 0, 0 version = 128 script_version = 12
; cse_alife_object properties game_vertex_id = 2325 distance = 11.1999998092651 level_vertex_id = 1144464 object_flags = 0xffffff3e custom_data = <<END [story_object] story_id = mine_1
END spawn_story_id = 1
; cse_shape properties shapes = shape0 shape0:type = sphere shape0:offset = 0,0,0 shape0:radius = 2
; cse_alife_space_restrictor properties restrictor_type = 3
; cse_alife_custom_zone properties max_power = 0
; cse_alife_anomalous_zone properties offline_interactive_radius = 30 artefact_spawn_count = 32 artefact_position_offset = 0xb200
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[10021]
; cse_abstract properties section_name = zone_mine_field name = mine_2 position = -281.488617,-0.506008,-295.421783 direction = 0, 0, 0 version = 128 script_version = 12
; cse_alife_object properties game_vertex_id = 2325 distance = 11.1999998092651 level_vertex_id = 1144464 object_flags = 0xffffff3e custom_data = <<END [story_object] story_id = mine_2
END spawn_story_id = 2
; cse_shape properties shapes = shape0 shape0:type = sphere shape0:offset = 0,0,0 shape0:radius = 2
; cse_alife_space_restrictor properties restrictor_type = 3
; cse_alife_custom_zone properties max_power = 0
; cse_alife_anomalous_zone properties offline_interactive_radius = 30 artefact_spawn_count = 32 artefact_position_offset = 0xb200
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[10022]
; cse_abstract properties section_name = zone_mine_field name = mine_3 position = -281.488617,-0.506008,-295.421783 direction = 0, 0, 0 version = 128 script_version = 12
; cse_alife_object properties game_vertex_id = 2325 distance = 11.1999998092651 level_vertex_id = 1144464 object_flags = 0xffffff3e custom_data = <<END [story_object] story_id = mine_3
END spawn_story_id = 3 ; cse_shape properties shapes = shape0 shape0:type = sphere shape0:offset = 0,0,0 shape0:radius = 2
; cse_alife_space_restrictor properties restrictor_type = 3
; cse_alife_custom_zone properties max_power = 0
; cse_alife_anomalous_zone properties offline_interactive_radius = 30 artefact_spawn_count = 32 artefact_position_offset = 0xb200
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3. Открываем( если нет - то берёшь из ресурсов игры) файл gamedata\configs\game_spawn_story_ids.ltx В него ниже секции [spawn_story_ids] пишем mine_1 = 1 mine_2 = 2 mine_3 = 3 Это метки наших секций в all.spawn. Я их специально обозвал также, как и story_id, чтобы потом не путаться.
4. На локации ставишь рестриктор, который будет в зависимости от включенной/выключенной опций либо спавнить либо удалять аномалии. Пишешь ему такую логику. [logic] active = sr_idle@wait
[sr_idle@wait] on_info = {+opt_deactivate_minetrap} sr_idle@remove %=remove_zone_mine_fields( mine_1:mine_2:mine_3 )%
[sr_idle@remove] on_info = {-opt_deactivate_minetrap} sr_idle@wait %=spawn_zone_mine_fields( mine_1:mine_2:mine_3 )%
4. Теперь в файл xr_effects.script добавляем функции на удаление мин-аномалии и на спавн мин-аномалий. function spawn_zone_mine_fields( actor, obj, p ) if p then local ini = ini_file( "game_spawn_story_ids.ltx" ) for k,v in pairs( p ) do local spawn_story = ini:r_string( "spawn_story_ids" , v ) local section_number = alife():spawn_id( tonumber( spawn_story ) ) alife():create( section_number ) end end end
function remove_zone_mine_fields( actor, obj, p ) if p then for k,v in pairs( p ) do local story_obj_id = get_story_object_id( v ) if story_obj_id then local se_obj = alife():object( story_obj_id ) if se_obj then remove_spot_on_map(story_obj_id,sgm_flags.spot_ground_trap) alife():release( se_obj, true ) end end end end end
В принципе всё. Можешь пробовать.[/cut]
Терпение...... И все получится!
|
|
|
Эти 0 пользователя(ей) поблагодарили makdm за это полезное сообщение: |
|
|
|