Перейти к контенту

Рекомендуемые сообщения

_Призрак_, хм, стандартных функций нету, я не нашел, может кто получше знает? Но пришла идея. Пост получился в стиле догадок, так что попрошу не смеяться\плакать. Прим.: лв - левел вертекс.

Как можно вообще получить лв?

1. Через граф игры, но там нигде не используется позиция. В общем, не то, хотя кто его знает.

2. Методы game_object.

2.1. accessible_nearest(const vector&, vector&)

Первый вектор это наша позиция, второй - направление(?). Предположительно, возвращает ближайший вертекс к позиции в направлении второго вектора, куда может пойти непись, к которому был применен этот метод. У меня вызывал вылет без лога, может у тебя, _Призрак_, получиться. Пример использования в xr_kamp, при этом, как условие, используется и метод accessible(number), аргумент - ид лв. Общий смысл наверное этот, но почему у меня не работает, не знаю. Это было первое, что мне пришло в голову.

 

2.2. level_vertex_id()

Более чем знакомый метод. Поясню смысл, по заданной позиции мы спавним предмет, который не требует лв (антирад например). Дальше я хотел узнать сразу лв через свойство серверного объекта m_level_vertex_id, но ни черта не вышло - вернуло nil, почему? Класс не тот? Использовал другую секцию, соответственно другой класс, где это свойство точно должно быть, и опять nil. Решил довести до конца, т.е. до клиентского объекта.

if se_obj then
    local cl_obj = level.object_by_id(se_obj.id)
    if cl_obj then
        local text = string.format("diff time %s; c_lv: %s; s_lv %s; s_gv %s",
        time - begin,c_obj:level_vertex_id(),tostring(se_obj.m_level_vertex_id),tostring(se_obj.m_game_vertex_id))
        dprint(text)
        alife():release(se_obj,true)
        se_obj = nil
    end
else
    se_obj = alife():create("antirad",vector():set(42.7,6.1,-23.67),0,2791)
    begin = time_global()
end

Все это дело конечно же в апдейте, вне функций объявлены se_obj и begin. В лог посыпалась такая инфа

! Cannot find saved game ~~~ diff time 239; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 249; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 296; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 252; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 258; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 280; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 286; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 250; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 224; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 258; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 271; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 269; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 269; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 264; c_lv: 17459; s_lv nil; s_gv nil
! Cannot find saved game ~~~ diff time 287; c_lv: 17459; s_lv nil; s_gv nil

 

Лв тот, это с моей локации, но способ убивает своей дорогой в Москву через Китай, при этом нужно знать хотябы один гейм вертекс с локации. В общем кривое и сумасшедшее решение.

 

2.3. set_actor_position(vector&)

И тут мне пришла еще одна дурацкая идея, разновидность 2.2. Можно переместить ГГ в заданную позицию, на следущем апдейте снять его лв и вернуть обратно. Минусы значительнее: все это только в пределах активной локации, невозможность обработать сразу несколько точек. Точнее можно и несколько точек, но если их будет слишком много, то играющий успеет увидеть мерцание экрана сразу после загрузки игры (если вообще планируется снимать лв в самом начале, иначе тоже ф топку).

if begin == true then
    old_pos = db.actor:position()
    db.actor:set_actor_position(vector():set(42.7,6.1,-23.67))
    begin = false
elseif begin == false then
    dprint(db.actor:level_vertex_id())
    db.actor:set_actor_position(old_pos )
    begin = nil
end

Снова в апдейте, а begin и old_pos так же объявлены как глобальные для модуля. Единственный плюс, меньше нагрузки и скорость побольше, за один апдейт все свершиться. Но о лучше\хуже вообще не стОит говорить, все как видно и так плачевно :)

 

3. level.vertex_in_direction(number, vector&, number)

И вот вроде бы эврика, но черта с два. Тесты показали несостоятельность этой задумки, точнее только на половину. Итак, эта функция возвращает лв в направлении единичного вектора (2 аргумент) от другого лв (ид - 1 аргумент) на расстоянии (число - 3 аргумент). Например level.vertex_in_direction(0,vector():set(0,0,1),5) - по хорошему это дело вернет лв от нулевого лв на расстоянии 5 метров строго на север, НО если на пути не будет ноды (аи сетка пошла вокруг камня, а направление проходит как раз через камень), то возвратится граничный лв. Решил немножко порисовать. 6b8f865cf50a15758c3fb370f6fe68c1bce20d126316361.jpg

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

function get_vl_by_pos(pos_lv)
    local n = 16661
    pos_lv = vector():set(42.7,6.1,-23.67)
    local pos_n = level.vertex_position(n)
    local dir = vector():sub(pos_lv,pos_n)
    local radius = dir:magnitude()
    dir:normalize()
    local lv = level.vertex_in_direction(n,dir,radius)
    dprint(lv)
end

Сначала я взял n = 0 но не вышло изза описаной выше проблемы, взял который не так далеко, все заработало. Тут я переопределил входной аргумент, это исходная позиция.

 

 

В итоге тоже присоединяюсь к вопросу, покажите мне, извращенцу, как можно получить лв по позиции? И задам еще более обширный вопрос, как получить все лв, которые находятся в какой либо зоне, в рестрикторе например?

ТЧ 1.0004. SAP и Trans mod

github

Ссылка на комментарий

Zander_driver, А возможно ли заблокировать стандартное значения конфига, допустим опять же inv_weight, будет считываться не с конфига а со скрипта ?

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

Возможно есть какое ни будь решение с характеристиками ?

Ссылка на комментарий

boryan67, собственно все есть в процитированном тобою же.

Если в логике для конкретного рестриктора указать типа:

[logic]
active = sr_idle@in

[sr_idle@in]
on_actor_inside = nil %=my_func(my_param)%

- то в my_func(actor,obj,p) ты можешь делать все что хочешь именно с этим рестриктором (obj). Т.е. он "сам себе" вызвал функцию и в ней его же можно удалить иль еще чего душа пожелает. Условие "on_actor_inside" подбираешь под свои задачи.

 

boryan67: Другими словами, возможно ли установить, что данный конкретный рестриктор уже отработал и может быть удален?

А вот об этом ты должен позаботиться. Скрипт сам не может знать, отработал об'ект свою задачу иль нет. Дав, например, какой нибудь инфопоршень при выпонении задачи - ты по наличию этого инфопоршня и подскажешь скрипту ... Для одноразовых, как в примере выше, это не требуется.

 

_Призрак_, не получится в игре ТЧ получить айдишники вертексов по позиции ... без доработки движка или без трудоемкой иттерации. Для ЧН/ЗП есть: level.vertex_id(vPos).

Во-первых, идентификаторы левел-вертексов (да и game-) не распложены как-то упорядоченно, т.е. не получиться составить табличку соответствий координат и идентификаторов.

Во-вторых, при перекомпиляции карт все подобное соответстве изменяется, а это значит, что и в модах с разными картами все это различно.

 

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

 

Могу только предложить некоторые наработки по этой теме из Симбиона:

function Get_LevelId(idGv)
  if idGv and game_graph():valid_vertex_id(idGv) then
    local oVertex = game_graph():vertex(idGv)
    if oVertex then
      return oVertex:level_id() --/> idLevel | idMap
    end
  end
  printf("Get_LevelId:idGv=[%s]<~NOT_valid:<%s>", idGv, "Warning!")
  return nil --/>
end

function fGet_LevelId(Obj,idGv)
  if not idGv and Obj then
    idGv = Obj.m_game_vertex_id
    if not idGv then
      idGv = Obj.game_vertex_id and Obj:game_vertex_id()
    end
  end
  if idGv then
    return this.Get_LevelId(idGv) --/> idLevel | idMap
  end
  printf("fGet_LevelId:Obj=[%s/%s]:<%s>", type(Obj), type(Obj) == 'userdata' and Obj:name(), "Warning!")
  return nil --/>
end

function Get_LevelName(idGv)
  local idLevel = this.Get_LevelId(idGv)
  if idLevel then
    return sim:level_name(idLevel) --/> sLevelName
  end
  return nil --/>
end

function fGet_LevelName_Object(Obj)
  local idLevel = this.fGet_LevelId(Obj)
  if idLevel then
    return sim:level_name(idLevel) --/> sLevelName
  end
  return nil --/>
end

function Get_LevelIdByName(sLevelName)
  if not tLevelIdByName[sLevelName] then
    local idLevel,sLevel = 0,""
    --/ 'глобальное' сканирование всех game_vertex'ов
    local id,idLevelSav,sLevelSav = 0,0,""
    local gmg = game_graph()
    while gmg:valid_vertex_id(id) do
      idLevel = gmg:vertex(id):level_id() --/ ID уровня по game_vertex'у
      if idLevel ~= idLevelSav then --/ сменился ID-уровня?
        sLevel = sim:level_name(idLevel) --/ имя уровня по его ID
        if sLevel ~= sLevelSav then --/ сменилось имя уровня?
          sLevelSav = idLevel
          sLevelSav = sLevel
          tLevelIdByName[sLevel] = idLevel --/ запоминаем
        end
      end
      id = id +1
    end
  end
  return tLevelIdByName[sLevelName] --/> idLevel
end

function Get_IdsByLevelName(sLevelName)
  if not tIdsByLevelName[sLevelName] then
    local idMap = this.Get_LevelIdByName(sLevelName)
    if idMap then
      local idGv = 0
      local gmg = game_graph()
      while gmg:valid_vertex_id(idGv) do
        if gmg:vertex(idGv):level_id() == idMap then
          local idLv = gmg:vertex(idGv):level_vertex_id()
          tIdsByLevelName[sLevelName] = {idMap,idGv,idLv}
          return idMap, idGv, idLv --/>
        end
        idGv = idGv +1
      end
    end
    tIdsByLevelName[sLevelName] = {idMap,nil,nil}
  end
  return tIdsByLevelName[sLevelName][1],tIdsByLevelName[sLevelName][2],tIdsByLevelName[sLevelName][3] --/>
end

--/ вычисление Min & Max game- и level- вертексов для всех локаций
function Choice_MinMax_Vertexes()
  local gmg = game_graph()
  if not gmg then return end --/> еще рано?
  local id,idMap,idPreMap = 0,nil,-1
  while id < 65536 do
    if gmg:valid_vertex_id(id) then
      idMap = gmg:vertex(id):level_id() --/ ID локации
      if idMap ~= idPreMap then --/ не сканировалась?
        tMaxVertexIds[idMap] = {}
        tMaxVertexIds[idMap][1] = id --/ min idGv
        if tMaxVertexIds[idPreMap] then --/ предыдущая просканированная локация
          tMaxVertexIds[idPreMap][2] = id-1 --/ max idGv
        end
        idPreMap = idMap
      end
    else
      tMaxVertexIds[idPreMap][2] = id-1 --/ last max idGv
      break
    end
    id = id +1
  end
  for idx,v in pairs(tMaxVertexIds) do
    v[3] = this.Get_Max_IdLevelVertex(idx,v[1],v[2]) --/ добавляем max idLv
  end
end

function Get_MinMax_IdVertexes(idMap)
  if not idMap then idMap = sim:level_id() end --/ берем текущий уровень
  if not tMaxVertexIds[idMap] then
    local gmg = game_graph()
    local id,idGvMin,idGvMax = 0,nil,nil
    while id < 65536 do
      if gmg:valid_vertex_id(id) and gmg:vertex(id):level_id() == idMap then --/ ID искомой локации?
        if not idGvMin then
          idGvMin = id --/ 1-й индекс искомой локации
        end
        idGvMax = id --/ текущий (он же последний) искомой локации
      elseif idGvMin then --id = 65536
        break
      end
      id = id +1
    end
    local idLvMax = this.Get_Max_IdLevelVertex(idMap,idGvMin,idGvMax)
    tMaxVertexIds[idMap] = {idGvMin,idGvMax,idLvMax}
  end
  return tMaxVertexIds[idMap][1], tMaxVertexIds[idMap][2], tMaxVertexIds[idMap][3] --/> idGvMin и idGvMax и idLvMax
end

function Get_Max_IdLevelVertex(idMap,idGvMin,idGvMax)
  local idLvMax = idMap and tMaxVertexIds[idMap] and tMaxVertexIds[idMap][3]
  if idLvMax then
    return idLvMax --/>
  elseif not (idGvMin and idGvMax) then
    if not idMap then
      idMap = this.Get_LevelId(idGvMin or idGvMax or sim:level_id())  --/ ... или сканируем текущий уровень
    end
    idGvMin,idGvMax,idLvMax = this.Get_MinMax_IdVertexes(idMap)
  end
  if not idLvMax and idGvMin and idGvMax then
    local gmg = game_graph()
    local id,idLv = 0,nil
    for id=idGvMin, idGvMax do
      idLv = gmg:vertex(id):level_vertex_id()
      if not idLvMax or idLvMax < idLv  then
        idLvMax = idLv
      end
    end
    if idMap then tMaxVertexIds[idMap][3] = idLvMax end
  end
  return idLvMax --/>
end

--/ -----------------------------------------------------------------
--/ минимизация погрешности ранее вычисленного 'idLvMax' для текущего уровня:
--/ -----------------------------------------------------------------
function Correct_Max_IdLevelVertex()
  local idLvMax = idMapNow and idMapNow > 0 and tMaxVertexIds[idMapNow] and tMaxVertexIds[idMapNow][3] --/< idLvMaxNow
  if not idLvMax then return end --/> еще рано ...
  local idLv,id,vPos,vPosPrev = 0,1,vector(),vector()
  --/ последовательная итерация увеличения максимального индекса левел-вертекса до НЕ валидного:
  for id=1, 32768 do --/16, 512, 1024, 8192, 16384, 32768, 65535<~X
    idLv = idLvMax + id
    vPos = level.vertex_position(idLv)
    if type(vPos) ~= 'userdata' or type(vPos.getP) ~= 'function' --/ вектор?
       or type(vPos.x) ~= 'number' or type(vPos.y) ~= 'number' or type(vPos.z) ~= 'number' --/ имеются осевые координаты?
       or (vPos.x == 0 and vPos.y == 0 and vPos.z == 0) --/ валидна хотя бы одна из осевых координат?
       or (vPos.x == vPosPrev.x and vPos.y == vPosPrev.y and vPos.z == vPosPrev.z) --/ координаты идентичны предыдущим?
      then --/ не валиден
      idLv = idLv -1 --/ откат к предыдущему валидному значению
      break --/ прерываем итерацию
    else
      vPosPrev = vPos --/ запоминаем вектор координат валидного вертекса
    end
  end
  --/ сравниваем новый и прежний:
  if idLv > idLvMax then --/ 'новый' индекс вертекса больше прежнего?
    idLvMaxNow, tMaxVertexIds[idMapNow][3] = idLv, idLv --/ обновляем новым значением!
    return idLvMaxNow --/>
  end
end
--/ -----------------------------------------------------------------
--/ определение ближайшего левел вертекса к заданной координате (position) с погрешностью ...
--/ -----------------------------------------------------------------
function Get_Never_idLv_by_Pos(vPos,iErr,Obj)
  if not iErr then iErr = 0.5 end --/ если не задана погрешность по дистанции (0 => макс.точность)
  if not vPos and Obj then --/ если не задана позиция ...
    if type(Obj.position) == 'function' then
      vPos = Obj:position()
    else
      vPos = Obj.position
    end
  end
  local idLv,iDistMin,iDist
  for id=0,idLvMaxNow do
    iDist = level.vertex_position(id):distance_to_sqr(vPos)
    if not iDistMin or iDist < iDistMin then
      idLv = id
      iDistMin = iDist
      if iDistMin < iErr then break end --/ прерываем цикл
    end
  end
  return idLv,iDistMin --/>
end

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

 

Добавлено через 6 мин.:

GreadFiasco, тебе стОит понять, что при запуске игры движек считывает все штатные конфиги в свою "память" и ими оперирует. Т.о. параметры, для которых не предусмотрены методы для изменения их значений - не доступны ни для измененеий ни для блокировки.

И параметров актора это касается в первую очередь ... дабы читерить потруднее было бы :crazy:

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Как сделать в скриптовом диалоге рандомный выбор следующей фразы?(одну из двух)...пробовал и с прекондишном, и с пустой фразой...что-то все не то что нужно.

 

Вот когда сформулируешь, что же "нужно", и что/как делал и вышло - "не нужно", тогда и возможен дальнейший разговор/подсказки, а не погадалки. --/Artos

Изменено пользователем Artos
Ссылка на комментарий

Artos, Не думаю что имея конфиги актора и прочего, кому то будет трудно считерить.

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

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

Ссылка на комментарий

Делал я откровенно говоря бред, поэтому и вышло то что "не нужно".

 

А что надо...

 

- Текст 1 =>

- Текст 2 =>

- Текст 3 либо Текст 4

 

Еще часто баги вылетают такие, что как бы НПС говорит фразу ГГ, или после моей фразы опять такая же(по содержанию) только НПС ее говорит. Как с этим бороться?

Изменено пользователем Struck
Ссылка на комментарий
Еще часто баги вылетают такие, что как бы НПС говорит фразу ГГ, или после моей фразы опять такая же(по содержанию) только НПС ее говорит. Как с этим бороться?

Скорее всего, ид фраз неправильно задаешь. Не тот тип данных при своевольных трактовках луа приводит к глюкам в данном случае.

По нужной тебе затее - в первой фразе через экшен вызови math.random(1,100)

Сохрани результат. А на нужные тебе рандомные фразы повесь прекондишены вида

function randomselect_1_2() return (phrase_select_random < 51) end
function randomselect_2_2() return (phrase_select_random > 50) end

 

Driv3r

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

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

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

Zander_driver,

 

Не тот тип данных при своевольных трактовках луа приводит к глюкам в данном случае.

 

Не понял вот эту фразу...вот мой диалог в котором косяки:

 

function news_dlg(dlg)
     phr0 = dlg:AddPhrase(intro_phrase[math.random(1, table.getn(intro_phrase))], "0", "", -10000):GetPhraseScript()
    phr0:AddHasInfo("tutorial_end")
     phr1 = dlg:AddPhrase("Текст 2", "1_2", "0", -10000):GetPhraseScript()
    phr1:AddAction("escape_dialog.costs")
    phr1:AddPrecondition("escape_dialog.randomselect_1_2")
    phr2 = dlg:AddPhrase(no_item_phrase[math.random(1, table.getn(no_item_phrase))], "2_2", "0", -10000):GetPhraseScript()
     phr2:AddPrecondition("escape_dialog.randomselect_2_2")
    -- phr2:AddAction("dialogs.break_dialog")
end

 

Добавлено через 30 мин.:

Что-то никак не поборю эти баги, рандом работает как нужно, спасибо.

 

Вот я даже засунул диалог и тутора(там априори не может быть неправильно), вот такое словил:

 

3176410m.jpg

Изменено пользователем Struck
Ссылка на комментарий

Прошу помочь с вопросом. Допустим. Есть секция предмета в device.ltx.

[active_ruck]
GroupControlSection    = spawn_group
discovery_dependency    = 
$spawn                          = "devices\active_ruck"
class                = O_INVBOX
cform                = skeleton
visual = dynamics\devices\dev_rukzak\dev_rukzak.ogf
script_binding      = bind_secret_box.init

Далее биндер предмета

function init(Obj)
    local new_binder = InvBinder(Obj)
    Obj:bind_object(new_binder)
end

class "InvBinder" (object_binder)
function InvBinder:__init(Obj) super(Obj)
   self.rr_id=Obj:id()
end

function InvBinder:reload(section)
    object_binder.reload(self, section)
end

function InvBinder:reinit()
    object_binder.reinit(self)
    self.object:set_callback(callback.use_object, self.use_callback, self)
end

function InvBinder:update(delta)
    --local actor_pos = db.actor:position()
    --local obj_pos = self.object:position()
    --local dist = actor_pos:distance_to(obj_pos)
    object_binder.update(self, delta)
end

function InvBinder:net_spawn(data)
    return object_binder.net_spawn(self, data)
    if self.rr_id==nil then
        local se_obj=alife():object(self.rr_id)
        if se_obj~=nil then
            level.map_add_object_spot_ser(se_obj.id, "treasure_spot", game.translate_string("mod_treasure"))
            news_manager.send_tip(db.actor, "Получен уникальный тайник", nil, nil, 5000)
        end
        self.rr_id=nil
    end
end

function InvBinder:net_destroy()
    object_binder.net_destroy(self)
    self.object:set_callback(callback.use_object, nil)
end

function InvBinder:net_save_relevant()
    return true
end

function InvBinder:save(packet)
    object_binder.save(self, packet)
end

function InvBinder:load(reader)
    object_binder.load(self, reader)
end

function InvBinder:use_callback(Obj, Who)
  if Obj and Who:id() == db.actor:id() then
    if self.rr_id~=nil and level.map_has_object_spot(self.rr_id, "treasure_spot")~= 0 then
       level.map_remove_object_spot(self.rr_id, "treasure_spot")
    end
  end         
end

Из схемы видно, что являеться целью данного мучения. Я не скриптер, и только учусь. Прошу подсказать, правильно ли я сделал? И в случае спавна разных предметов этой секции произойдёт ли установка метки на другой обьект? Спавн такой схемой

CreateTreasureBox("active_ruck",vector():set(20.52420,-3.29770,-54.53437),298504,112,"avs_secret_1")
--спавн инвенторного ящика
function CreateTreasureBox(section,position,level_vertex_id,game_vertex_id,custom_name)
    local obj = alife():create(section, position, level_vertex_id, game_vertex_id)
    if obj then
        local t = amk.get_invbox_data(obj)
        t.custom = "[logic]\ncfg = scripts\\mod_secret\\"..custom_name..".ltx"
        amk.set_invbox_data(t, obj)
    end
end

В кустом дате обьекта секция [spawn] и перечесление предметов.

Изменено пользователем panzyuza
Ссылка на комментарий

GreadFiasco, все же темы по фантазиям в ином месте, а тут - о том что имеем и конкретно по скриптам. ;-)

 

proger_Dencheek, в ТЧ/ЧН проверку визуала можно сделать только или прочитав соответствующий параметр из нет-пакета непися или парсинком его профиля в xml'ке ...

 

Struck, рандомность выбора фраз в диалогах возможна только при самом первом создании драфта (дерева) диалога. В последующем - что получил - то и будет показывать в диалоге, и так до перезагрузки.

 

Добавлено через 6 мин.:

panzyuza, метки подобным образом ставятся на идентификатор об'екта и поэтому "произойти установки метки на другой обьект" накак не может. Т.е. на какой id ставишь - не том и будет метка.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий
Artos, если я правильно понял, нужно оставить данную секцию как базовую, и просто спавнить рюкзаки с другими секциями. Значит, их секции и будут использованы как id. Изменено пользователем panzyuza
Ссылка на комментарий

panzyuza, у тебя какая-то каша в голове ....

1. Что значит в твоем понимании и в контексте твоего вопроса "базовая секция"?

2. Секции НЕ имеют и не подучают идентификаторов (id), вот заспавнив по какой-либо секции об'ект - он и получает игровой иденификатор, который можно использовать ...

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

Ссылка на комментарий

Как сделать, чтоб после определенного действия улучшались характеристики определенного оружия(хочу сделать подобие книги тактики ведения боя, из Sigerous)

Ссылка на комментарий
Не понял вот эту фразу...вот мой диалог в котором косяки:

Ну что тут не понять? игра хочет видеть число, а ты ей строку подсовываешь.

 phr0 = dlg:AddPhrase(intro_phrase[math.random(1, table.getn(intro_phrase))], "0", "", -10000):GetPhraseScript()

"0" измени на 0. "" - на -1.

 phr1 = dlg:AddPhrase("Текст 2", "1_2", "0", -10000):GetPhraseScript()

"1_2" - замени на 2. "0" - на 0.

И так далее, не строки, а числа. Как я понял из сторонних источников, строковые ид фраз применяются начиная с 5-го патча. А на 4-м и ранее - только числа.

Artos !

Struck, рандомность выбора фраз в диалогах возможна только при самом первом создании драфта (дерева) диалога. В последующем - что получил - то и будет показывать в диалоге, и так до перезагрузки.

Ну вы бы читали хоть вышенаписанное. Я же уже привел пример как рандомный выбор реализовать :)

 

Вот, если угодно, его величество рандом во всей красе

local phrase_select_random
function upd_random()
phrase_select_random = math.random(1,100)
end
function randomselect_1_10() return (phrase_select_random < 11) end
function randomselect_2_10() return (phrase_select_random > 10 and phrase_select_random < 21) end
function randomselect_3_10() return (phrase_select_random > 20 and phrase_select_random < 31) end
function randomselect_4_10() return (phrase_select_random > 30 and phrase_select_random < 41) end
function randomselect_5_10() return (phrase_select_random > 40 and phrase_select_random < 51) end
function randomselect_6_10() return (phrase_select_random > 50 and phrase_select_random < 61) end
function randomselect_7_10() return (phrase_select_random > 60 and phrase_select_random < 71) end
function randomselect_8_10() return (phrase_select_random > 70 and phrase_select_random < 81) end
function randomselect_9_10() return (phrase_select_random > 80 and phrase_select_random < 91) end
function randomselect_10_10() return (phrase_select_random > 90) end

 

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

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

Изменено пользователем Zander_driver

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

AMD Ryzen 9 7950X (16 ядер, 32 потока, 5.75 ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

Ссылка на комментарий

У меня вопрос касающийся зомбиков.

--    if self.object:character_community() == "zombied" then
        local manager = self.object:motivation_action_manager()
        manager:remove_evaluator    (stalker_ids.property_anomaly)
        manager:add_evaluator        (stalker_ids.property_anomaly, property_evaluator_const(false))
--    end

Здесь сказан, что для зомби аномалий нет.

А если я сделаю так:

    if self.object:character_community() == "zombied" then
        local manager = self.object:motivation_action_manager()
        manager:remove_evaluator    (stalker_ids.property_anomaly)
        manager:add_evaluator        (stalker_ids.property_anomaly, property_evaluator_const(true))
    end

зомби теперь будут умирать, при попадании в аномалию?

 

Добавлено через 15 мин.:

И ещё помогите создать функцию на проверку из какого оружия убили НПС или монстра, и если это граната, wpn_rg-6

wpn_rpg7, то эффект был как от аномалии грави (точно не помню, принцип её действии как трамплин в ЗП). Труп должен исчезнуть, а на его мести заспавниться рюкзак с оружием, патронами и прочими вещами, что было у нпс. Если уничтожен монстр то просто исчезает, конечно же остаётся кровь.

 

Извиняюсь если не понятно высказал свои мысли...

32481252.f.500.500.jpg
Ссылка на комментарий

proger_Dencheek, проверять свершилось ли твое действие, и подменять ствол на более лучший.

 

Zander_driver, спасибо, все вышло как надо, просто я делал по тутору...и не удосужился посмотреть примеры в файлах игры, все как всегда просто оказалось, появился вылет правда "No available phrase to say, dialog[escape_trader_test_2]", но видно диалог не так составил.

 

Strelok_124, вешай в death_callback'и неписей и монстров проверку на активное оружие в руках, если это гранатометы, то считывай инвентарь НПС записывай в табличку спавни рюкзак при взятии которого эта табличка спавнится актору(на мотив сетевой игры), а труп удаляй и проигрывай партикл...был какойто забугорный мод где это сделали. А кровь вроде и так останется...но я не уверен.

Ссылка на комментарий

Artos, провел эксперимент по самоудалению рестриктора.

Логика:

[logic]
active = sr_idle@one

[sr_idle@one]
on_actor_inside = | nil %=debug.del_restr%

Функция:

function del_restr(actor, obj, p)
    if obj then
        alife():release(obj)
    end
end

Функция получает правильный объект. Отрабатывает, объект не удаляется, биндер виснет (часы останавливаются).

В чем моя ошибка?

Ссылка на комментарий

boryan67, удалять надо серверный объект, а не что под руку попало.

    if obj then
        local sobj = alife():object(obj:id())
        if sobj then
            alife():release(sobj,true)
        end
    end

 

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   1 пользователь

×
×
  • Создать...