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

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

Artos

Я так понял ему надо изменит нет-пакетом параметры фонарика или какого то другого инвентарного предмета.

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

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

Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О

Мастер аномалий на свою заднюю точку.

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

i have make a script witch shall repswan npc

local first_spwan = false
local respwan_table = {}
local timer = 0
local timer_repswan = 0
local spwan = false

function spwawn()
local levels = {[0] = "marsh", [1] = "l01_escape", [2] = "l02_garbage", [3] = "l03_agroprom", [4] = "l04_darkvalley", [5] = "l05_bar", [6] = "l06_rostok", [7] = "l07_military", [8] = "l08_yantar"}
local level_name = level.name()
if spwan == false then
    if timer == 0 then timer = time_global() + math.random(36, 60) end

        if db.actor:alive() then

            if time_global() > timer then

            timer = 0 
                for indx, lvl in pairs(levels)do
                    if level_name == lvl then
                    ws = indx
                    spwan = true            
                        if spwan == true then
                                if ws == 0 then
                                spawn = 
                                alife():create("mar_clear_sky_respawn_1", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id())
                                alife():create("mar_clear_sky_respawn_2", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id())
                                alife():create("mar_clear_sky_respawn_3", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id())
                                respwan_table[spawn.id] = true
                                first_spwan = true
                                end
                        end
                    end
                end
            end
        end
    end    
if first_spwan == true then
if type(respwan_table) == "table" then
local obj,count,tbl_cnt = nil,0,#respwan_table 

for k,v in pairs(respwan_table) do
obj = alife():object(k)

if obj == nil then
k = respwan_npc_name
v = nil   
if timer_repswan == 0 then timer = time_global() + math.random(36, 60) end
    if db.actor:alive() then
        if time_global() > timer_repswan then
            timer_repswan = 0  
            spawn = alife():create(respwan_npc_name, vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id())
            respwan_table[spawn.id] = true
        end
    end
end
end
end
end
end

but when i kill a npc the npc donґt respwan but why?

can anyoen help me?

thank you

 

No errors, except for some discrepancies.

It is not clear assignment script.

Describe your idea - what do you want to do?

ColR_iT

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

Artos

1. А для чего переводить в оффлайн находящуюся в рюкзаке у актора, например, аптечку иль иной предмет?

Как Shoker и предположил, для изменения нет-пакетом параметров фонарика. Очень хочу попробовать скриптово его вкл\выкл. Состояние его получить могу (исп. Ваш модуль) а вот изменить...

2. А что ты ожидаешь увидеть (когда и где, на экране, в логе, иль еще где) в качестве - "вот предмет находится в оффлайне"?

Сообщение. Для этого в Вашем модуле временно добавил в local execute_switchings = function():

..........................
else --/ object in 'offline' - phase-2:
local msg = "объект в офф-лайн"
news_manager.send_tip(db.actor, msg, nil, nil, 30000)
..........................

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

 

Shoker

А как у Вас в общих чертах выглядит

пришлось для перевода сперва выкидывать предмет на землю, а потом загонять обратно в инвентарь.

Как выкинуть из слота\инвентаря мне понятно, а вот как назад забрать ?

 

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

Sorry that i make a new psot but i donґt knwo how i can at it on my

i will make a script what respwan npc

i have write a script first what all npcґs spwant and then are this npcґs incold in a table

local first_spwan = false
local respwan_table = {}
local timer = 0
local timer_repswan = 0
local spwan = false

function spwawn()
local levels = {[0] = "marsh", [1] = "l01_escape", [2] = "l02_garbage", [3] = "l03_agroprom", [4] = "l04_darkvalley", [5] = "l05_bar", [6] = "l06_rostok", [7] = "l07_military", [8] = "l08_yantar"}
local level_name = level.name()
if spwan == false then
    if timer == 0 then timer = time_global() + math.random(36, 60) end

        if db.actor:alive() then

            if time_global() > timer then

            timer = 0 
                for indx, lvl in pairs(levels)do
                    if level_name == lvl then
                    ws = indx
                    spwan = true            
                        if spwan == true then
                                if ws == 0 then
                                spawn = 
                                alife():create("mar_clear_sky_respawn_1", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id())
                                alife():create("mar_clear_sky_respawn_2", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id())
                                alife():create("mar_clear_sky_respawn_3", vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id())
                                respwan_table[spawn.id] = true
                                first_spwan = true
                                end
                        end
                    end
                end
            end
        end
    end    
if first_spwan == true then
if type(respwan_table) == "table" then
local obj,count,tbl_cnt = nil,0,#respwan_table 

for k,v in pairs(respwan_table) do
obj = alife():object(k)

if obj == nil then
k = respwan_npc_name
v = nil   
if timer_repswan == 0 then timer = time_global() + math.random(36, 60) end
    if db.actor:alive() then
        if time_global() > timer_repswan then
            timer_repswan = 0  
            spawn = alife():create(respwan_npc_name, vector():set(-61.996055603027, 0.92057931423187, 293.67742919922), db.actor:level_vertex_id(), db.actor:game_vertex_id())
            respwan_table[spawn.id] = true
        end
    end
end
end
end
end
end

in the next part of the script the table checked wether the npc is dead

is the nc dead a timmer start and after the timer the npc will respwan

i hope anyone can understand this

sorry for my bad englisch

but when i kill a npc ,the npc dont respwan but why?

can anyoen help me?

thank youolaf1, olaf1, olaf1,

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

Цитата из мануало о том, как задавать вопросы:

Описывайте цель, а не отдельный шаг

 

Если вы пытаетесь разобраться, как что-либо сделать (а не сообщаете об ошибке), начинайте с описания цели. И только потом описывайте конкретный шаг на пути к ней, который вы не смогли выполнить.

 

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

*Shoker*, мною был задан адресный вопрос и суфлерство в данном случае как раз неуместно (и перепрочти цитату).

 

AndreySol, вот желание скриптово вкл/выкл фонарик - еще как то можно назвать целью, а потуги с нет-пакетами и офф/онлайном - это средства. СтОит это все же различать.

(отвечу пока с конца)

1. Учитывая, что фонарик актору достается нахаляву (спавнится в инвентарь автоматом), попадает в слот автоматом и не виден в слоте (в оригинале игры) то спрашивается - а какого лешего фонарик светит во лбу 'голого' актора? А зачем его включать/отключать(,), если можно просто взять и удалить, а когда нужно заспавнить! (ну иль переместить куда-нить во вне актора, например в ящик)

Т.о. если целью является лишить актора возможности светить изо лба (фонариком) - то совсем необязательно управлять фонариком, а достаточно просто удалять фонарик или добавлять его актору. В отличии от иных типов предметов (оружие, КПК, ...) свойства фонарика типа "исправность" иль иные никак не влияют ни на что. Учитывая п.3 (см.ниже) - это вполне позволяет достичь желаемой цели.

 

2. Учитывая, что в ТЧ имеется баг с визуалом актора (вид от 3-го лица) и при получении в инвентарь любого костюма/броника визуал приходится "подправлять" снимая его и надевая - как раз самое удобное и проверять - имеется ли у костюма шлем и если да - переспавнивать фонарик. Ну а если нет на голове ничего - то и фонарик можно не спавнить. Ну это так ... мысли о вообще "что делает на голом лбу фонарик".

 

3. Если "вспомнить", что игра (сингл) возможна только при условии нахождения актора в онлайне, и движек и скрипты контролируют это - то спрашивается, а вообще как это возможно, что основной объект (родитель/владелец) в онлайне, а его часть (предмет из инвентаря) - в оффлайне? Кто-то может мне это объяснить на пальцах? Ну а если предмет "в слоте" - то вообще неясно, что же игрок/модмейкер подразумевает под перевод предмета в оффлайн так, чтобы он не покидал слот ...

Вспоминаем, что телепортируя актора куда-то, мы НЕ занимаемся телепортацией его всего барахла, а это делает движек автоматом!

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

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

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

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

Artos, извиняюсь за 5 копеек, но боюсь, что Вы оба думаете о разных вещах.

Осмелюсь предположить, что AndreySol, хочет именно вкл/выкл фонарик и именно скриптами. Я приблизительно догадываюсь для чего это вообще нужно - батарейки для фонаря, так ведь, AndreySol? :)

Если не ошибаюсь, то фонарик принадлежит классу CTorch, если это так, то набор методов для него скудный и метода вкл/выкл я там не наблюдаю...

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

ColR_iT, я не зря первоначально задал 'глупые' вопросы и привел цитату. Не мне бы нужно адресовать твой пост, а AndreySol ...

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

а) свойства объекта напрямую зависят от свойств его владельца, если таковой есть. И глупо пытаться перевести в онлайн гранату из рюкзака находящегося в оффлайне непися или наоборот. Даже если методы для объекта имеются доступны, то движек все одно контролирует подобное и или блокирует/игнорирует или разрешает ...

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

Повторю, если хочется именно скриптово управлять - читаем п.а). Нельзя же от скриптов требовать невозможного.

Если хочется включать/выключать не давя на кнопки (т.е. через скрипты) включать/выключать - то вариант с переспавном именно это и позволяет делать. Игрок все равно не видит своего фонарика в игре и то, что он гаснет иль загорается - это и есть цель, а то, что фонарика нет в слоте не важно и не заметено! Ну если вес иль объем рюкзака важен(!) - то ничего не мешает внести в алгоритмы расчетов нужные поправки.

Если же кто-то захотел управлять именно яркостью/фокусом ... - то тут уже не раз писАлось, что это невозможно через свойства фонарика, доступные в игре. Тут или напрямую ковырять память игры внешними приблудами или делать несколько вариантов фонариков с разными конфигами и "хитро" переспавнивать (подменять) их в зависимости от пожелалки. Но это уже совсем иная тема и никак не относится к исходному вопросу о нет-пакетах и попытках перевода офф/онлайн.

 

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

 

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

P.S. ColR_iT, метод включения и выключения для фонариков имеется, и о чем упомянуто на предыдущей странице (torch_flags.Active = 1). Управляя флагами через нет-пакеты можно включать/выключать фонарики у неписей (о(в)тключая схему sr_light). Но именно к актору это не применимо, т.к. а) для перечтения измененных флагов фонарик требуется или засэйвить и залоадить или перевести офф-олайн (о чем и речь!) и именно это для актора невозможно. И б) игрок всегда может перебить скрипты имея забинденную <L> ...

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

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

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

ColR_iT

Осмелюсь предположить, что AndreySol, хочет именно вкл/выкл фонарик и именно скриптами. Я приблизительно догадываюсь для чего это вообще нужно - батарейки для фонаря, так ведь, AndreySol?

Именно так.

 

Artos

А зачем его включать/отключать(,), если можно просто взять и удалить, а когда нужно заспавнить! (ну иль переместить куда-нить во вне актора, например в ящик)

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

 

по п.3 - оно то понятно, насчет родительского объекта, но ведь движок все-же изменяет свойства объектов в слотах\инвентаре актера(ГГ) (к примеру - износ оружия в процессе стрельбы) без изъятия (перевода он-офф-он) их из этих самых слотов\инвентаря. И делает он это явно с использованием нет-пакетов, так как это, видимо, единственный способ синхронизации состояния клиентской и серверной частей объекта. Вот я и думал, что возможно менять свойства путем изменения нет-пакетв объектов даже в инвентаре\слотах актера(ГГ).

 

Я только начал изучать работу с нет-пакетами, и модуль для работы с ними от Artos очень помог. А то, что меня попрекают якобы не знанием "элементарных базовых" основ, это все-же не моя вина - уж очень пахабно движок разрабами писан. И с этим (на мой взгляд) очень тяжело поспорить.

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

AndreySol, не ставь телегу перед лошадью ...

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

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

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

2.

AndreySol: ... то, что меня попрекают якобы не знанием "элементарных базовых" основ, это все-же не моя вина - уж очень пахабно движок разрабами писан. И с этим (на мой взгляд) очень тяжело поспорить.
Мда-а-а, спорить тут бесполезно ... в таких случаях говорят - "это диагноз". Почему то все другие модмейкеры с этой "похабщиной" работают и создают моды, не сваливая на разработчиков свои проблемы ...

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

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

can anyone help me??

i have write a script wich shll respwan npcґs in any level

i hope you can see what for what is and i hope that anyone help me.

when you have question to my script the ask me.

local respwan_table = {}
local timer = nil
local levels = {marsh=            {x=-61.996055603027,y=0.92057931423187,z=293.67742919922}
                }
                
local respwan_npc = {
mar_clear_sky_respawn_1 = true,
mar_clear_sky_respawn_2 = true,
mar_clear_sky_respawn_3 = true,
}


function spwan()
if db.actor:alive() == false then return end
            local level_name = level.name()
                    if timer == nil then
                            timer = level.get_time_hours() + math.random(3, 6)
                            if timer > 23 then timer = timer - 24 end
                    end
                    if time_global() > timer then
                            timer = nil
                            for lvl, pos in pairs(levels) do
                                if level_name == lvl then 
                                            local pos = vector():set(pos.x, pos.y, pos.z)
                                            local lvi = db.actor:level_vertex_id()
                                            local gvi = db.actor:game_vertex_id()
                                    for npc,spwan in pairs(respwan_npc)do
                                        if spwan == true then
                                               respwan_table[alife():create("mar_clear_sky_respawn_1", pos, lvi, gvi).id] = true
                                            table.insert(respwan_npc,2,false)
                                           end
                                    end
                                end
                            end
                            
           end   
           local tbl_count,obj = 1,nil
           for k,v in pairs(respwan_table) do
                   obj = db.storage[k] and db.storage[k].object
                        if obj and obj:alive() == false and v == true then
                       table.insert(respwan_npc,2,true)   
                       end
          end
end

but when i start the game i get a crash but in the log are nothing

can anyone help me away?

thank you.

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

olaf1

Sorry for English:)

Firstly, you have logical error in your timer. You have used level.get_time_hours() and time_global() which return not the same type of time. If you open the Referenceща Function and classes (you can find it on our forum) you will see, that level.get_time_hours() returns time in hours,which show which hour now in game, but time_global() returns time in milliseconds,which show how many milliseconds have passed since starting the program. So, you must change underlying code:

if timer == nil then
    timer = level.get_time_hours() + math.random(3, 6)
    if timer > 23 then timer = timer - 24 end
end
if time_global() > timer then

on this code:

if timer == nil then
    timer = level.get_time_hours() + math.random(3, 6)
    if timer > 23 then timer = timer - 24 end
end
if level.get_time_hours() = timer then

 

Secondly, what this code must do? It so.... I can't translate what I think, but it's realy strange code:

for npc,spwan in pairs(respwan_npc)do
    if spwan == true then
        respwan_table[alife():create("mar_clear_sky_respawn_1", pos, lvi, gvi).id] = true
        table.insert(respwan_npc,2,false)
    end
end

Please, explain:)

 

And the last for now, May be I now why you have crash witout log. In for construction you use 'spwan' which already name of function. Change

for npc,spwan in pairs(respwan_npc)do
    if spwan == true then

on

for npc,myspwan in pairs(respwan_npc)do
    if myspwan == true then

and try again. Replay after check

Изменено пользователем _Призрак_

Freedom

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

olaf1, _Призрак_, давайте придерживаться общепринятых норм и правил. Это русскоязычный форум и сообщения на нем пишутся на русском языке(!). В сложных случаях можно писать и дублированием сообщения на оригинальном языке, но не следует этим злоупотреблять!

 

olaf1, уже не первый раз пишешь в тему с нарушением правил. Ничто не мешает тебе использовать онлайн-переводчики. Потрудись, плз, это делать в дальнейшем.

- Считаю, пусть лучше пишет, как пишет: и на английском-то плохо, а с переводчиком будет совсем кошмар и никто ничего не поймет. Cyclone

 

P.S. Именно для "понимания написанного" и применяется вариант с дублированием на общепринятом и родном!

Ну а коды olaf1, уже не раз тут появляющиеся - сложно понять и на Lua-шном языке. ;-) --/Artos

 

И, если интересует ответ на свой вопрос, то переведешь самостоятельно текст ниже:

1. Собственно код написан без синтаксических ошибок и не должен приводить к фатальным ошибкам при запуске игры. Но код очень абсурден, что уже показал _Призрак_, и может приводить к переполнению стека при постоянном использовании table.insert(respwan_npc,2,false) при вызовах.

2. Не знаю что за идея у тебя с 'timer', но если ее выкинуть, то вероятно должно получиться что-то в этом роде:

local respwan_table = {}
local timer = nil
local levels = {marsh= {x=-61.996055603027,y=0.92057931423187,z=293.67742919922} }

local respwan_npc = {
  ["mar_clear_sky_respawn_1"] = true,
  ["mar_clear_sky_respawn_2"] = true,
  ["mar_clear_sky_respawn_3"] = true,
}


function spwan()
  if db.actor:alive() == false then return end
  --[[ --/ абсурд! (nonsense!)
  if timer == nil then
    timer = level.get_time_hours() + math.random(3, 6)
    if timer > 23 then timer = timer - 24 end
  end
  if time_global() > timer then
    timer = nil
  --]]
    local level_name = level and level.name()
    local coordinates = levels[level_name]
    if coordinates then
      local pos = vector():set(coordinates.x, coordinates.y, coordinates.z)
      local lvi = db.actor:level_vertex_id()
      local gvi = db.actor:game_vertex_id()
      for section,flag in pairs(respwan_npc)do
        if flag == true then --/ если разрешен спавн
          local se_obj = alife():create(section, pos, lvi, gvi) --/ спавн НПС по координатам
          respwan_table[se_obj.id] = section --/ запоминаем ID и секцию заспавненного НПС
          respwan_npc[section] = false --/ ставим метку запрета повторного спавна
        end
      end
    end
  --end
  
  for id,section in pairs(respwan_table) do
    local obj = db.storage[id] and db.storage[id].object
    if not obj or obj:alive() == false then --/ если нет НПС или он мертв:
      respwan_npc[section] = true --/ метка разрешения спавнить
      respwan_table[id] = nil --/ чистка (clear)
    end
  end
end

 

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

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

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

Artos, привет. Извини, но возможно опять глупый вопрос. Не подскажешь, возможно ли организовать две таблички - аналоги db.storage , но что бы одна была сталкеров, а другая для мутантов?

Есть ли наработки по этому поводу что бы посмотреть?

 

Объясняю для чего мне это нужно. Для поиска сендера в новостях у меня используется перебор вида:

function GetStalkers(ThisObj,RadMin,RadMax,who)
    for k, v in pairs(db.storage) do
    local obj = level.object_by_id(k)
        if (obj) and (IsStalker(obj)) and (obj:alive()) and (obj:id() ~= who:id()) then
        local ComThisObj = ThisObj:character_community()
        local ComSender = obj:character_community()
        if CommunityChenalStatus(ComSender,1) then
            if (ComThisObj ~= ComSender)  then --Данным методом ищем  сталкера.
            if ValNpc(obj)~=true then --Отсекаем квестовых нпс
            local Pos = ThisObj:position()
            local Dist = Pos:distance_to(obj:position())
            if (Dist < RadMax) and (Dist > RadMin) then
                table.insert(StkLevelTbl, obj)
                end
                end
                end
                end
        end
end
end
function GiveStalker(ThisObj,RadMin,RadMax,who)
GetStalkers(ThisObj,RadMin,RadMax,who)
if next(StkLevelTbl)  then
local obj = StkLevelTbl[math.random(#StkLevelTbl)]
return obj
else 
return nil
end
end

 

 

Первая функция делает перебор - и заносит в табличку подходящие варианты по параметрам. Вторая выбирает рандомный( если же в первую внести

 

return obj

вместо

table.insert(StkLevelTbl, obj)

то мы вечно будем получать одного и того же нпс (в зависимости от радиуса , но практически одного и того же), а извлечение в таблицу и рандомный выбор - устраняют это) - Это на случай, если будет вопрос зачем столько таблиц. Но проблема в том, что в момент этого перебора идет нагрузка и игра на 0,1 сек - зависает (рывок такой получается), что есть не гуд.

 

У меня была идея, но опять неподкрепленная мат.частью:

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

1. если объект в оффе, то его взять мне не удается (А есть ли такой способ вообще)

2. не учитываются заспавненные в последующем через скрипт.

Т.е. эта идея провалилась с потрохами.

 

Теперь воникла идея с клоном db.storage, но :

 

1. Можно ли такое реализовать.

2. Стоит ли оно такого? Т.е. прекратятся ли рывки - насколько уменьшится нагрузка при переборе?

 

И вопрос на миллион - есть ли другие варианты? Или как можно снять нагрузку при переборе?

З.Ы. Мне не нужно готовых вариантов, я готов учиться - только ткните с чего начать?

 

Artos, Спасибо, все ясно. Буду пробовать.

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

Что-то кончается, что-то начинается...

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

Vano_Santuri, отдельные таблички для объектов 'сталкеры' и 'мутанты' давным давно применяются, например, в Zenobian-моде.

У себя в моде (ТЧ/ЧН) тоже давным давно использую подобное, причем и для всех серверных объектов организованы таблицы (сталкеры/монстры) и и для онлайновых свои (сталкеры/монстры/аномалии/вертушки/...). Бери и смотри ...

Честно говоря, ты по сути с новостями для ЗП изобретаешь велосипед. Может быть не все и не так, но в динамических новостях для ТЧ давным давно многое сделано, над чем ты сейчас бьешься. Почему бы не посмотреть и не взять то, что имеет смысл и оптимальность?

1. Про отдельные таблички уже говорил. Также, в купе с модулем оффлайн-алайф (иль вырезав из него) вполе реально иметь таблички неписей монстров и пр. по локациям, что дает возможность давать новости сканируя только таблицу нужной локации.

2. Рандомность для исключения повторяемости дело конечно хорошее ... но и не оптимальное. И на локации в нужном месте вполе может оказаться всего один-два подходящих сендера (что сведет на нет весь рандом), да и рандом то "повторяем".

Вполне можно организовать что-то типа спам-фильтра, т.е. запоминать одного-двух последних сендеров и их "повторять" только при необходимости.

3. Имена для сендеров также нет смысла вычислять каждый раз. Ведь они то никогда не изменяются для одного и того же непися - вот и определив один раз заносить в табличку и потом брать именно из нее.

4. Учитывая, что сталкера/монстры НЕ ракеты и их перемещение все же имеет конечные скорости - вполне можно сканировать таблички и запоминать координаты их расположения и прочие нужные параметры с некоторой дискретностью (не чаще 1 минуты, например, а то и реже), что разгрузит затратные ресурсы на твои скрипты.

 

Т.о., учитывая, что при загрузке игры все интересующие тебя онлайновые объекты (сталкеры/монстры) регистрируются в db.storage, да и серверные объекты не сложно из метода on_register рассовывать по нужным таблицам(локациям) - то собственно 50% (и даже более) нужных данных ты можешь получить сразу при старте.

И не следует зашориваться на db.storage, это все же именно таблица онлайновых объектов и "всех в одной куче". Ни что не мешает организовывать свои таблички по нужным тебе параметрам и их использовать.

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

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

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

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

Этот код предназначен для проверки respwan_npc второй позади = истинное, если он верен ему в таблице (respwan_table) NPC gespwant вплоть до уровня

 

, а затем положил обратно в таблице respwan_npc значение ложной

 

for npc,spwan in pairs(respwan_npc)do
    if spwan == true then
        respwan_table[alife():create("mar_clear_sky_respawn_1", pos, lvi, gvi).id] = true
        table.insert(respwan_npc,2,false)
    end
end

 

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

olaf1, оператор table.insert действительно кладет куда указываешь, но(!) все остальные имеющиеся позиции сдвигаются!

... и кладет каждый раз только значение (т.е. false) и твоя исходная таблица превращается в это:

respwan_npc = {
  ["mar_clear_sky_respawn_1"] = true,
  [2] = false,
  [3] = false,
  ...
  [NNN] = false,
  ["mar_clear_sky_respawn_2"] = true,
  ["mar_clear_sky_respawn_3"] = true,
}

Т.о. ты постоянно наращиваешь существующую таблицу новыми полями, не уничтожая прежние.

И использовать для неиндексированной таблицы подобное НЕЛЬЗЯ! Ведь в твоей таблице respwan_npc в качестве ключей идут секции для спавна НПС, а не упорядоченные индексы 1,2,3...

 

Советую почитать материалы по работе с неиндексированными таблицами и ограничения на использование как table.insert / table/remove, так и метода ipairs для таблиц, подобных твоей respwan_npc.

 

Выше, тебе как раз дан вариант, который проверяет значение для ключа-секции спавна НПС и, если оно 'true' - разрешается спавн и этот ключ (секция) помечаются значением 'false', что и исключит повторный спавн пока не изменится это значение.

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

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

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

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

О таблице всех нпс на локе, зачем? радиус алайфа ну совсем мизерный...

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

мой пример:
function GetSender(sType, oPos, oKiller)
    local oSender = nil
    if sType == "murder" then
        local iMinDist = 30
        local iMaxDist = 100
        for k,v in pairs(db.storage) do                
            local oTrav = level.object_by_id(k)    
            if oTrav and IsStalker(oTrav) and oTrav:character_community() ~= "actor" and not ExcludedNpcs(oTrav) then
                if xr_wounded.is_wounded(oTrav) == false and oTrav:alive() then
                    if oKiller then
                        if oTrav:id() ~= oKiller:id() then fGetSender = true end
                    else
                        fGetSender = true
                    end
                    if fGetSender then
                        local DiffDist = oPos:distance_to(oTrav:position())
                        if DiffDist < iMaxDist and DiffDist > iMinDist then
                            iMaxDist = DiffDist -- я об этом
                            oSender = oTrav
                        end    
                    end
                end    
            end
        end            
    end
    return oSender
end

 

 

ЗЫ это так же логичней/реалистичней, в плане нахождения реального сендера, в добавок - намного оптимальней

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

Изменено пользователем Viнt@rь
Ссылка на комментарий

Viнt@rь,

 

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

 

Да было дело давненько, с таблицами первый раз работал. Просто я тогда мало знал о свойствах объектов (родит, дочерные и т.п). В данный момент я практически все отрезал, совсем по другому замутил. Никогда не думал, что сначала делать алгоритм на бумажке куда полезнее, чем сразу печатать код... Но пока это все в разработке и играбельно будет не скоро...

 

Код твой заценил - теперь понятно, таким образом ты сокращаешь расстояние - неплохо. Я просто не думал о таком алгоритме. Сам придумал?

Но db.storage -- куча хлама, как сказал Artos.

Я все-таки сделаю себе пару табличек, и чтоб они так "размазано" апдейтились - будет чуток быстрее. Плюс можно будет использовать

 

for k=1,#tbl do 
local t=tbl[k]
end

 

Как я почитал - говорят быстрее будет. Нужно будет проверить...

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

Что-то кончается, что-то начинается...

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

Viнt@rь, Vano_Santuri в-первую очередь оптимизация определяется целями и заданными начальными условиями, а никак не "а вот у меня так, а тут так".

Viнt@rь, если ваши "новости" ограничиваются только смертями иль не только, но именно на текущей локации, то использование db.storage может быть и оправдано (зачем городить еще чего-то), но говорить об оптимизации НЕ стОит.

1. Даже многократное выпонение простенькой проверки: if oTrav and IsStalker(oTrav) ... все же лучше выполнять не 500 раз, а всего 100 (к примеру). Ведь подобное можно встретить еще в десятке скриптов ... и порою на том же апдейте ... Так зачем каждый раз проверять НЕ нужное???

2. Кто бы объяснил, ну зачем каждый раз вычислять и группировку и не принадлежность к актору и "не труп" и расстояние и т.п.? И все это делать единомоментно для всех подходящих по условиям неписей ...

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

Вспомните, что все(!) неписи имеют свои апдейты! Вспомнили?! Ну а теперь попробуйте сказать, что организовав один раз свою "новостную табличку" и (от)регистрируя в ней каждого НПС иль монстра по net_spawn/net_destroy и обновляя из уже готового для вас апдейта каждого непися в уже созданной табличке информацию и по координатам и по группировке и по "жив иль мертв" и т.п. вы не получите выигрыша? Ведь за вас движек уже распределяет собственно и процесс сканирования/апдейта и за вас актуализирует все нужные данные, не проверяя за раз всех оптом.

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

(это конечно только для онлайновых новостей иль подобного сгодится)

 

Ну и ... как ранее заметил Vano_Santuri, все же не стОит алгоритм загонять в жесткие рамки. Если у костра сидит с десяток сталкеров - то ближайший к некоей точке вне костра будет как правило только один - что на "реализЬм" новостей плохо сказывается, превращая этого "ближнего" в штатного корреспондента.

 

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

И ... я не говорил что: "db.storage -- куча хлама, но для конкретной задачи типа новостей от сталкеров, в db.storage действительно для данного алгоритма "куча ненужного хлама". Легко самим посмотреть, что при старте чистой ЗП за Затоне в db.storage более 700 объектов из которых неписей на порядок меньше.

(приписывая свои слова другому стОит это делать аккуратно)

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

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

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

Artos, а разве хранение всех данных о нпс в еще одной табличке не даст той же нагрузки, что и проверка? К тому же, как я сказал ранее, радиус алайфа ну черезвычайно маленький(сделать больше - будут лаги), а ведь только онлайновые нпс обновляются... К чему я веду, к тому, что нпс в онлайне на локации мало, а убийств/смертей нпс еще меньше, тоесть проверка выполняется вообще мизерное кол-во раз(правда если ГГ не начнет гамселить всех и вся:)), так зачем же тогда создавать и заполнять еще одну табличку... если можно получить НПС из стораджа и из него уже "вытянуть" инфу...

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

 

Ну и ... как ранее заметил Vano_Santuri, все же не стОит алгоритм загонять в жесткие рамки. Если у костра сидит с десяток сталкеров - то ближайший к некоей точке вне костра будет как правило только один - что на "реализЬм" новостей плохо сказывается, превращая этого "ближнего" в штатного корреспондента.

 

Лично у меня, в данном случае, это наблюдатель, для новостей типа видел/слышал, потому, такой вариант мне подходит, нет, даже больше, такой вариант для меня идеален :)

 

Сорри, чет понесло в оффтоп...

Изменено пользователем Viнt@rь
Ссылка на комментарий

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

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

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

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

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

Войти

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

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

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