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

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

а мог он так зависнуть что другие колбеки актора работают?
У меня actor_binder:on_item_take срабатывает, и там обнаруживается что актора нет.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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.

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

Нашел причину. Зависание произошло в actor_binder:load. причем по дурацкой причине - читались всякие данные из конфига, ltx:r_string(section, line). в качестве section оказался nil. И процесс завис.
actor_binder:net_spawn после этого вообще не вызвался.
когда устранил зависание, оказалось что actor_binder:net_spawn вызывается сразу после actor_binder:load.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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.

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

что actor_binder:net_spawn вызывается сразу после actor_binder:load

 

Да. Всегда, кроме начала игры. И не только актор, а вообще все.

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

Всем привет.
Хотел добавить зависимость выпадения вещей после смерти НПС от ранга. Но поскольку я в скриптинге не очень опытный, то возникают баги.


--' Ключем является группировка персонажа. Значением является таблица, содержашая имена секций предметов.
local item_by_community = {}

--' Зависимости в спауне предметов. Предмет спауниться только если есть хотя бы один из зависимых.
local item_dependence = {}

--' Множители и минимаксы для выпадения вещей в зависимости от уровня
local mul_by_level = {}
local count_by_level = {}

--' Множители и минимаксы для выпадения вещей в зависимости от ранга
local mul_by_rank = {}
local count_by_rank = {}

--' Предметы, которые нельзя удалять (квестовые например)
local always_keep_item = {}

--' Предметы, относящиеся к патронам. Их надо спаунить другим методом.
local ammo_sections = {}

local death_ini = ini_file("misc\\death_generic.ltx")


function init_drop_settings()
local community_list = { "stalker", "dolg", "freedom", "bandit", "military", "zombied", "ecolog", "killer", "monolith", "arena_enemy", "actor_dolg" }

for k,v in pairs(community_list) do
--' Необходимо заполнить таблицу
item_by_community[v] = {}
if death_ini:section_exist(v) then
local n = death_ini:line_count(v)
local id, value = "", ""
for i=0,n-1 do
result, id, value = death_ini:r_line(v,i,"","")
item_by_community[v][id] = 100*tonumber(value)
end
end
end

--' Заполняем таблицу зависимостей
local n = death_ini:line_count("item_dependence")
local id, value = "", ""
for i=0,n-1 do
result, id, value = death_ini:r_line("item_dependence",i,"","")
item_dependence[id] = {}
local vvv = parse_names(value)
for k,v in pairs(vvv) do
item_dependence[id][v] = true
end
end

--' Множители и минимаксы для выпадения вещей в зависимости от уровня
local level_name = level.name()

if not death_ini:section_exist(level_name) then
level_name = "default"
end

local n = death_ini:line_count(level_name)
local id, value = "", ""
for i=0,n-1 do
result, id, value = death_ini:r_line(level_name,i,"","")
mul_by_level[id] = tonumber(value)
end

--' Множители и минимаксы для выпадения вещей в зависимости от ранга
local character_rank = db.actor:rank()

if not death_ini:section_exist(character_rank) then
character_rank = "novice"
end

local n = death_ini:line_count(character_rank)
local id, value = "", ""
for i=0,n-1 do
result, id, value = death_ini:r_line(character_rank,i,"","")
mul_by_rank[id] = tonumber(value)
end

local item_count_section = "item_count_" .. level.get_game_difficulty()
local n = death_ini:line_count(item_count_section)
for i=0,n-1 do
result, id, value = death_ini:r_line(item_count_section,i,"","")
--' Нужно распарсить value в два значения
local t = parse_nums(value)
if t[1] == nil then
abort("Error on [death_ini] declaration. Section [%s], line [%s]", item_count_section, tostring(id))
end
local min = t[1]
local max = t[2]
if max == nil then
max = min
end

if mul_by_level[id] == nil then
mul_by_level[id] = 0
end

if mul_by_rank[id] == nil then
mul_by_rank[id] = 0
end

min = tonumber(min) * (mul_by_level[id] + mul_by_rank[id])
max = tonumber(max) * (mul_by_level[id] + mul_by_rank[id])

count_by_level[id] = {min = min, max = max}
count_by_rank[id] = {min = min, max = max}
end

--' Предметы, которые нельзя удалять (квестовые например)
local n = death_ini:line_count("keep_items")
for i=0,n-1 do
result, id, value = death_ini:r_line("keep_items",i,"","")
if value == "true" then
always_keep_item[id] = true
end
end

--' Предметы, относящиеся к патронам. Их надо спаунить другим методом.
ammo_sections = {}
local n = death_ini:line_count("ammo_sections")
local id, value = "", ""
for i=0,n-1 do
result, id, value = death_ini:r_line("ammo_sections",i,"","")
ammo_sections[id] = true
end
end



class "drop_manager"
function drop_manager:__init(npc)
self.npc = npc
end
function drop_manager:create_release_item()
--' Спрашиваем у серверного объекта генерились ли предметы
local se_obj = alife():object(self.npc:id())
if se_obj.death_droped == true then
return
end
se_obj.death_droped = true

--' Запускаем итератор на удаление предметов
self.npc:iterate_inventory(keep_item, self.npc)

--' Проверка на отсутствие спауна лута
local ini = self.npc:spawn_ini()

if ini and ini:section_exist("dont_spawn_loot") then
return
end

--' Доспавниваем необходимое количество итемов:
--' Необходимо составить список объектов которые могут быть заспавнены для персонажа

local spawn_items = item_by_community[self.npc:character_community()]
for k,v,t in pairs(spawn_items) do
--' По каждому объекту необходимо получить зависимости
if check_item_dependence(self.npc, k) == true then
--' По каждому объекту необходимо получить количество
local number = math.ceil(math.random(count_by_level[k].min, count_by_level[k].max))
--' Необходимо заспавнить нужное количество.
create_items(self.npc, k, number, v)
end
end
end

--' Функция вызывается для каждого предмета, если вернет false то предмет удалится.
function keep_item(npc, item)
if item==nil or alife():object(item:id())==nil then return end
local section = item:section()

if section == "bolt" then
return false
end

if always_keep_item[section] == true then
return true
end

local item_id = item:id()
local item_in_slot = npc:item_in_slot(1)
if item_in_slot ~= nil and
item_in_slot:id() == item_id
then
--' Тут надо уменьшить кондишн оружия
item:set_condition((math.random(15)+75)*item:condition()/100)
return true
end
item_in_slot = npc:item_in_slot(2)
if item_in_slot ~= nil and
item_in_slot:id() == item_id
then
--' Тут надо уменьшить кондишн оружия
item:set_condition((math.random(15)+75)*item:condition()/100)
return true
end
alife():release(alife():object(item:id()), true)
end
function set_weapon_drop_condition(item)
local condition = (math.random(15)+75)/100
--printf("condition [%s]", tostring(condition))
item:set_condition(condition)
end

--' Функция спавнит необходимое число предметов
function create_items(npc, section, number, rnd)
--'printf("create %s of %s", tostring(number), tostring(section))
if ammo_sections[section] == true then
if number > 0 then
se_respawn.create_ammo(section,
npc:position(),
npc:level_vertex_id(),
npc:game_vertex_id(),
npc:id(),
number)
end
else
for i=1,number do
--' Проверяем вероятность появить каждый объект в отдельности
if math.random(100) <= rnd then
alife():create(section,
npc:position(),
npc:level_vertex_id(),
npc:game_vertex_id(),
npc:id())
end
end
end
end


--' Функция проверяет есть ли хоть один из зависимых объектов у персонажа
function check_item_dependence(npc, section)
if item_dependence[section] == nil then
return true
end

local d_flag = true
for k,v in pairs(item_dependence[section]) do
local obj = npc:object(k)
if obj ~= nil and npc:marked_dropped(obj) ~= true then
return true
end
d_flag = false
end

return d_flag
end

Функця работает, но дело в том, что учитывается ранг Актора, а не НПС. А вот как сделать, чтобы учитывался ранг НПС, я не знаю.

Изменено пользователем Gaz24
Ссылка на комментарий
@Gaz24, ну, во-первых, ранг нпс, получаемый функцией npc:charactr_rank() - это число. А во-вторых, ранг нпс нужно проверять в функции drop_manager:__init(npc), т.к. именно сюда передаётся объект нпс при спавне лута, здесь уже можно получит его ранг, а от него уже и плясать.
  • Согласен 1

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

Ссылка на комментарий
function actor_set_freedom (actor, npc)
    printf ("ACTOR NOW IN FREEDOM COMMUNITY")
    if db.actor then
       db.actor:set_character_community ("actor_freedom", 0, 0)
    end
end

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

Intrel Core i5 9400F, msi gtx 1660 super ventus, RAM 16g-DDR4, HD 2000g, Win 10x64, SSD 256g, SSD m2 500g.

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

@Хемуль36рус, конечно можно:

function npc_set_freedom (actor, npc)
    if npc then
       printf ("NPC [%s] NOW IN FREEDOM COMMUNITY", npc:name())
       npc:set_character_community ("freedom", 0, 0)
    end
end
Изменено пользователем naxac
  • Полезно 1

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

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

@Хемуль36рус, немного дополню ответ @naxac.

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

Изменено пользователем Kirgudu
  • Полезно 1
Ссылка на комментарий

Господа спасибо за науку. Вот только, я что-то не пойму. Дело происходит на складах. НПС которому нужно быстро сменить группировку сталкер, мне его надо сделать врагом. Проблем нет, но иногда находятся сочувствующие ему, что не нужно совсем. Применяя вот такую функцию

 
if first_speaker:id()==0 then
  second_speaker:set_goodwill(-5000, first_speaker)
else
  first_speaker:set_goodwill(-5000, second_speaker)
end

НПС(Цыган) становится врагом без смены естественно группировки.

 

Делаю как написали

function npc_set_killer (actor, npc)
    if npc then
       printf ("NPC [%s] NOW IN KILLER COMMUNITY", npc:name(cigan))
       npc:set_character_community ("killer", 0, 0)
    end
end

Цыган тоже враг, но группировка почему-то не меняется, и вдобавок Свободовцы то же становятся врагами. :blink: Не понятно почему. Главное Цыган враг, при этом он одиночка, но никак не найм. Сразу не глянул, оказывается ГГ становится наймом, а не НПС, НПС заспавнен через скрипт, может поэтому и не работает. Нужен через алспавн, со своим id?

Изменено пользователем Хемуль36рус

Intrel Core i5 9400F, msi gtx 1660 super ventus, RAM 16g-DDR4, HD 2000g, Win 10x64, SSD 256g, SSD m2 500g.

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

 

 

оказывается ГГ становится наймом, а не НПС

ошибка скорее всего в передаче объектов в ф-цию npc_set_killer (actor, npc) - актер и НПС попутаны.

Попробуй, сделать так:

 

if npc:section() ~= "actor" then
     npc:set_character_community ("killer", 0, 0)
else
     actor:set_character_community ("killer", 0, 0)
end

такой код будет универсальный - в любом раскладе именно НПС сменит группировку.

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

 @AndreySol, функция заработала когда поменял местами npc и actor.

e1e614a303a95f49f1fb8afd9ca5f0e6bcfe7e19

Изменено пользователем Хемуль36рус

Intrel Core i5 9400F, msi gtx 1660 super ventus, RAM 16g-DDR4, HD 2000g, Win 10x64, SSD 256g, SSD m2 500g.

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

@Хемуль36рус, не могу сейчас посмотреть, как в ТЧ, но в ЧН в модуле dialogs.script есть такая функция:

function who_is_npc(first_speaker, second_speaker)
  local npc = second_speaker
  if db.actor:id() == npc:id() then
    npc = first_speaker
  end
  return npc
end 

которая возвращает НПС при любом порядке подачи аргументов. Можно обратить условие и получить функцию возврата актора.

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

function npc_set_killer(actor, npc)
  local npc = who_is_npc(actor, npc)
  printf("NPC [%s] NOW IN KILLER COMMUNITY", npc:name())
  npc:set_character_community("killer", 0, 0)
end
Ссылка на комментарий

@Kirgudu, ну вот на тч артос такое написал, а вообще советовал бы диалогс.скрипт из симбиона глянуть, там в целом удобно все сделано:


function fGet_Actor(oSpeaker1, oSpeaker2)
if oSpeaker1:id() == (idActor or db.actor:id()) then
return oSpeaker1 --/>
end
return oSpeaker2 --/>
end
function fGet_NPC(oSpeaker1, oSpeaker2)
if oSpeaker2:id() == (idActor or db.actor:id()) then
return oSpeaker1 --/>
end
return oSpeaker2 --/>
end
function fGet_Actor_NPC(oSpeaker1, oSpeaker2)
if oSpeaker1:id() == (idActor or db.actor:id()) then
return oSpeaker1,oSpeaker2
end
return oSpeaker2,oSpeaker1 --/>
end

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

Просто я хотел показать @Хемуль36рус, как можно сделать, чтобы не забивать голову выбором объекта.

Kirgudu

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

Всем привет.

Всё никак не могу найти способ/функцию/метод высаживания гг из машины. Подскажите пожалуйста, возможно ли это реализовать через скрипт.

Интересует также возможность получения состояния двигателя машины - включён или нет, а так же задание этого состояния. 

 

P.S. Работаю с модом LWO 1.5

... А наше дело маленькое - с ружьём да по болотам. (с)

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

Если нужен актор - для сингла его id всегда 0, а game object - db.actor

Если нужен непись, то ( ( ( n1:id() ~= 0 ) and n1 ) or n2 )

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

Доброго веремени суток, не подскажет ли кто, как перенести выброс от АМК на чистую игру, только выброс, какие файлы отвечают за него, и что куда прописать, заранее благодарен.

 

Не выйдет "куда что прописать". Минимум 5 файлов, относящихся к собственно выбросу. И за ними куча других. dc

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

Вопрос по функциям класса game_object

function change_team(number, number, number)
void change_team(int team, int squad, int group) 
меняет для объекта team, squad и group.
function set_character_community(string, number, number)
void set_character_community(string comm, int squad, int group)
определяет объект в группировку. Аргументы:
comm - название группировки
squad - отряд, в который определяется объект
group - группа, в которую определяется объект.

 

 

Для чего предназначены вот эти team, squad и group. На что влияют?

в самостоятельных раскопках выяснил - у клиентского объекта эти свойства можно только установить, вышеуказанными функциями, но нельзя узнать (нет функции возвращающей их). У серверных объектов можно как установить, так и узнать. Поиск по скриптам: team упоминается в скриптах занимающихся схемами поведения нпс, и работой гулагов. squad и group только в скриптах гулагов. Если кто может разъяснить назначение этих параметров, буду благодарен.

Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на 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.

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

Кто знает как проверить в ЗП установленный на костюм апгрейд? Помогите пожалуйста, нужен пример.

Типа:

Если установлен_апгрейд то

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

 

 

Для чего предназначены вот эти team, squad и group. На что влияют?

Советую почитать настройку логики вот здесь.

Вкратце, это объединение\распределение неписей в группы и группки, для синхронизации их действий.

Вообще-то я белая и пушистая...

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

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

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

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

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

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

Войти

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

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

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...