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


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


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
makdmДата: Пт, 13.03.2015, 23:32 | Сообщение # 586
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

sergej5500,
перед строкой

if type(x) == "string" then

напиши

local base_treasure = nil

затем вместо

secret_case = alife():create(model,ptr:point(0),ptr:level_vertex_id(0),ptr:game_vertex_id(0))

напиши

base_treasure = alife():create(model,ptr:point(0),ptr:level_vertex_id(0),ptr:game_vertex_id(0))


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


Сообщение отредактировал makdm - Пт, 13.03.2015, 23:32
 
shram_437Дата: Сб, 14.03.2015, 19:51 | Сообщение # 587
Сталкер
Вольные сталкеры
Сообщений: 215
Награды: 3
Репутация: [ 25 ]

Доброго вечера, товарищи мододелы! Уже давненько мечтаю сделать горячую клавишу для функции "забрать всё из инвентаря" в Тенях Чернобыля наподобие Clear sky и Зов припяти. Перечитал уже много информации на Амк форуме, но вот подходящей для себя не нашёл. Можете подсказать какие файлы отвечают за инвентарь и можно ли назначить выполнение скрипта в окне обыска ящика/трупа на кнопку? Битый час сидел все подряд файлы скриптов пересматривал(((

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

Цитата shram_437 ()
Битый час сидел все подряд файлы скриптов пересматривал

И зря, исходники движка надо было пересматривать.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
shram_437Дата: Сб, 14.03.2015, 21:08 | Сообщение # 589
Сталкер
Вольные сталкеры
Сообщений: 215
Награды: 3
Репутация: [ 25 ]

denis2000, досадно sad , но спасибо что пояснили.

 
sergej5500Дата: Сб, 14.03.2015, 21:12 | Сообщение # 590
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

Добрый вечер.

В СГМ есть функция спавна сквада по координатам.

[cut=_g]-- 'Создание отряда(сквада).
function create_force(squad_sect,x,y,z,lv,gv)
if y~=nil then
local board=sim_board.get_sim_board()
local squad=board:create_force(squad_sect,x,y,z,lv,gv)
for k in squad:squad_members() do
board:setup_squad_and_group(k.object)
end
squad:update()
else
local board=sim_board.get_sim_board()
local smart=board.smarts_by_names[x]
local squad=board:create_squad(smart,squad_sect)
board:enter_smart(squad,smart.id)
for k in squad:squad_members() do
board:setup_squad_and_group(k.object)
end
squad:update()
end
end[/cut]

[cut=sim_board]
--' Создание нового отряда
function sim_board:create_force(sq_id,x,y,z,lv,gv)
printf("create squad called")
local squad_id = tostring(sq_id)
local squad = alife():create(squad_id,vector():set(x,y,z),lv,gv)
squad:create_member(x,y,z,lv,gv)
squad:set_squad_relation()
sgm_callbacks.on_squad_create(squad_id,squad.id)
for k in squad:squad_members() do
local obj = k.object
squad.board:setup_squad_and_group(obj)
end
return squad
end[/cut]

Функция очень удобна. Позволяет спавнить сквады в произвольной точке. Попробовал сделать аналогичную по смыслу функцию для спавна по спавн-пойнту.

[cut=_g]function create_skvad(squad_sect,spot_name,spot_descr)
local sp_name = spot_name
local sp_descr = spot_descr
if type(x) == "string" then
if level.patrol_path_exists(x) then
local ptr = patrol(x)
local board=sim_board.get_sim_board()
local squad=board:create_skvad(squad_sect,spot_name,spot_descr)
sp_name = y
sp_descr = z
for k in squad:squad_members() do
board:setup_squad_and_group(k.object)
end
squad:update()
else
local board=sim_board.get_sim_board()
local smart=board.smarts_by_names[x]
local squad=board:create_squad(smart,squad_sect)
board:enter_smart(squad,smart.id)
for k in squad:squad_members() do
board:setup_squad_and_group(k.object)
end
squad:update()
end
end
end[/cut]

[cut=sim_board]function sim_board:create_skvad(squad_sect,spot_name,spot_descr)
printf("create squad called")
local sp_name = spot_name
local sp_descr = spot_descr
local squad_id = tostring(sq_id)
local ptr = patrol(x)
local squad = alife():create(squad_id,ptr:point(0),ptr:level_vertex_id(0),ptr:game_vertex_id(0))
sp_name = y
sp_descr = z
squad:create_member(ptr:point(0),ptr:level_vertex_id(0),ptr:game_vertex_id(0))
squad:set_squad_relation()
sgm_callbacks.on_squad_create(squad_id,squad.id)
for k in squad:squad_members() do
local obj = k.object
squad.board:setup_squad_and_group(obj)
end
return squad
end[/cut]

Вылетов при активации функции нет. Спавна тоже нет. Функция просто не работает. Где я допустил ошибку?
 
denis2000Дата: Сб, 14.03.2015, 21:19 | Сообщение # 591
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

shram_437, Хотя чисто теоретически можно сделать скриптовое перемещение всех объектов инвентаря, обрабатывая событие on_use функция motivator_binder:use_callback в скрипте xr_motivator.script. Но тут придется все самому делать, от рисования окна до обработки нажатий кнопки.

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
makdmДата: Вс, 15.03.2015, 10:36 | Сообщение # 592
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

sergej5500, в первой функции

Цитата sergej5500 ()
if type(x) == "string" then
if level.patrol_path_exists(x) then
local ptr = patrol(x)


и во второй функции

Цитата sergej5500 ()
local ptr = patrol(x)


А какое значение присвоено X ?
У тебя x = nil
Поэтому и спавна нет.


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

makdm,

Спасибо за помощь. Возникла такая мысль.

[cut=Функция]
-- 'Создание отряда(сквада).
function create_force(squad_sect,x,y,z,lv,gv)
if y~=nil then
local board=sim_board.get_sim_board()
local squad=board:create_force(squad_sect,x,y,z,lv,gv)
for k in squad:squad_members() do
board:setup_squad_and_group(k.object)
end
squad:update()
else
local board=sim_board.get_sim_board()
local smart=board.smarts_by_names[x]
local squad=board:create_squad(smart,squad_sect)
board:enter_smart(squad,smart.id)
for k in squad:squad_members() do
board:setup_squad_and_group(k.object)
end
squad:update()
end
end[/cut]

Её можно применить в двух вариантах.

--create_force("army_sim_squad_novice",-154.44709777832,-29.441591262817,-380.06079101563,96937,1708)
create_force("army_sim_squad_novice","esc_smart_terrain_1")


В первом варианте сквад появляется в нужной точке. Во втором варианте - на нужном смарте.

Нужно добавить третий вариант. Спавнить по спавн-пойнту. Если задан спавн-пойнт, то нужно получить от него численные значения X,Y,Z,левел-вертекс,гейм-вертекс. Использовать полученные значения для спавна по первому варианту. Свести задачу к уже решенной.
 
makdmДата: Вс, 15.03.2015, 14:49 | Сообщение # 594
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

Цитата sergej5500 ()
Нужно добавить третий вариант.

Зачем городить огород.
Проще написать отдельную функцию для спавна по вей-поинтам
Пропиши эту функцию в _g.script и вызывай, когда тебе нужно провести спавн.
Например назовём эту функцию create_on_path

Код
function create_on_path(  squad_sect, path, index )
       local ptr = patrol( path )
       local ind = index or 0
       local position = ptr:point( ind )
       local board = sim_board.get_sim_board()
       local squad = board:create_force( squad_sect, position.x, position.y, position.z, ptr:level_vertex_id( ind ), ptr:game_vertex_id( ind ) )
       squad:update()
end


Вызов функции create_on_path( секция_сквада, вей-поинт, точка спавна )
Если точку спавна не указывать, то спавн будет на нулевой точке пути.

P.SСкрипт исправил ( ошибка закралась)


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


Сообщение отредактировал makdm - Вс, 15.03.2015, 15:03
 
shram_437Дата: Сб, 21.03.2015, 22:23 | Сообщение # 595
Сталкер
Вольные сталкеры
Сообщений: 215
Награды: 3
Репутация: [ 25 ]

Доброго времени суток, товарищи. Можете объяснить как правильно добавить в статиску новое оружие(это я про раздел любимое оружие в пда)? В файл xr_statistic.script в таблицу оружия я новое дописал, но почему-то вместо нормальных иконок из ui_actor_weapons отображаются совершенно не те.

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

Цитата shram_437 ()
но почему-то вместо нормальных иконок из ui_actor_weapons отображаются совершенно не те.

Исправьте upgr_icon_x, upgr_icon_y, upgr_icon_width, upgr_icon_height в конфиге оружия.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
shram_437Дата: Пн, 23.03.2015, 02:00 | Сообщение # 597
Сталкер
Вольные сталкеры
Сообщений: 215
Награды: 3
Репутация: [ 25 ]

denis2000, проблема вроде уменьшилась: неправильные иконки отображаются только у уникального оружия содержащего в названии имена секций стандартного оружия (например: fn2000_nimble). Не могли бы Вы объяснить: в таблице с оружием в файле xr_statistic название оружия - это кусок названия секции оружия (например из такой секции [wpn_fn2000] берется только fn2000 = 0,)?

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

Цитата shram_437 ()
Не могли бы Вы объяснить: в таблице с оружием в файле xr_statistic название оружия - это кусок названия секции оружия

Да именно так, смотрите внимательнее функцию:
Код
function set_best_weapon(hit_amount)
  local active_item = db.actor:active_item()
  if(active_item) then
   local s_obj = alife():object(active_item:id())
   if(s_obj) then
    local s = s_obj:section_name()
    for w in string.gfind(s, "%w+") do
     if(weapons_table[w]~=nil) then
      weapons_table[w] = weapons_table[w] + hit_amount
     end
    end
   end
   local amount = 0
   for k,v in pairs(weapons_table) do
    if(v>amount) then
     amount = v
     if(k=="rgd5" or k=="f1") then
      actor_statistic.favorite_weapon_sect = "grenade_"..k
     else
      actor_statistic.favorite_weapon_sect = "wpn_"..k
     end
     if(k=="desert") then
      actor_statistic.favorite_weapon_sect = "wpn_desert_eagle"
     elseif(k=="rg") then
      actor_statistic.favorite_weapon_sect = "wpn_rg-6"
     end
    end
   end
  end
end


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

Добрый день.

Имеются две функции в xr_condition. Измеряют расстояния от актора до точек в way_***
[cut=Функции]
function distance_from_actor_to_point_ge(actor, npc, p)
local patrol_way = patrol(p[2])
local point_id = 0
if p[3] then
point_id = tonumber(p[3])
end
if actor then
return actor():distance_to_sqr(patrol_way:point(point_id)) >= p[1]*p[1]
end
return false
end

function distance_from_actor_to_point_le(actor, npc, p)
local patrol_way = patrol(p[2])
local point_id = 0
if p[3] then
point_id = tonumber(p[3])
end
if actor then
return actor():distance_to_sqr(patrol_way:point(point_id)) < p[1]*p[1]
end
return false
end[/cut]

[cut=Рестриктор]

[sr_idle@task1]
on_info = {=distance_to_smart_ge(zat_stalker_base_smart:330)} sr_idle@task2 %=zat_b103_lost_merc_curjer_info_sms_1%
on_info2 = {+zat_b103_merc_fight} sr_idle@end
on_info3 = {+zat_b103_merc_storyline_done} sr_idle@end

[sr_idle@task2]
on_info = {=distance_from_actor_to_point_le(zat_b103_lost_merc_curjer_1_rukzak_1:150)} sr_idle@task3 %=zat_b103_lost_merc_curjer_1_squad_spawn%
on_info2 = {=distance_from_actor_to_point_le(zat_b103_lost_merc_curjer_1_rukzak_2:150)} sr_idle@task3 %=zat_b103_lost_merc_curjer_1_squad_spawn%
on_info3 = {=distance_from_actor_to_point_le(zat_b103_lost_merc_curjer_1_rukzak_3:150)} sr_idle@task3 %=zat_b103_lost_merc_curjer_1_squad_spawn%
on_info4 = {+zat_b103_merc_fight} sr_idle@end %=zat_b103_lost_merc_curjer_quests_delete1%
on_info5 = {+zat_b103_merc_storyline_done} sr_idle@end %=zat_b103_lost_merc_curjer_quests_delete1%

[sr_idle@task3]
on_info = {=actor_has_item(zat_b103_lost_merc_curjer_1_pda)} sr_idle@task4 %+zat_b103_lost_merc_curjer_1%
on_info2 = {+zat_b103_merc_fight} sr_idle@end %=zat_b103_lost_merc_curjer_quests_delete1%
on_info3 = {+zat_b103_merc_storyline_done} sr_idle@end %=zat_b103_lost_merc_curjer_quests_delete1%[/cut]

При удалении от смарта Скадовска приходит СМС и спавнятся квестовые объекты. Но на вторую секцию рестриктор принципиально не переходит. Если после прихода СМС сделать сейв и загрузиться с него, то придет 2-я СМС и отреспится 2-й комплект квестовых предметов.

Вопрос: рабочие ли функции?
 
makdmДата: Пн, 30.03.2015, 16:21 | Сообщение # 600
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

Цитата sergej5500 ()
рабочие ли функции?

Функции не рабочие.
Измеряться должен квадрат расстояния между точками на карте.
А в вашем случае это не происходит.

Вместо

actor():distance_to_sqr(patrol_way:point(point_id)) >= p[1]*p[1]

пишем

actor:position():distance_to_sqr(patrol_way:point(point_id)) >= p[1]*p[1]

Аналогично во второй функции.

Кроме того у вас перепутаны аргументы.

Там где указано p[2] нужно указать p[1], и наоборот, там где p[1] указать p[2]


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


Сообщение отредактировал makdm - Пн, 30.03.2015, 16:24
 
Поиск: