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

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

ТЧ v 1.0005

О фонарике актера(ГГ) - пробую удалять его так:

local obj = db.actor:item_in_slot(9)
if obj then
    alife():release(alife():object(obj:id()), true)
end

или так

local obj = db.actor:object("device_torch")
if obj then
    alife():release(alife():object(obj:id()), true)
end

в результате - из 5-ти попыток 1-2 удачно, 3-4 вылет из игры. Что такого с этим долбаным фонариком - почему не удаляется нормально ?

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

AndreySol

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

Делая так:

local obj = db.actor:item_in_slot(9)
if obj then
  local se_obj = alife():object(obj:id()) --/ получаем серверный объект
  if se_obj then --/ серверный объект в игре?
    alife():release(se_obj, true) --/ удаляем
  end
end

- ты будешь иметь безопасный код для удаления.

 

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

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

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

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

Artos

Твоя заковыка в данном случае в том, что получая клиентский объект фонарика, ты по его признаку (ID) пытаешься удалять серверный объект, не проверив наличие его в игре

Я поправил код удаления - теперь фонарик вообще перестал удаляться. Его вообще нельзя удалить ? Или это надо как-то иначе делать ?

 

Ты нас тут за кашпировских принимаешь? Чтобы ответить "иль как иначе" необходимо видеть что ты у себя нагородил. --/Artos

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

AndreySol, ошибка многих в подобных твоему случаях в том, что:

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

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

2. При наличии у актора НЕ одного объекта поверяемого типа/класса, получение и удаление через db.actor:object("device_torch"), т.е. только по секции, не гарантирует удаление именно требуемого предмета (например, того, что в слоте) ...

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

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

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

Еще попробовал вариант с получением объекта фонарика через "iterate_inventory", результат тот-же.

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

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

Expression    : fatal error
Function      : CScriptEngine::lua_error
File          : E:\stalker\patch_1_0004\xr_3da\xrGame\script_engine.cpp
Line          : 73
Description   : <no expression>
Arguments     : LUA error: ...shadow of chernobyl2\gamedata\scripts\y_level.script:6: attempt to call global 'get_netpk' (a nil value)

Вот скрипт

function Tropa_Rostok()
  local story_id = 20017
  if not alife():story_object(story_id) then
    local position,lvid,gvid = vector():set(-253.30751037598,-19.407945632935,-154.47235107422),8672,8 --/ координаты перехода
    local soLvChg = alife():create("level_changer", position, lvid, gvid) --/ спавн перехода
    local pk = get_netpk(soLvChg) --/ запрос нет-пакета
    if pk:isOk() then --/ получен доступ к нет-пакету объекта?
      local data = pk:get() --/ читаем данные из нет-пакета
      data.story_id             = story_id
      --data.shapes:addSphere(3) --/ задаем форму сферы радиусом в 3м
      data.shapes:addBox(vector():set(3,0,0),vector():set(0,5,0),vector():set(0,0,3),vector():set(0,0,0))
      data.restrictor_type      = 3 --/ RestrictorTypeNone
      data.dest_level_name      = "marsh"
      data.dest_game_vertex_id  = 9
      data.dest_level_vertex_id = 6344
      data.dest_position        = vector():set(-259.36654663086,-18.755743026733,-160.60395812988)
      data.dest_direction       = vector():set(0.0,2.0,0.0)
      data.dest_graph_point     = 'start_actor_02'
      data.silent_mode          = 0
      --data.custom_data:setString("[pt_move_if_reject]\npath = "..path) --/ "точка возврата"
      pk:set(data) --/< запись в нет-пакет
      level.map_add_object_spot(obj.id, "level_changer", "")
      news_manager.send_tip(db.actor, "На Болота", nil, nil, 20000)
    end
  end
end

 

 

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

Daniar299, а читать readme кто будет?

Из m_netpk.txt:

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

а) local pk = get_netpk(obj,flag) -- по классу переданного объекта будет автоматически подобран нужный класс нет-пакета.

При прямых обращених к модулю и/или классу пакета:

б) local pk = m_netpk.get(obj,flag) -- аналогично а).

в) local pk = m_netpk.net_XXX(obj,flag) -- указываем КОНКРЕТНЫЙ класс (XXX) требуемого пакета, как подобрать, см. ниже

...

Подключение модуля в модификациях игры:

1) Скопировать m_netpk.script в папку скриптов установленной игры.

2) Скопированть m_netpk.ltx в папку конфигов игры.

3) (опционально) Для возможности использовать короткое имя 'get_netpk' для вызовов из различных скриптов:

Подключить первичную инициализацию модуля при старте игры для чего в скрипте _g.script

дописать строку в конце функции 'start_game_callback':

function start_game_callback()
     ...
     m_netpk.init() -- инициализация модуля
end

Т.о. если использование модуля m_netpk единичное и/или не хочется заморачиваться с правками в _g.script то и используй обычный (прямой) вызов:

m_netpk.get(soLvChg) --/ запрос нет-пакета

 

Примечание: Да и собственно саму свою функцию Tropa_Rostok() не обязательно выделять в отдельный y_level.script, а вполне можно в конец того же gulag_escape.script дописать ... Скрипт y_level нужен был при старом варианте кодов (by antreg).

 

 

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

AndreySol, повторю, что по даже по куцим упоминаниям о CUIScriptWnd, но не видя конкретных кодов, можно только гадать.

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

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

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

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

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

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

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

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

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

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

 

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

AndreySol, мне совершенно не хочется видеть чьи-то коды, если это не необходимо для ответов на не мои же вопросы ... (уже насмотрелся любых кодов)

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

Мне уже видеть коды абсолютно не к чему, и этот вопрос и ответ на него - более не интересен.

 

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

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

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

Наверно уже обсуждалось, но можно ли, используя level.main_input_reciver(), получить доступ к интерфейсу инвенторя, а конкретно к сетке. на которой находятся иконки предметов. Цель - необходимо перекрасить в игре иконку нужного предмета, например придать ей красный оттенок. Такое возможно?

 

Или же такой вопрос, можно ли в ТЧ\ЧН делать инвентарный предмет "не продаваемым", аналог can_trade = false из конфигов, чтобы предмет при торговле был выделен красным и не продавался. Только делать это надо скриптами, и для конкретного предмета, а не для всех предметов данной секции.

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

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

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

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

Похоже отсутствие ответов на вопрос *Shoker*'а говорит о том, что готового варианта нет и даже боле-менее разумного тоже ...

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

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

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

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

*Shoker*,

Наверно уже обсуждалось, но можно ли, используя level.main_input_reciver(), получить доступ к интерфейсу инвенторя, а конкретно к сетке. на которой находятся иконки предметов. Цель - необходимо перекрасить в игре иконку нужного предмета, например придать ей красный оттенок. Такое возможно?

 

Или же такой вопрос, можно ли в ТЧ\ЧН делать инвентарный предмет "не продаваемым", аналог can_trade = false из конфигов, чтобы предмет при торговле был выделен красным и не продавался. Только делать это надо скриптами, и для конкретного предмета, а не для всех предметов данной секции.

По второму вопросу, есть такие средства в проекте x-ray extensions. По-первому не уверен, но кажется SkyLoader добавил что-то в этом духе.

В чистом движке таких возможностей нет.

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

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

В последнем (r24) варианте x-ray extensions SkyLoader добавил билдовскую фичу в окнах торговли - подцветка (зелененьким фоном) для предметов, которые находятся в слотах (включая пояс). Подцвечиваются любые предметы в слотах, а не заданные по каким-то параметрам и не подцвечиваются находящиеся просто в рюкзаке.

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

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

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

Добрый день!

Подскажите, пожалуйста,

есть такие простые функции для спавна и удаления предметов (объектов) из инвентаря актёра

:

--Универсальная рабочая функция удаления предмета из инвентаря
function delete_object(section,obj)
       if obj== nil then obj = db.actor end
        local item= obj:object(section)
        if item then 
        local seobj = alife():obect(item:id())
        if seobj then 
        alife():release(seobj)
        end
    end
end

--Сама функция удаления конкретного предмета
function delete_fotik()
this.delete_object("wpn_foto")
end

--Функция спавна предмета в инвентарь
function spawn_fotik()
local obj=alife():create("wpn_foto", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id())
end

 

Функции прекрасно работают с любым итемом или оружием, но как только пытаемся проделать теже манипуляции с device_torch, то сразу вылет с аргументом на неправильное задание объекта в функции. Видимо device_torch не является обычным объектом для инвентаря. Есть какое-то решение по данному вопросу?

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

antreg, как и AndreySol (читай чуть выше), гадаешь сам и заставляешь гадать других ...

Ну и где в твоих приведенных функциях может выскакивать "сразу вылет с аргументом на неправильное задание объекта в функции", если оперируешь секцией?

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

Повторю, ничем фонарики не отличаются от других инвентарных предметов, кроме того, что аттачатся в "фонарный" слот, и их спавн/удаление ничем не отличаются от удаления надетого костюма иль ножа.

 

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

Вот вам пример кода (из ТЧ), в котором фонарик добавляется/удаляется при одевании/снятии костюма (чтобы не светил на "голом" лбу):

function Check_Actors_Torch() --/ вызывается раз в секунду из апдейта актора
  local oActor = db.actor
  if oActor then --/ актор в игре?
    if oActor:get_current_outfit() then --/ на акторе одет костюм?
      local oTorch = oActor:item_in_slot(9)
      if not oTorch then --/ у актора нет фонарика в слоте?
        oTorch = oActor:object("device_torch")
        if oTorch then --/ у актора есть фонарик в рюкзаке?
          oActor:transfer_item(oTorch,oActor) --/ перекладываем в слот
        else --/ спавним новый фонарик в инвентарь (в слот сам попадет)
          alife():create( "device_torch", oActor:position(), oActor:level_vertex_id(), oActor:game_vertex_id(), oActor:id() )
        end
      end
    else --/ актор без костюма:
      local oTorch = oActor:item_in_slot(9)
      if oTorch then --/ если есть у актора фонарик в слоте:
        local soTorch = alife():object(oTorch:id())
        if soTorch then --/ серверный объект фонарика в игре?
          alife():release(soTorch,true) --/ удаляем "слотовый" фонарик
        end
      end
    end
  end
end

- и ни разу данная функция не вызывала ошибок/вылетов.

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

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

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

Пытаюсь адаптировать схему рестриктора по мод.Но правильно ли я написал код таймера для эффектов?

class "action_poltergeist"

function action_poltergeist:__init(obj, storage)
self.actor_inside = false
self.timer_atacks = 0
end

function action_poltergeist:update(delta)
        if not db.actor:alive() then return end

    if xr_logic.try_switch_to_another_section(self.object, self.st, db.actor) then
        return
    end

        self.actor_inside = self.object:inside(db.actor:position())

    local time = time_global()

        -- Актор в зоне.Нужно отыграть спецэффекты
        if self.actor_inside == true and (self.timer_atacks or 0) < time then
                self.play_sounds()
                self.update_hit()
        ogse.spawn_phantom()
            level.add_pp_effector("psi.ppe", 10222, true)
            self.timer_atacks = time + 18000
        else
               self.timer_atacks = false
    level.remove_pp_effector(10222)
        end

end

function action_poltergeist:play_sounds()
    local iRandom = math.random(1, 8)
    local sSound = [[ambient\under\fear_sound_25]]
    if iRandom == 1 then 
        sSound = [[ambient\under\fear_sound_10]]
    elseif iRandom == 2 then
        sSound = [[ambient\under\fear_sound_2]]
    elseif iRandom == 3 then
        sSound = [[ambient\under\fear_sound_7]]
    elseif iRandom == 4 then
        sSound = [[ambient\under\fear_sound_9]]
        elseif iRandom == 5 then
        sSound = [[ambient\under\fear_sound_16]]
    elseif iRandom == 6 then
        sSound = [[ambient\under\fear_sound_20]]
    elseif iRandom == 7 then
        sSound = [[ambient\under\fear_sound_24]]
        elseif iRandom == 8 then
        sSound = [[ambient\ugrnd\ugrnd_whispers_2]]
    end
    ogse.PlaySound(sSound)
end

function action_poltergeist:update_hit()
    local h = hit()
    h.power = 0.02
    h.direction = vector():set(0, 0, 0)
    h.impulse = 0
    h.draftsman = db.actor
    h.type = hit.telepatic
    db.actor:hit(h)
end

function add_to_binder(obj, ini, scheme, section, storage)
    local new_action = action_poltergeist(obj, storage)
    xr_logic.subscribe_action_for_events(obj, storage, new_action)
end

function set_scheme(obj, ini, scheme, section, gulag_name)
    local st = xr_logic.assign_storage_and_bind(obj, ini, scheme, section)
    st.logic = xr_logic.cfg_get_switch_conditions(ini, section, obj)
end

 

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

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

Хоть и не в тему, но позволь дать один небольшой совет...

Метод play_sounds уж больно у тебя громоздкий и достаточно расточительный. Все твои проверки можно уместить в две строки:

function action_poltergeist:play_sounds()
    local sSound = [[ambient\under\fear_sound_0]]..math.random(8)
    ogse.PlaySound(sSound)
end

При одном маленьком условии: переименуй название твоих .ogg файлов эквивалентно следующей таблице:

[[ambient\under\fear_sound_25]]       -> [[fear_sound_00]]
[[ambient\under\fear_sound_10]]       -> [[fear_sound_01]]
[[ambient\under\fear_sound_2]]        -> [[fear_sound_02]]
[[ambient\under\fear_sound_7]]        -> [[fear_sound_03]]
[[ambient\under\fear_sound_9]]        -> [[fear_sound_04]]
[[ambient\under\fear_sound_16]]       -> [[fear_sound_05]]
[[ambient\under\fear_sound_20]]       -> [[fear_sound_06]]
[[ambient\under\fear_sound_24]]       -> [[fear_sound_07]]
[[ambient\ugrnd\ugrnd_whispers_2]]    -> [[fear_sound_08]]

Ну и положи их в одну папку.

P.S. Кстати, в твоём случае файл fear_sound_25, никогда проигрываться не будет, поскольку ниже по коду его "затрёт" один из вариантов.

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

panzyuza

По таймеру: сделано неправильно. При таком варианте и излишние вычисления и если актор вне зоны, то будет постоянно "вырубаться" эффект.

Если же в зоне, то как только включится эффект и будет запущен таймер - тут же на следующем апдейте из-за таймера же и выключится. И так по циклу ...

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

Попробуй самостоятельно поправить ошибки и после проверь, не так ли у тебя получилось:

function action_poltergeist:__init(obj, storage)
  self.timer_atacks = 0
end

function action_poltergeist:update(delta)
  if not db.actor:alive() then return end
  if xr_logic.try_switch_to_another_section(self.object, self.st, db.actor) then
    return
  end
  -- Актор в зоне.Нужно отыграть спецэффекты
  if self.actor_inside = self.object:inside(db.actor:position()) then --/ актор в зоне?
    if self.timer_atacks < time_global() then --/ ожидание закончилось?
      self.timer_atacks = time_global() + 18000 --/ обновляем период ожидания (~18sec)
      self.play_sounds()
      self.update_hit()
      ogse.spawn_phantom()
      if not self.play_pp_effector then --/ эффект не запущен?
        level.add_pp_effector("psi.ppe", 10222, true)
        self.play_pp_effector = true --/ флаг о запущенном эффекте
      end
    end
  elseif self.pp_effect_played then --/ актор вне зоны и проигрывается эфект?
    level.remove_pp_effector(10222)
    self.play_pp_effector = nl --/ сброс флага дабы не выключать постоянно
  end
end

Эффект включается один раз при каждом вхождении актора в зону, а музон и фантомы - каждый 18 секунд пока актор в зоне.

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

 

(подправил немного)

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

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

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

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

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

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

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

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

Войти

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

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

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