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

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

В дополнение к теме телепорта на другую локацию.

 

Значит я через acdc скомпилировал спавн, в который добавил новую локацию (пещера из солянки). Нужно сделать так, чтобы после диалога спавн происходил именно на этой локации (пещера). Сейчас имею ровно обратную картину: актор телепортируется на другую точку кордона, а все обьекты из локации "пещера" спавнятся на кордоне.

 

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

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

@Rod_K Что бы не потрошить спаун, воспользуйся скриптовым ЛЧ. Если новая локация добавлена без косяков, всё отработает хорошо.

Под спойлером ф-ии спавна и удаления ЛЧ. Для примера - телепорт в комнату Бармена. Вызываешь спавн/удаление в удобных тебе местах.

Скрытый текст

-- Аргумент info для фикса телепортации Кордон-ТД
function start_level_changer(p_dest_pos, p_dest_lv, p_dest_gv, p_dest_level, info)

    -- Перед созданием ЛЧ выдём инфо, если необходимо
    if info ~= nil then
        if not has_alife_info(info) then 
            db.actor:give_info_portion(info) 
        end
    end

    local obj = alife():create("level_changer", db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id())
    local packet = net_packet()
    obj:STATE_Write(packet)
    -- свойства cse_alife_object
    local game_vertex_id     = packet:r_u16()
    local distance           = packet:r_float()
    local direct_control     = packet:r_u32()
    local level_vertex_id    = packet:r_u32()
    local object_flags       = packet:r_u32()
    local custom_data        = packet:r_stringZ()
    local story_id           = packet:r_u32()
    local spawn_story_id     = packet:r_u32()
    -- свойства cse_shape
    local shape_count = packet:r_u8()
    for i = 1, shape_count do
        local shape_type = packet:r_u8()
        if shape_type == 0 then
            -- sphere
            local center = packet:r_vec3()
            local radius = packet:r_float()
        else
            -- box
            local axis_x                = packet:r_vec3()
            local axis_y                = packet:r_vec3()
            local axis_z                = packet:r_vec3()
            local offset                = packet:r_vec3()
        end
    end
    -- свойства cse_alife_space_restrictor
    local restrictor_type             = packet:r_u8()
    -- свойства cse_alife_level_changer
    local dest_game_vertex_id        = packet:r_u16()  
    local dest_level_vertex_id         = packet:r_u32()  
    local dest_position             = packet:r_vec3()
    local dest_direction             = packet:r_vec3()
    local dest_level_name             = packet:r_stringZ()
    local dest_graph_point             = packet:r_stringZ()
    local silent_mode                 = packet:r_u8()
 
    packet:w_begin(game_vertex_id)
    packet:w_float(distance)
    packet:w_u32(direct_control) 
    packet:w_u32(level_vertex_id)
    packet:w_u32( bit_not(193) )
    packet:w_stringZ(custom_data)
    packet:w_u32(46489)
    packet:w_u32(46489)
    packet:w_u8(1)
    packet:w_u8(0)
    packet:w_vec3(vector():set(0, 0, 0))
    packet:w_float(2)
    packet:w_u8(3)
    packet:w_u16(p_dest_gv)
    packet:w_u32(p_dest_lv)    
    packet:w_vec3(p_dest_pos)
    packet:w_vec3(vector():set(0, 0, 0))
    packet:w_stringZ(p_dest_level)
    packet:w_stringZ("start_actor_99")
    packet:w_u8(1)
    packet:r_seek(0)
    
    obj:STATE_Read(packet, packet:w_tell())
end

local disposition

function teleport_bar_vip_room() 
    disposition = vector():set(114.89195251465,-5.3071584701538,14.840103149414)
    if level.name()~="l05_bar" then
        start_level_changer(disposition, 33615, 1239, "l05_bar")
    else
        db.actor:set_actor_position(disposition)
    end    
end

function Del_LevelChanger()
  local LV = alife():story_object(46489)
    if LV then                                           
        alife():release(LV, true)                                     
    end
end

 

Изменено пользователем mole venomous
  • Согласен 1
  • Полезно 2

Здесь могла быть ваша реклама.

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

Я в очередной раз напомню, что вот так, как в выше приведённом примере, делать не нужно. Не нужно закатывать солнце в ручную, нужно использовать m_netpk.

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

Столкнулся со странной загадкой в плане кондишена оружия.

Пример: имеем у себя любое оружие - my_wpn.

Загружаем игру. СТРЕЛЯЕМ из него несколько раз, чтобы подпортить его кондишн.

Берём клиентский объект этого оружия (у примеру у нас автомат в слоте):

cl_wpn = db.actor:item_in_slot(inventory_slots.RIFLE)

Читаем кондишн:

cl_cond=cl_wpn:condition() -- получаем 0.80 (к примеру)

берём серверный объект:

s_wpn = server_object(cl_wpn:id())

вычисляем его кондишн:

local pk = m_netpk.get(s_wpn, 1)
local data = pk:get()
local s_cond=data.condition

получаем 0.81 (!)

ИМЕЕМ РАЗНИЦУ (доходит до ~ 0,15%).

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

Правим вручную серверную кондицию, приводя её к величине клиентской:

data.condition=cl_cond

pk:set(data)

Если теперь снова прочитать клиентскую и серверную кондиции, то они будут равны!

НО! Сохраняем игру и тут же загружаем. Читаем кондиции. И снова имеем эту разницу (уже не стреляя), 

КАК БУДТО МЫ НЕ МЕНЯЛИ СЕРВЕРНУЮ КОНДИЦИЮ!

 

Извините за многобукв, постарался попонятнее.

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

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

@phalcor если я не ошибаюсь, у тебя ОП-2.1, в котором собственный движок и исходников его нет. Кто знает, что они там наворотили.

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

@phalcor Дело в том, что движок передает (от клиентского объекта к серверному), и сохраняет в сейве состояние через апдейт пакет в сжатом виде (u8, то есть всего 256 позиций). Отсюда и погрешность.

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

  • Спасибо 1
  • Полезно 2
Ссылка на комментарий
4 минуты назад, Bak сказал(а):

В качестве решения можно завести собственный скриптовый метод сохранения состояния.

Ну да, сделал я скриптовые костылики: при сохранении формирую табличку кондиций оружия актора, а при load - применяю её. Или есть способ элегантней?

  • Нравится 1
Ссылка на комментарий
19 минут назад, phalcor сказал(а):

есть способ элегантней?

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

  • Спасибо 1
  • Полезно 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.

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

Не нахожу поиском или туплю. В ТЧ есть скриптовый метод проверки ГГ на кровотечение? Задумал тут перетащить медиков из ЗП...

    if  db.actor.bleeding > 0 then -такая проверка вообще возможна в ТЧ?

Ну и сам скрипт лечения:

function medic_magic_potion(first_speaker, second_speaker)
    db.actor.health = 1
    db.actor.power = 1
    db.actor.radiation = -1
    db.actor.bleeding = 1
end

Будет ли работать в ТЧ? Где подсмотреть?

Ссылка на комментарий
Только что, Капрал Хикс сказал(а):

Будет ли работать в ТЧ?

Без правок движка - нет, не будет.

Только что, Капрал Хикс сказал(а):

 db.actor.bleeding = 1

Потому что нет такого на запись, в оригинальном ТЧ.

На чтение тоже несколько иначе. db.actor:get_bleeding() возвращает float от 0 до... существенно более единицы возможно.

Изменено пользователем Zander_driver
  • Спасибо 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.

Ссылка на комментарий
23 минуты назад, Капрал Хикс сказал(а):

db.actor.bleeding

Нет такого свойства. Да и зачем тебе именно кровотечение, попробуй

bool wounded() -- состояние ранености

void wounded(boolean) -- изменить состояние ранености

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

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

А это ничего, что "раненность" изменяется в диапазоне несколько более сложном, чем "вкл/выкл" ? :crazy2:

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

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

@AndreySol @Zander_driver , я тут поразмыслил, и понял, что лучше всего использовать банальную проверку на состояние здоровья ГГ <1.0 (ну и радиации). Ведь если у ГГ есть кровотечение, то здоровье всё равно будет ниже единицы?

А насчёт записи состояния кровотечения - в x-ray extension вроде добавлен метод:

// CEntityAlive
heal_wounds(float)

Кстати, в R.M.A. по идее он должен работать, только как правильно вызвать функцию остановки кровотечения?

Изменено пользователем Капрал Хикс
Ссылка на комментарий
2 часа назад, Капрал Хикс сказал(а):

то здоровье всё равно будет ниже единицы?

Например от голода - разве это признак ранения? Костыли, скорее всего, не помогут, а что там в x-ray extension накрутили - надо в описании и читать.

  • Полезно 1
Ссылка на комментарий
12 минут назад, AndreySol сказал(а):

Например от голода - разве это признак ранения?

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

 

15 минут назад, AndreySol сказал(а):

что там в x-ray extension накрутили - надо в описании и читать.

// CEntityAlive
heal_wounds(float)

- там вот так и описано, что-де добавлен метод такой.

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

Решил сделать горячие кнопки на установку/снятие глушителя для оружия в активном слоте.

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

В очень усечённом виде это выглядит так:

local w = db.actor:active_item() --активный ствол
local w_sect=w:section()
if w:has_silencer() then				
	local addon_sect=w:detach_silencer(true) --ph: false - снятый глушитель исчезает, true - попадает в инвентарь
end

Установка: а вот тут возникла проблемка. Имеется такой метод установки  глушителя:

weapon:attach_silencer(sil)  --здесь sil - имя секции глушителя.

При этом устанавливается вновь заспавненный глушитель. Мне же нужно

или - 1)  брать уже имеющийся из инвентаря 

или - 2)  менять condition на установленном указанным выше методом, а из инвентаря соответственно просто удалять

Есть ли методы для вариантов 1 или 2? 

 

 

 

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

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

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

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

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

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

Войти

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

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

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