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

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

Спасибо за ответы! По-ржал от души! 

Знаете, чем отличаются американские форумы от русских?

На американском форуме задаёшь вопрос - все пытаются тебе помочь.

На русском  - при ответе на вопрос, все начинаются мериться своими .... познаниями.

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

 

Вообще-то вопросы  были не про хранение переменных, а немного о другом:

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

2.Почему при спавне 63-го объекта - движок "не видит" отдельный файл в папке Scripts???

Итак, ты удалил alife():release из STATE_Read?

Добавил обработку, чтобы у тебя данные грузились не 62 раза, а 1 раз?

Если нет, проверил ли ты скрипты, в которых вызывается загрузка, что они нормально переживают загрузку 62 раза?

 

Дело вообще не объектах, а в твоих скриптах.

Слушай отвечающих. Тот же Zander_driver сказал весьма по делу.

Изменено пользователем abramcumner
  • Нравится 2
Ссылка на комментарий
Эка несуразность.
Ну хорошо, вот придумали разрабы кондлист, в котором кондишены заключили в скобки,
а экшены в проценты. Пока нормально. Но почему-то распарсивают 'find'-ом и 'sub'-ом.
Первое что мне например пришло в голову - это паттерн '%b', который как раз и ищет
строки заключенные в указанные символы.
В результате можно записать проще и понятнее. Напр.
function parse_condlist(npc, section, field, src)
    local t = {}
    local n = 0
    
    for w in string.gmatch(src,'[^,]+') do
        n = n + 1
        t[n] = {infop_check = {}, infop_set = {}}
        
        local before, infop, after = w:match('^(.-)(%b{})(.-)$')
        
        if infop then
            parse_infop(t[n].infop_check, infop:match('{(.-)}'))
            w = before .. after
        end
        
        before, infop, after = w:match('^(.-)(%b%%)(.-)$')
        
        if infop then
            parse_infop(t[n].infop_set, infop:match('%%(.-)%%'))
            w = before .. after
        end
        
        t[n].section = w:match('%S+') or ''
    end
    
    return t
end

 

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

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

 

function parse_condlist1( src )
    local t, n = {}, 0
    local s1, s2, s3, ic, is
    for s in string_gfind( src, "%s*([^,]+)" ) do    -- разбиваем на разделенные запятыми части
        -- Здесь s это набор info в {} и имя секции, на которую переключиться
        ic, is = {}, {}    -- "+infop1 -infop2 +infop3 ..." -> { "infop_name" = true/false }

        s1, s2, s3 = string_match( s, "([^{]*){([^}]+)}(.*)" )    -- Выделяем список info для проверки
        if s2 then parse_infop( ic, s2 ); s = s1 .. s3 end

        -- куда переключаемся, и какие info ставим/убираем, в произвольном порядке
        s1, s2, s3 = string_match( s, "([^%%]*)%%([^%%]+)%%(.*)" )    -- список info для установки
        if s2 then parse_infop( is, s2 ); s = s1 .. s3 end    -- s - имя секции

        n = n + 1
        t[n] = { ["section"] = string_match( s, "%s*(.*)" ), ["infop_check"] = ic, ["infop_set"] = is }
    end
    return t
end

 

 

Или у тебя сейчас только руки дошли ?

 

P.S. Кстати, один аргумент, по тому что прочее здесь и куче других мест скрипта вполне бессмысленны - просто не срабатывают, а в части случаев и не могут быть переданы в принципе.

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

лучше б parse_infop до ума довести. Я сделал на скорую руку, но это так - временно:

 

 function parse_infop1( rslt, str )
	if str then
		local infop_name, sign
		local infop_n = 1
		for s in string_gfind( str, "%s*([%-%+%~%=%!][^%-%+%~%=%!%s]+)%s*" ) do
			sign = string_sub( s, 1, 1 )
			infop_name = string_sub( s, 2 )
			if sign == "+" then rslt[infop_n] = { name = infop_name, required = true }
			elseif sign == "-" then rslt[infop_n] = { name = infop_name, required = false }
			elseif sign == "~" then rslt[infop_n] = { prob = tonumber( infop_name ) }
			elseif sign == "=" then rslt[infop_n] = { func = infop_name, expected = true }
			elseif sign == "!" then rslt[infop_n] = { func = infop_name, expected = false }
			else abort( "parse_infop1, invalid condlist, %s", str )
			end
			infop_n = infop_n + 1
	end	end
end

 

 

И, самое главное, try_switch_to_another_section() c pick_section_from_condlist() - вот где ахтунг-то..

Почти все остальное у меня вылизано.

 

upd: короче, в прозекторскую текущую недоделку закинул. Может, совместно чего допилим до человеческого вида.

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

pick_section_from_condlist я пока сделал так (особо не вдавался в подробности)

 

function pick_section_from_condlist(actor, npc, condlist)
    local rval
    
    for n, cond in pairs(condlist) do
        local infop_conditions_met = true -- изначально считаем, что все условия переключения удовлетворены
        
        for inum, infop in pairs(cond.infop_check) do
            if infop.prob then 
                rval = rval or math.random(100)
                infop_conditions_met = (infop.prob < rval)
            elseif infop.func then
                local func = xr_conditions[infop.func]
                if not func then
                    abort("object '%s': pick_section_from_condlist: function '%s' is " ..
                        "not defined in xr_conditions.script", npc:name(), infop.func)
                end
                
                infop_conditions_met = (func(actor, npc, infop.params) == infop.expected)
            else
                infop_conditions_met = (has_alife_info(infop.name) == infop.required)
            end
            
            if not infop_conditions_met then
                break
            end
        end
        
        if infop_conditions_met then
            local a = db.actor
            -- Условия выполнены. Независимо от того, задана ли секция, нужно проставить требуемые infoportions:
            for inum, infop in pairs(cond.infop_set) do
                if not a then
                    abort("TRYING TO SET INFOS THEN ACTOR IS NIL")
                end
                
                local func_name = infop.func
                
                if func_name then
                    local func = xr_effects[func_name]
                                            or
                                 abort("object '%s': pick_section_from_condlist: function '%s' " ..
                                 "is not defined in xr_effects.script",
                                 if_then_else(npc, npc:name(), "nil"), func_name)
                    
                    func(actor, npc, infop.params)
                else
                    local info = has_alife_info(infop.name)
                    
                    if infop.required and not info then
                        actor:give_info_portion(infop.name)
                    elseif not infop.required and info then
                        actor:disable_info_portion(infop.name)
                    end
                end
            end
            
            local sec = cond.section
            return sec ~= "never" and sec or nil
        end
    end
    
    return nil
end 

 

Ну а остальное нужно смотреть

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

Уважаемые, каким образом можно получить список НПС вокруг ГГ, аналогично цифре на худе? очень не хочется писать for i,65535... 

Благодарю за информацию!

  • Полезно 1
Ссылка на комментарий

 

 

Уважаемые, каким образом можно получить список НПС вокруг ГГ

смотри примеры в ПЫС скриптах, реализаций такого дочерта там...

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

 

 

ПЫС скриптах
- например? хоть приблизительно, либо ключевое слово :) . я собственно сделал, но все равно приходится перебирать лишние данные. как я смог выяснить, какой то структуры данный, доступной для lua , которая хранит нпс "рядом" (это "рядом" на основе некоего параметра)  - нет. Судя по всему - она есть, но только для движка, он же рисует на худе как то количество НПС.
Ссылка на комментарий

@Winsor, что-то вроде этого:

local npc
local aPos = db.actor:position()
local npc_online = {}
for k,v in pairs(db.storage) do
  npc = level.object_by_id(k)
  if npc and isStalker(npc) and npc:alive() and aPos:distance_to(npc:position())<50 then
    npc_online[k] = npc
  end
end
  • Спасибо 1

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

naxac.gif

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

@Winsor, ну а кто мешает сократить этот список так, чтобы он содержал только сталкеров? Точнее, добавить ещё один.

Могу сказать про ЧН, но в ТЧ должно быть что-то аналогичное. В ЧН объекты добавляются в db функцией db.add_obj(), которая вызывается из motivator_binder:net_spawn(sobject).
Надо всего лишь добавить в db ещё одну таблицу (например, db.stalkers), а в add_obj добавить проверку isStalker() и если она вернёт true - вставлять запись в новую таблицу (и в общую по-прежнему тоже).

Таким образом сокращение размера выборки произойдёт уже на стадии загрузки (и/или спавна нового объекта), то есть заранее.
А потом в функции, которую привёл выше @naxac, делать перебор по этой таблице, а не по общей.

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

@Winsor, на самом деле лучше сделать как, смотри, в storage хранится куча всяко-разного, это довольно большая таблица в которую на протяжении "жизни" объекта пишется все и вся, доступ идет по айди, что как ни крути в принципе неплохо. По этому в неокторых модах ты можешь видеть таблицу creatures (db.creatures), кто туда заносится ясно из названия, посему воспользуйся советом Киргуду, и заведи несколько массивов monster, stalkers... куда пиши только айди, а все данные будешь черпать из storage по ним без всякого перебора, если надо, а для дистанции и это вовсе не надо :).


@naxac, v можно опустить, for k in...

  • Спасибо 1
  • Согласен 1
Ссылка на комментарий

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

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

update-часть нетпакета оружия:

      {
      [KEY:  STRING:num_items] = VALUE:  NUMBER:0;
      [KEY:  STRING:ammo_type] = VALUE:  NUMBER:0;
      [KEY:  STRING:weapon_state] = VALUE:  NUMBER:0;
      [KEY:  STRING:condition] = VALUE:  NUMBER:255;
      [KEY:  STRING:weapon_flags] = VALUE:  NUMBER:0;
      [KEY:  STRING:current_fire_mode] = VALUE:  NUMBER:0;
      [KEY:  STRING:weapon_zoom] = VALUE:  NUMBER:0;
      [KEY:  STRING:ammo_elapsed] = VALUE:  NUMBER:1;
      [KEY:  STRING:addon_flags] = VALUE:  NUMBER:0;
      }

Для чего предназначены ключи num_items, weapon_flags, weapon_zoom?

  • Нравится 1

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

weapon_flags - оружие спрятано/взято в руки (0/1).

weapon_zoom - режим обычный/прицеливание (0/1).

num_items - точно не скажу, но вроде бы от значения этого параметра зависит дальнейший состав нет-пакета. То есть если там 0 - дальше следуют как раз оружейные параметры. Если не 0 - перед оружейными параметрами идёт ещё update-часть от cse_alife_inventory_item.

Как-то так.

 

Upd: насчёт доп. свойств нет-пакета при num_items ~= 0 были упоминания пару лет назад, например здесь: http://www.amk-team.ru/forum/index.php?showtopic=6185&p=727594

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

ТЧ 1.0006 + НС

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

local action=manager:action(xr_actions_id.stohe_kamp_base + 3) --xr_kamp.action_go_position
action:add_precondition(world_property(ev_see_box_id,false))
local action=manager:action(xr_actions_id.stohe_kamp_base + 1) --xr_kamp.action_wait
action:add_precondition(world_property(ev_see_box_id,false))
ev_see_box_id - айди моего эвалуатора, который возвращается true если ящик доступен для действия,  костер все равно не отпускает НПС, и его несчастного начинает кидать от костра и обратно. Насколько я себе представляю - необходимо повысить приоритет моего эвалуатора в xr_kamp. каким образом это можно сделать, чтобы костер временно отпускал НПС?
Благодарю за разъяснения!
Ссылка на комментарий

Добрый день, камрады!

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

При использовании se_stor от Артоса.

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

Для меня это тёмный лес, модуль Артоса я подключить ещё смог в своё время, а дальше затык. Я честно признаюсь, что я "моддер-солянщик", знания скриптов на уровне WinMerge и if/then.

Считаю, что разбор проблемы с примерами кода (если решение возможно, конечно) помог бы не только мне.

---------------------------------

www.amk-zone.de

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

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

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

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

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

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

Войти

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

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

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