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

Цитата men_stalker ()
Здравствуйте, есть функция function pda:InitControls()

Да потому, что это ни разу не функция. Это метод InitControls() для объекта pda, заявленного экземпляра класса такого-то.
Поэтому перед выполнением какого либо метода, требуется этот объект предварительно определить (подсмотрите как это делается например для treasure_manager)


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
men_stalkerДата: Вс, 01.01.2017, 16:03 | Сообщение # 872
Инженер «Свободы»
Свобода
Сообщений: 184
Награды: 5
Репутация: [ 40 ]

denis2000, вы про это?
[cut=treasure_manager.script]
Код
local treasure_manager = nil
class "CTreasureManager"
function CTreasureManager:__init()
    self.items_spawned = false
    self.check_time = nil
    self.secrets = {}
  self.secret_restrs = {}
  self.items_from_secrets = {}
end

function CTreasureManager:initialize()
    local ini = ini_file("misc\\secrets.ltx")
    local n = ini:line_count("list")
    for i=0,n-1 do
  local result, id, value    = ini:r_line("list",i,"","")
  if(ini:section_exist(id)) then
   self.secrets[id] = {items = {}, given = false, empty = nil, refreshing = false, checked = false, to_find = 0}
     local items_count = ini:line_count(id)
     local item_section = ""
     for i=0,items_count-1 do
       result, item_section, str = ini:r_line(id,i,"","")
    if(item_section=="empty") then
         local parsed_condlist = xr_logic.parse_condlist(nil, "treasure_manager", "empty_cond", str)
     self.secrets[id].empty = parsed_condlist
    elseif(item_section=="refreshing") then
         local parsed_condlist = xr_logic.parse_condlist(nil, "treasure_manager", "refreshing_cond", str)
     self.secrets[id].refreshing = parsed_condlist
    else
         self.secrets[id].items[item_section] = {}
         local tbl = utils.parse_spawns(str)
         if(#tbl==0) then
                    abort("There is no items count set for treasure [%s], item [%s]", id, item_section)
         end
     for i=1,#tbl do
      local tbl = {count = tonumber(tbl[i].section), prob = tonumber(tbl[i].prob or 1)}
      table.insert(self.secrets[id].items[item_section], tbl)
     end
    end
   end
  else
   abort("There is no section [%s] in secrets.ltx", tostring(id))
  end
    end
end

function CTreasureManager:fill(se_obj, treasure_id)
    if(self.secrets[treasure_id]) then
    local item = self.secrets[treasure_id].items[se_obj:section_name()]
  if(item) then
   for i=1,#item do
       if not(item[i].item_ids) then
         item[i].item_ids = {}
       end
       local count = #item[i].item_ids
    if(count<item[i].count) then
         item[i].item_ids[count+1] = se_obj.id
     return true
    end
   end
  else
   abort("Attempt to register unknown item [%s] in secret [%s]", se_obj:section_name(), treasure_id)
  end
    else
  abort("Attempt to register item [%s] in unexistent secret [%s]", se_obj:name(), treasure_id)
    end
end

function CTreasureManager:register_item(se_obj)
    local spawn_ini = se_obj:spawn_ini()
    if(spawn_ini:section_exist("secret")) then
  local result, id, value
  result, id, value    = spawn_ini:r_line("secret",0,"","")
  if id ~= "name" then
   abort("There is no 'name' field in [secret] section for object [%s]", se_obj:name())
  end
  if value == "" then
   abort("Field 'name' in [secret] section got no value for object [%s]", se_obj:name())
  end
  return self:fill(se_obj, value)
    end
end

function CTreasureManager:register_restrictor(se_obj)
    local spawn_ini = se_obj:spawn_ini()
    if(spawn_ini:section_exist("secret")) then
  self.secret_restrs[se_obj:name()] = se_obj.id
    end
end

function CTreasureManager:update()
    if not(self.items_spawned) then
   for k,v in pairs(self.secrets) do
     self:spawn_treasure(k)
   end
  self.items_spawned = true
    end
    local global_time = time_global()
    if(self.check_time and global_time-self.check_time<=500) then
  return
    end
    self.check_time = global_time

  for k,v in pairs(self.secrets) do
    if(v.given) then
    if(v.empty) then
       local sect = xr_logic.pick_section_from_condlist(db.actor, nil, v.empty)
       if(sect=="true") and not v.checked then
         level.map_remove_object_spot(self.secret_restrs[k], "treasure")
         xr_statistic.inc_founded_secrets_counter()
         v.empty = nil
     v.checked = true
         printf("Empty secret [%s] remove map spot!", k)
       end
   elseif(v.refreshing and v.checked) then
       local sect = xr_logic.pick_section_from_condlist(db.actor, nil, v.refreshing)
       if(sect=="true") then
         v.given = false
         v.checked = false
         printf("Given secret [%s] now is avaliable!", k)
       end
   end
    end
  end
end

function CTreasureManager:spawn_treasure(treasure_id)
    if not(self.secrets[treasure_id]) then
  abort("There is no stored secret [%s]", tostring(treasure_id))
    end
    if(self.secrets[treasure_id].given) then
  printf("Secret [%s] already given!", treasure_id)
  return
    end
    for item_section,item_params in pairs(self.secrets[treasure_id].items) do
  for num = 1,#item_params do
     for i = 1,item_params[num].count do
       local prob = math.random()
       if(prob<item_params[num].prob) then
     if(item_params[num].item_ids and item_params[num].item_ids[i]) then
                    local se_obj = alife():object(item_params[num].item_ids[i])
                    local obj = alife():create( item_section,
                    se_obj.position,
                    se_obj.m_level_vertex_id,
                    se_obj.m_game_vertex_id)
                    obj.angle = se_obj.angle
                    obj:use_ai_locations(se_obj:used_ai_locations())
                    self.items_from_secrets[obj.id] = self.secret_restrs[treasure_id]
                    self.secrets[treasure_id].to_find = self.secrets[treasure_id].to_find + 1
     else
--[[
      log("----------->error id="..treasure_id)
      print_table(self.secrets[treasure_id])
      log("----------->item_section="..tostring(item_section))
      log("----------->num="..tostring(num))
      log("----------->i="..tostring(i))
      log("----------->prob="..tostring(prob))
]]
     end
       end
     end
  end
    end
end

function CTreasureManager:give_treasure(treasure_id, spawn)
    if not(self.secrets[treasure_id]) then
  abort("There is no stored secret [%s]", tostring(treasure_id))
    end
    if(self.secrets[treasure_id].given) then
  printf("Secret [%s] already given!", treasure_id)
  return
    end
    if(self.secrets[treasure_id].to_find==0 and not(self.secrets[treasure_id].empty)) then
  news_manager.send_treasure(2)
  printf("Secret [%s] already empty", treasure_id)
  return
    end
    if(spawn) then
  self:spawn_treasure(treasure_id)
    end
    level.map_add_object_spot_ser(self.secret_restrs[treasure_id], "treasure", "")
    self.secrets[treasure_id].given = true
    news_manager.send_treasure(0)
    printf("Give secret [%s]", treasure_id)
end

function CTreasureManager:give_random()
    local rnd_tbl = {}
    for k,v in pairs(self.secrets) do
    if not(v.given) then
   table.insert(rnd_tbl, k)
    end
    end
    if(#rnd_tbl~=0) then
   self:give_treasure(rnd_tbl[math.random(1,#rnd_tbl)])
  return
    end
    printf("There are no treasures avaliable!")
end

function CTreasureManager:on_item_take(obj_id)
    local restr_id = self.items_from_secrets[obj_id]
    local treasure_id = nil
    for k,v in pairs(self.secret_restrs) do
  if(restr_id==v) then
   treasure_id = k
  end
    end
    if(treasure_id) then
    self.secrets[treasure_id].to_find = self.secrets[treasure_id].to_find - 1
  if(self.secrets[treasure_id].to_find==0) then
   level.map_remove_object_spot(self.secret_restrs[treasure_id], "treasure")
   xr_statistic.inc_founded_secrets_counter()
   printf("Secret [%s] now is empty!", treasure_id)
   self.secrets[treasure_id].checked = true
   news_manager.send_treasure(1)
  end
  self.items_from_secrets[obj_id] = nil
    end
end

function CTreasureManager:save(package)
    set_save_marker(package, "save", false, "CTreasureManager")
    package:w_bool(self.items_spawned)
    local num = 0
    for k,v in pairs(self.items_from_secrets) do
  num = num + 1
    end
    package:w_u16(num)
    for k,v in pairs(self.items_from_secrets) do
  package:w_u16(k)
  package:w_u16(v)
    end

    num = 0
    for k,v in pairs(self.secrets) do
  num = num + 1
    end
    package:w_u16(num)
    for k,v in pairs(self.secrets) do
  if not(self.secret_restrs[k]) then
   package:w_u16(-1)
  else
   package:w_u16(self.secret_restrs[k])
  end
  package:w_bool(v.given)
  package:w_bool(v.checked)
  package:w_u8(v.to_find)
    end
    set_save_marker(package, "save", true, "CTreasureManager")
end

function CTreasureManager:load(package)
    set_save_marker(package, "load", false, "CTreasureManager")
    self.items_spawned = package:r_bool()
    self.items_from_secrets = {}
    local num = package:r_u16()
    for i=1,num do
  local k = package:r_u16()
  local v = package:r_u16()
  self.items_from_secrets[k] = v
    end

    local num = package:r_u16()
    for i=1,num do
  local id = package:r_u16()
  for k,v in pairs(self.secret_restrs) do
   if(v==id) then
    id = k
    break
   end
  end
  local given = package:r_bool()
  local checked = package:r_bool()
  local to_find = package:r_u8()
  if(id~=65535 and self.secrets[id]) then
   self.secrets[id].given = given
   self.secrets[id].checked = checked
   self.secrets[id].to_find = to_find
  end
    end
  set_save_marker(package, "load", true, "CTreasureManager")
end
--------------------------------------------------------------------------------
function get_treasure_manager()
    if(treasure_manager==nil) then
  treasure_manager = CTreasureManager()
  treasure_manager:initialize()
    end
    return treasure_manager
end

[/cut]
Простите, но процесс определения объекта я здесь не нашёл.


Сообщение отредактировал men_stalker - Вс, 01.01.2017, 16:04
 
denis2000Дата: Пн, 02.01.2017, 10:22 | Сообщение # 873
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

men_stalker, А это что: function get_treasure_manager() ?

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

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

С помощью функции типа

xr_effects.inc_faction_goodwill_to_actor(db.actor, nil, {"dolg", 200})

можно улучшить отношении фракции к ГГ на 200 единиц.

Какой функцией можно воспользоваться, чтобы выставить строго определенное отношение фракции к ГГ? Например, 1000 единиц. В xr_effects подходящей не увидел.
 
denis2000Дата: Чт, 04.05.2017, 21:52 | Сообщение # 875
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

sergej5500, relation_registry.set_community_goodwill("dolg", db.actor:id(), 1000)

"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)


Сообщение отредактировал denis2000 - Чт, 04.05.2017, 21:53
 
sergej5500Дата: Вс, 28.05.2017, 22:00 | Сообщение # 876
Полевой Исследователь
Ученые сталкеры
Сообщений: 3793
Награды: 29
Репутация: [ 1355 ]

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

Имеется функция для спавна аномалии.

[cut=_g.scripts]

-- 'Спавн аномалии.
function create_anomaly_1(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
offline_interactive_radius = 30
artefact_spawn_count = 32
packet:w_begin(0)
packet:w_u16(game_vertex_id)
packet:w_float(distance)
packet:w_s32(direct_control)
packet:w_s32(level_vertex_id)
packet:w_s32(object_flags)
packet:w_stringZ(custom_data)
packet:w_s32(story_id)
packet:w_s32(spawn_story_id)
packet:w_u8(1)
packet:w_u8(0)
packet:w_vec3(new_center)
packet:w_float(zone_radius)
packet:w_u8(restrictor_type)
packet:w_float(max_power)
packet:w_s32(owner_id)
packet:w_u32(enabled_time)
packet:w_u32(disabled_time)
packet:w_u32(start_time_shift)
packet:w_float(offline_interactive_radius)
packet:w_u16(artefact_spawn_count)
packet:w_s32(artefact_position_offset)
packet:r_seek(2)
sobj:STATE_Read(packet,packet:w_tell())
return sobj
end[/cut]

В заданной точке аномалия спавнится отлично.

Скрипт типа

create_anomaly_1("zone_mine_electric_weak",4,-2.5531272888184,-7.0012526512146,549.51348876953,db.actor:level_vertex_id(),db.actor:game_vertex_id())

Попробовал сделать скрипт спавна аномалии в произвольной точке в 30-60 метров впереди ГГ. Набросал код такого вида.

[cut=Код]elseif dik==DIK_keys.DIK_F5 then
self.OnButton_return_game()
local dis = 45+math.random(-15,15)
local dir = db.actor:direction()
local pos = db.actor:position()
local radiys = math.random(2,8)
position = pos:add(dir:mul(dis))
create_anomaly_1("zone_mine_electric_weak",radiys,position,db.actor:level_vertex_id(),db.actor:game_vertex_id())
--create_anomaly_1("zone_mine_electric_weak",4,-2.5531272888184,-7.0012526512146,549.51348876953,db.actor:level_vertex_id(),db.actor:game_vertex_id())[/cut]

Имею стабильный вылет с логом:

[cut=Лог]FATAL ERROR

[error]Expression : error handler is invoked!
[error]Function : handler_base
[error]File : D:\prog_repository\sources\trunk\xrCore\xrDebugNew.cpp
[error]Line : 764
[error]Description : illegal instruction


stack trace:[/cut]

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

sergej5500, Функция ожидает число с плавающей точкой, а вы передаете вектор!
Код
create_anomaly_1("zone_mine_electric_weak",radiys,position.x,position.y,position.z,db.actor:level_vertex_id(),db.actor:game_vertex_id())


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

Добрый день.

Два года назад я задавал вопрос по радиусу видимости НПС в разное время суток. Получил ответ. Подробности тут.

В СГМ плохое зрение НПС реализовано примерно так же.

В СГМ нашел функцию

-- 'Значение дальности обзора НПС.
function ReadEyeRange(section)
local ltx = system_ini()
if ltx:line_exist(section,"eye_range") then
return ltx:r_float(section,"eye_range")
else
return 80
end
end

Как я понял, функция должна прочитать значение радиуса обзора из конфига. И выдать числовое значение.

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

Функция makdm:

if self.object:character_community() ~= "zombied" then
if in_time_interval(21,7) then
self.object:set_fov(90)
self.object:set_range(50)
else
self.object:set_fov(180)
self.object:set_range(100)
end
end

Как это правильно сделать?

Добавлено (11.06.2017, 17:39)
---------------------------------------------
Всем добрый день. Вопрос, который ставил в предыдущем посту, решил самостоятельно.

Составил функцию для xr_motivator.

[cut=Функция]

function control_eye_range_fov(object)
if in_time_interval(21,5) then
if object:range()>30 then
object:set_range(30)
end
if object:fov()>90 then
object:set_fov(90)
end
else
if object:range()<ReadEyeRange(object:section()) then
object:set_range(ReadEyeRange(object:section()))
end
if object:fov()<ReadEyeFov(object:section()) then
object:set_fov(ReadEyeFov(object:section()))
end
end
end[/cut]

Две служебные функции в _g.scripts.

[cut=Функции]

-- 'Контроль зрения НПС.
function ReadEyeRange(section)
local ltx = system_ini()
if ltx:line_exist(section,"eye_range") then
return ltx:r_float(section,"eye_range")
else
return 90
end
end
function ReadEyeFov(section)
local ltx = system_ini()
if ltx:line_exist(section,"eye_fov") then
return ltx:r_float(section,"eye_fov")
else
return 160
end
end[/cut]

Тесты показывают, что всё работает. Ночью боты однозначно видят хуже. Проверил на тестовых зомби и на наймах с СПО на юге Затона.

Друг друга неписи ночью тоже видят много хуже. Спавнил рядом Долг и Свободу. Днем они засекают друг друга на гораздо большей дистанции.

Функцию control_eye_range_fov(object) вызываю из функции motivator_binder:update(delta).

Вопрос такой. В плане оптимизации это лучшее, что можно придумать для решения данной задачи? Или есть более рациональный путь? Если есть, то какой?

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

Цитата sergej5500 ()
В плане оптимизации это лучшее, что можно придумать для решения данной задачи?

Может разве что вести таблицу объектов которым делаешь изменение параметров и ориентироваться на нее, а не читать каждый раз параметры.


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

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

Из аддона Припять - Точка Отсчёта адаптировал на чистый ЗП скрипт воздействия аномалий на НПС. Адаптация прошла удачно.

В игре есть мины zone_mine_field. Пришла в голову мысль усилить действие мины, заспавнив динамит и подорвав его.

[cut=Код срабатывания мины]

elseif string.find( hit_type, "explosion" ) ~= nil then

self.sound_mine:play_at_pos( self.object, anomaly_pos, 0, sound_object.s3d )
self.part_mine:play_at_pos( vector():set( x, y, z ) )
self.sound_npc = sound_object( sound_npc_tbl[ math.random( #sound_npc_tbl ) ] )
self.sound_npc:play( npc, 0, sound_object.s2d )
npc:kill( npc )
local x = position_npc.x
local y = position_npc.y + 5.0
local z = position_npc.z
local vect = vector():set( x, y, z ):sub( position )
local property_hit = hit.strike
make_hit( npc, 10, 2000, "bip01_l_foot", npc, vect, property_hit )
local sobj = alife():object( self.object:id() )
alife():release( sobj, true )
return[/cut]

Написал такой код

[cut=Код]


elseif string.find( hit_type, "explosion" ) ~= nil then
local x = position.x
local y = position.y + 3
local z = position.z
local vect = vector():set( x, y, z ):sub( position )
self.sound_mine:play_at_pos( self.object, anomaly_pos, 0, sound_object.s3d )
self.part_mine:play_at_pos( vector():set( x, y, z ) )
local property_hit = hit.strike
self.sound_npc = sound_object( sound_npc_tbl[ math.random( #sound_npc_tbl ) ] )
self.sound_npc:play( npc, 0, sound_object.s2d )
make_hit( npc, 20, 2000, "bip01_l_foot", npc, vect, property_hit )
local sobj = alife():object( self.object:id() )
alife():create("remote_mine_field",vector():set(sobj:position()),sobj:level_vertex_id(),sobj:game_vertex_id())
level.add_call(
function()
if get_story_object("remote_mine_field") ~= nil then
return true
end
end,
function()
expl_obj = get_story_object("remote_mine_field")
expl_obj:explode(0)
end
)
if xr_conditions.object_exist(nil,nil,{"remote_mine_field"}) then
xr_effects.destroy_object(actor,npc,{"story","remote_mine_field"})
end

alife():release( sobj, true )
return[/cut]

Игра вылетает в момент спавна заряда.

alife():create("remote_mine_field",vector():set(sobj:position()),sobj:level_vertex_id(),sobj:game_vertex_id())

[cut=Лог]
FATAL ERROR

[error]Expression : !m_error_code
[error]Function : raii_guard::~raii_guard
[error]File : D:\prog_repository\sources\trunk\xrServerEntities\script_storage.cpp
[error]Line : 748
[error]Description : No such operator defined


stack trace:[/cut]

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

sergej5500, sobj:position() - это вектор, поэтому конструкция vector():set()- теряет смысл и приводит к вылету.

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

Цитата denis2000 ()
это вектор, поэтому конструкция vector():set()- теряет смысл и приводит к вылету


Хорошо. Тогда как написать правильно?
 
denis2000Дата: Пн, 12.06.2017, 22:59 | Сообщение # 883
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

sergej5500, Очевидно:
Код
alife():create("remote_mine_field",sobj:position(),sobj:level_vertex_id(),sobj:game_vertex_id())


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

denis2000,

Опробовал Ваш вариант кода.

[cut=Код]
elseif string.find( hit_type, "explosion" ) ~= nil then
local x = position.x
local y = position.y + 3
local z = position.z
local vect = vector():set( x, y, z ):sub( position )
self.sound_mine:play_at_pos( self.object, anomaly_pos, 0, sound_object.s3d )
self.part_mine:play_at_pos( vector():set( x, y, z ) )
local property_hit = hit.strike
self.sound_npc = sound_object( sound_npc_tbl[ math.random( #sound_npc_tbl ) ] )
self.sound_npc:play( npc, 0, sound_object.s2d )
make_hit( npc, 20, 2000, "bip01_l_foot", npc, vect, property_hit )
local sobj = alife():object( self.object:id() )

alife():create("remote_mine_field",sobj:position(),sobj:level_vertex_id(),sobj:game_vertex_id())
level.add_call(
function()
if get_story_object("remote_mine_field") ~= nil then
return true
end
end,
function()
expl_obj = get_story_object("remote_mine_field")
expl_obj:explode(0)
end
)
if xr_conditions.object_exist(nil,nil,{"remote_mine_field"}) then
xr_effects.destroy_object(actor,npc,{"story","remote_mine_field"})
end

alife():release( sobj, true )
return[/cut]

Ничего не изменилось. Всё тот же вылет на этапе спавна бомбы.
 
denis2000Дата: Ср, 14.06.2017, 08:01 | Сообщение # 885
Полевой исследователь
Ученые сталкеры
Сообщений: 2399
Награды: 35
Репутация: [ 1918 ]

Цитата sergej5500 ()
Всё тот же вылет на этапе спавна бомбы.

Значит вылет возникает или чуть ранее или из-за того, что вы спавните.


"Он ловко выхватил из-под себя табуретку и очень метко и сильно бросил ее в докладчика..."
(Чугунный всадник)
 
Поиск: