Войти на сайт Регистрация Лента форума Пользователи Правила сайта Поиск по форуму
Модератор форума: 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Дата: Вт, 02.06.2015, 08:29 | Сообщение # 646
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата sergej5500 ()
Можно ли этот параметр перенести в секцию сквада?

ЗАЧЕМ!? Просто НПС получает по умолчанию хит даже если этой строки в его логике нет или даже самой логики нет: local can_hit_anomaly = true


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

Цитата denis2000 ()
ЗАЧЕМ!?


Нужно параметр, запрещающий нанесение хита неписю, прописать в секции сквада. Если он прописан в логике, то он не действует, пока неписи не заняли работы в смарте.

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

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


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

Добрый день.

В аддоне Припять - Точка Отсчета (приквел к Время Альянса) есть функция рандомного спавна аномалий. Возникла идея сделать рандомный спавн артефактов. После выброса спавнит арты. Штук 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]

При тестовом запуске функции обнаружил, что она убирает артефакты, спавнящиеся в аномальных зонах оригинальной игры.

Можно ли исправить функцию, чтобы она не трогала артефакты в аномальных зонах.
 
makdmДата: Сб, 06.06.2015, 13:59 | Сообщение # 650
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

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


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

Всем добрый день.

Попробовал сделать в оригинальном Зове Припяти закладываемые рюкзаки, как в СГМ. Хочу использовать минимум функций из СГМ.

[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 метров. Рюкзак исчез. На его месте заспавнилась Электра. Функция спавна аномалии должна вызываться из логики рюкзака. И спавнить аномалию в точке нахождения рюкзака.
 
makdmДата: Вс, 14.06.2015, 11:21 | Сообщение # 652
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

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

Добрый день.

Попробовал сделать в чистом ЗП бустер для телепортации игрока. Как в СГМ 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=Логи]
Цитата
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:
[/cut]

В каком месте допущена ошибка?


Сообщение отредактировал sergej5500 - Чт, 18.06.2015, 16:55
 
denis2000Дата: Чт, 18.06.2015, 21:45 | Сообщение # 654
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

sergej5500, Первый XML естественно верный. А вот по скрипту вопрос: Класс объявляете ui_esc_gps_navigator, а методы написаны для esc_gps_navigator.

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

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

В аддоне Время Альянса нашел функцию рандомного спавна предметов в инвентарные ящики на локации.

[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]

Как усовершенствовать эту функцию? Нужно, чтобы спавн происходил только в пустой ящик. То есть, если в ящике что-то есть, то спавн в него проходить не должен.
 
makdmДата: Ср, 24.06.2015, 00:51 | Сообщение # 656
Рожденный в СССР
Разработчики
Сообщений: 1294
Награды: 29
Репутация: [ 1909 ]

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
 
avn1975Дата: Пн, 20.07.2015, 20:53 | Сообщение # 657
Гражданский
Пользователи
Сообщений: 15
Награды: 0
Репутация: [ 0 ]

как сделать выброс через реститор

Сообщение отредактировал avn1975 - Сб, 25.07.2015, 23:18
 
sergej5500Дата: Пн, 27.07.2015, 22:46 | Сообщение # 658
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

avn1975,

Для запуска выброса есть функция

function start_surge(actor, npc, p)
surge_manager.start_surge(p)
end

Вызвать её можно так:

on_info = {Условие} %=start_surge%
 
avn1975Дата: Пт, 31.07.2015, 16:19 | Сообщение # 659
Гражданский
Пользователи
Сообщений: 15
Награды: 0
Репутация: [ 0 ]

как зделать при старте нпс побежали пример скрипта https://yadi.sk/d/UglbUgs2iCWrZ
 
sergej5500Дата: Сб, 22.08.2015, 00:08 | Сообщение # 660
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

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

Функция для спавна аномалий по координатам.

[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-сетке? Корректировала высоту?
 
Поиск: