Войти на сайт Регистрация Лента форума Пользователи Правила сайта Поиск по форуму
Модератор форума: 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 по ссылке из шапки и соседнюю тему "Курс молодого бойца",
возможно Ваш вопрос уже рассматривался.


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


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
denis2000Дата: Пн, 04.05.2015, 20:57 | Сообщение # 616
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Сахар, Варианты:
1. Объект в оффлайне
2. Неверно назначен стори_ид
3. Объект в принципе не подразумевает назначение стори_ид

Сахар, Вообще судя по всему вы принципиально делаете это не правильно, зачем function mine_boom(actor, npc, p) если уже есть function barrel_explode (actor , npc , p). Посмотрите ее применение!


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
СахарДата: Вт, 05.05.2015, 11:31 | Сообщение # 617
Гражданский
Пользователи
Сообщений: 2
Награды: 4
Репутация: [ 69 ]

Дело было в классе аномалий. Достаточно сделать так
Код
[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

При вызове функций нечего не происходит.


 
denis2000Дата: Вт, 05.05.2015, 12:11 | Сообщение # 618
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Сахар,
1. news_manager.send_tip уже имеет вывод звука.
2. sound = sound_object("device\\pda\\pda_news")
3. Как вызываете функцию?
4. Совершенно не уверен, что строка типа "device\\pda\\pda_news" будет передана на вход вашей функции!


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
СахарДата: Вт, 05.05.2015, 12:52 | Сообщение # 619
Гражданский
Пользователи
Сообщений: 2
Награды: 4
Репутация: [ 69 ]

Цитата denis2000 ()
Как вызываете функцию?

Через рескриптор
Код
%=crete_sms(new_level_map_spot_found)%


 
denis2000Дата: Вт, 05.05.2015, 15:00 | Сообщение # 620
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Сахар, Правильная функция:
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


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
СахарДата: Вс, 10.05.2015, 16:43 | Сообщение # 621
Гражданский
Пользователи
Сообщений: 2
Награды: 4
Репутация: [ 69 ]

Всем привет. Прочитал статью на ап-про под названием " Динамическое подключение/отключение функций." решил попробовать.
Код
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

Итог спавн бесконечен.


 
denis2000Дата: Пн, 11.05.2015, 09:48 | Сообщение # 622
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Сахар, Откуда функция start вызвана?

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
СахарДата: Пн, 11.05.2015, 10:31 | Сообщение # 623
Гражданский
Пользователи
Сообщений: 2
Награды: 4
Репутация: [ 69 ]

denis2000, Из bind_stalker.script

 
makdmДата: Чт, 14.05.2015, 09:50 | Сообщение # 624
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

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]


Терпение......
И все получится!
 
sergej5500Дата: Чт, 14.05.2015, 17:28 | Сообщение # 625
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

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

то кроме мин быстро зачищаются ближайшие аномалии.
 
makdmДата: Чт, 14.05.2015, 20:08 | Сообщение # 626
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

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


Терпение......
И все получится!
 
sergej5500Дата: Пт, 15.05.2015, 10:55 | Сообщение # 627
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

makdm,

Спасибо за помощь. Функция работает отлично. Встала следующая задача.

В СГМ есть опция "Обесточить мины-ловушки". В моем случае это аномалии.

[sgm_mine_trap]:zone_mine_field
$spawn = "zones\sgm_mine_trap"
max_start_power = 20.0

После получения инфопорции opt_deactivate_minetrap все мины должны быть отключены. После сброса инфопорции все мины должны быть включены. Выключиться и включиться они должны одновременно на всех локациях. Я пока не знаю, сколько мин будет в момент переключения опции. Сколько мин игрок успеет удалить. Это нельзя предсказать. Часть мин расставлю в алл.спавн. Есть идея доспавнивать мины через скрипт в процессе игры.

Можно ли сделать функцию, проверяющую все объекты в игре? Если у объекта секционное имя sgm_mine_trap, то применить к нему отключение (включение мины)?
 
makdmДата: Пт, 15.05.2015, 18:38 | Сообщение # 628
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

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
 
sergej5500Дата: Сб, 16.05.2015, 00:53 | Сообщение # 629
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

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]

После добавления Вашего кода мина отключается сразу. Спавнил на мине тестового кабана. При наличии Вашего кода и отключенной опции кабан спавнится с металлическим звуком (удар болта по железу) и идет гулять по локации. Если кода в функции нет, то сразу после спавна кабана следует детонация. Дальше - больше. Включил опцию. Маркер пропал. Новый кабан заспавнился без металлического звука. Отключил опцию. Маркер не появился. Можно сделать вывод, что аномалия (мина) пропала. При кидании болтов ничего не слышно.

Единственное отличие моих мин от мин из оригинала, то что они многоразовые. Как Электры. Это нужно, чтобы случайные кабаны не разминировали минные заграждения.
 
makdmДата: Сб, 16.05.2015, 14:01 | Сообщение # 630
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

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]


Терпение......
И все получится!
 
Форум » Моды для игр » Модостроение » Модостроение. Редактирование и создание скриптов
Поиск: