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

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

Руководствуясь информацией из сообщения №3989

Для актора нужно проверять параметр нет-пакета: torch_flags (что даст информацию и по активности ПНВ) и если нужно изменять (управлять вкл/выкл)

провел серию экспериментов и выяснил следующее.

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

function Torch()
    local obj_torch = db.actor:item_in_slot(9)
    if obj_torch==nil then return end
    local se_obj = alife():object(obj_torch:id())
    if se_obj then 
        local pk = m_netpk.get(se_obj) 
        if pk:isOk() then
            local data = pk:get() 
            if data and data.upd and data.upd.torch_flags then
                local msg = string.format("%d", data.upd.torch_flags)
                news_manager.send_tip(db.actor, msg, nil, nil, 30000)
                data.upd.torch_flags=7    -- попытка включить принудительно
                pk:set(data)
            end
        end
    end
end

 

Заранее благодарен.

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

boryan67, плз, используй для кодов спойлер...

 

Тонкостей у сего девайса ниеаких нет, а вот о тонкостях касаемых любого подобного действия многие забывают.

1. В игре имеются для (почти) каждого предмета, непися и т.п. имеется по сути два об'екта - серверный и клиентский. Эти два об'екта синхронизируются между собою (обмениваются информацией) ... в каких-то ситуациях автоматически (движком), в каких-то требуется ручная синхронизация. Операции с нет-пакетами доступны только для серверных об'ектов!

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

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

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

А вообще, выключить фонарик/ПНВ таким образом вполне не сложно, а вот включить ... тут как то не пробовал (за ненадобностью).

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

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

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

Доброго времени суток.

 

Есть ли способ у убитого сталкера обратно включить фонарик ?

Специально убрал удаление фонарика у сталкеров -- в трупе вижу "очки".

Добавил код в хвост функции death_manager.on_death

    local torch = npc:object("device_torch")
    get_console():execute("load ~~~ [death_manager] "..npc:name().." torch "..tostring(torch ~= nil))
    if torch then
        torch:enable_attachable_item(true)
    end

 

Не срабатывает.

 

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

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

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

 

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

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

что делать со скриптом фриплея если во время него я немогу попасть на базу долга (якобы я не имею пока права попасть к Ворониниу)?? cit_fail_first_task ---- может эта инфопорция мешает??? Кто может помочь напишите пожалуйста в ЛС.

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

Анимация запрещена.

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

В схему влез, у трупа фонарик не тушится и схема не дёргается. В xr_motivator:death_callback вызов схемы убрал. Похоже, что у трупов все аттачи "отваливаются" и не работают.

Ссылка на комментарий
sapsan, Skyloader делал так, что у мертвых НПС горели фонарики, а вот как он это сделал сказать не могу (вроде другой фонарик сделал). Лучше поинтересоваться у него.
Ссылка на комментарий

Рассмотрим содержимое net_packet'а, к-ое содержит информацию о cse_alife_item_weapon (в Зове Припяти):

use constant flAddonSilencer    => 0x01;
use constant flAddonLauncher    => 0x02;
use constant flAddonScope    => 0x04;
use constant properties_info => (
    { name => 'ammo_current',    type => 'u16',    default => 0 },    # 0x194    (0x1b4)
    { name => 'ammo_elapsed',    type => 'u16',    default => 0 },    # 0x196 (0x1b6)
    { name => 'weapon_state',    type => 'u8',    default => 0 },    # 0x191 (0x1b1)
    { name => 'addon_flags',    type => 'u8',    default => 0 },    # 0x1a8 (0x1cc)
    { name => 'ammo_type',        type => 'u8',    default => 0 },    # 0x192 (0x1b2)
    { name => 'cse_alife_item_weapon__unk1_u8',    type => 'u8',    default => 0 },    # cs(0x1a0)

 

Если мы хотим получить информацию о том, какие плюшки повешены на оружие, то надо добраться до значения addon_flags и смотреть биты этого значения. (Кстати, здесь перепутано. Экспериментально установлено, что flAddonScope = 0x01, flAddonSilencer=0x04). С flAddonLauncher и flAddonSilencer всё понятно: существует только одна секция, предметы которой можно повесить в качестве подствола или глушителя. Однако, существует несколько секций оптических прицелов, которые можно повесить на оружие. Например строка из w_lr300.ltx

scopes_sect                   = scope_susat_lr, scope_susat_x1.6_lr, scope_susat_custom_lr, scope_susat_dusk_lr, scope_susat_night_lr

 

Как определить, какой именно прицел повешен на оружие?

 

Заранее спасибо! :)

 

1. Используй спойлер для текстов кодов

2. Даблпостинго вопросов - нарушение правил форума. --/Artos

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

1. Никак не получить, т.к. АМК-таймеры не имеют соответствующего интерфейса по доступу к ним. Ну а кто патался написать ... вероятно понимал, что проще и лучше написать свои таймеры заново, чем вставлять костыли "одряхлевшему" коду.

2. А не слышал о проблеме 2000-го года? Того же порядка, т.е. в принятом формате параметра не хватает разрядности и в какой-то момент наступает "переполнение"/сброс.

В АМК-тайрах используется 32-х битный таймер game.time() и кол-во разрядов хватает на ... немного меньше месяца игрового времени. Далее наступает обнуление бахового времени и все "новые" таймеры будут заведомо с меньшим временем, чем те, которые были до "часа Х".

Лечить таймеры в общем-то бессмысленно, т.к. эта ошибка присуща не только им а имеется во многих кодах игры и следует глобально поменять использование game.time() на 64-х битный вариант game.CTime()

 

Объясни дураку поподробнее пожалуйста. Значит прочитал я про game.CTime(), если game.time() хранит время в миллисекундах с начала игры. То CTime() у на класс, у которого 7 аргументов... Собственно как сделать счетчик на game.CTime() аналогично game.time() - чтоб выдавал в милисекундах... Как я понял если заменить game.time() на game.CTime() тоже самое мы не получим?

 

Полез я в великий и могучий Simbion- нашел такое.

--/-------------------------------------------------------------------------------------------------
--/ Game-Time Section
--/-------------------------------------------------------------------------------------------------
--/ Установка игрового времени на дату из 'alife.ltx'
function set_game_start_time()
    local t = str_explode(":", system_ini():r_string("alife", "start_time"), true)
    local d = str_explode(".", system_ini():r_string("alife", "start_date"), true)
    db.game_start_time = game.CTime()
    --/ формат установки времени = (Y,M,D, h,m,s,ms)
    db.game_start_time:set(tonumber(d[3]),tonumber(d[2]),tonumber(d[1]), tonumber(t[3]),tonumber(t[2]),tonumber(t[1]),0)
end
--/ время в игровых минутах
function get_game_minutes()
    local gt = game.get_game_time() --/ game-time (ms)
    local gs = gt:diffSec(db.game_start_time) --/ game-time (sec)
    --return math.floor(gs) --/> game-time (sec)
    return math.floor(gs/60) --/> game-time (minutes)
end
--/ время в игровых часах
function get_game_hours()
    local gt = game.get_game_time() --/ game-time (ms)
    local gs = gt:diffSec(db.game_start_time) --/ game-time (sec)
    return math.floor(gs/3600) --/> game-time (hour)
end

 

 

Если я откорректирую дату, а затем вызову что-то типо

--/ Установка игрового времени на дату из 'alife.ltx'
function set_game_start_time()
    local t = str_explode(":", system_ini():r_string("alife", "start_time"), true)
    local d = str_explode(".", system_ini():r_string("alife", "start_date"), true)
    db.game_start_time = game.CTime()
    --/ формат установки времени = (Y,M,D, h,m,s,ms)
    db.game_start_time:set(tonumber(d[3]),tonumber(d[2]),tonumber(d[1]), tonumber(t[3]),tonumber(t[2]),tonumber(t[1]),0)
end


    local gt = game.get_game_time() --/ game-time (ms)
    local gs = gt:diffSec(db.game_start_time) --/ game-time (sec)
              local time = gs --/ game-time (ms) -- !!! Это будет аналог game.time() ?

 

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

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

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

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

IQDDD, во-первых, не нужно своими "экспериментальными" проверками голословно(!) опровергать то, что у всех остальных как раз так как указано в процитированном тобою куске кода из ACDC. Если у тебя не так - то или у тебя движек с ума сошел или ... твои проверки. ;-)

 

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

Т.о. хочешь узнать секцию - читай флаг и если он установлен - читай индекс апгрейда и высчитывай ...

 

 

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

Vano_Santuri, ты бы вопрос лучше формулировал, а не свои размышления "на тему" ...

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

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

Примечание: Через день-два будет доступен последний вариант SIMBION'a (ТЧ) в котором все критичное (в том числе и общие таймеры) переведено на 64-х разрядные таймеры и можно будет посмотреть самому ...

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

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

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

Artos, Спасибо. Понятно.

 

И маленький вопрос. Как определить текущую секцию работы НПС. И какую секцию имеет работа, когда НПС стоит возле аномалии и махает детектором(типо арт ищет) для ЗП.

 

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

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

 

Artos, Ясно. Ну в силу того, что я пока не понимаю как работает оффлайн_алайф система , прицепить я ее не смогу.

Ну тогда просто сделаю поиск случайного арта по локе - привяжу к нему случайного нпс, и место, где арт валяется...

 

Просто хочется реалистичности... Вернее того, чего еще никто не делал... О_о, а сделаю я два варианта...

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

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

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

Vano_Santuri, как определить текущую секцию работы НПС легко посмотреть в кодах игры: db.storage[idNPC].active_section

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

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

 

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

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

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

Artos, насчёт флагов может я и напутал, хотя врят ли. Завтра ещё раз проверю.

Насчёт оптики вы не правы: спавнил в инвенатре все указанные выше секции, и любая подходила.

 

UPD: и с флагами у меня тоже всё правильно. Ставлю прицел на пушку: флаг становится 1. Добавляю глушитель - 5.

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

IQDDD, давай придерживаться темы топика а не заниматься погадалками!

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

Также, когда утверждаешь что кто-то не прав в чем-то, приводи аргументы по сути, а не "туфту" ... При чем тут подходит иль нет оптика для оружия и определение "какая установлена"? Если в конфиге прописана секция в параметре - то и новичку-конфигеру должно быть ясно что установить ее можно на оружие иль нет.

Могу пока только посоветовать проверить соответствие последнего байта в state-пакете оружия ('cse_alife_item_weapon__unk1') на соответствие порядковому номеру в строке "scopes_sect" - вполне возможно что это и есть твой искомый результат. (сам пока с ЗП не ковыряюсь ...)

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

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

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

Artos, Еще пару моментов по АМК- таймерам. В коде имеются такие вот вызовы

 local time = level.get_time_days()*60*24+level.get_time_hours()*60+level.get_time_minutes()  --time in game minutes

 

Меня терзают сомнения. Что данная функции работают тоже от game.time() , в следствии чего через 49 дней, они тоже не будут работать... ?

Если я сделаю так, это будет корректно?

 

--/ время в игровых минутах
function get_game_minutes()
    local gt = game.get_game_time() --/ game-time (ms)
    local gs = gt:diffSec(db.game_start_time) --/ game-time (sec)
    return math.floor(gs/60) --/> game-time (minutes)
end

local time = get_game_minutes()  --time in game minutes --!!!

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

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

Ты немного путаешь вещи. Проблема с game.time() в том, что в нём со временем скапливается очень большое число, на хранение которого просто не достаёт ресурсов.

 

Тут же тебе просто возвращаются текущие дни\часы\минуты.

Часы никогда не могут быть больше 23, минуты больше 59, а несколько миллионов игровых дней ты врятли когда либо отыграешь, чтобы у тебя всплыла такая ошибка. :D

 

___

 

И да, они точно не работают от game.time(), т.к game.time() считается фактическое время в игре (или он всё же зависет от alife-фактора? Просто забыл уже)

А дни\месяцы\минут можно перематывать как угодно, т.к что они не должны быть привязаны к game.time(), да и использовать его для этого как минимум не целесообразно.

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

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

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

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

Artos,

1.

function get_addons(se_item)
    local np=net_packet()
    np:w_begin(0)
    se_item:STATE_Write(np)
    np:r_seek(2)
    np:r_u16() -- cse_alife_object
    np:r_u32()
    np:r_u32()
    np:r_u32()
    np:r_u32()
    np:r_stringZ()
    np:r_u32()
    np:r_u32()
    np:r_stringZ() -- cse_visual
    np:r_u8()
    np:r_u32() -- cse_alife_item
    local count = np:r_u32()
    for i = 1, count do
        msg(np:r_stringZ())
    end
    np:r_u16() -- cse_alife_item_weapon
    np:r_u16()
    np:r_u8()
    local addons_flag = np:r_u8() -- addon_flags
    msg(addons_flag)
    if bit_and(addons_flag, 1) ~= 0 then
        msg("Has scope")
    else
        msg("Hasn't scope")
    end
    if bit_and(addons_flag, 2) ~= 0 then
        msg("Has launcher")
    else
        msg("Hasn't launcher")
    end
    if bit_and(addons_flag, 4) ~= 0 then
        msg("Has silencer")
    else
        msg("Hasn't silencer")
    end
end

 

2. Что вы понимаете под "туфтой" и "аргументами по сути"? Я же написал, что запускал и проверял, и было так, как написал выше. Вам надо видео снять и выложить, что бы это был "аргумент по сути"? Да и вообще, какие могут быть аргументы? Мы что, спорим разве?

3. Как связь между тем, "подходит или нет" и "какая установлена"? А такая: из первого следует невозможность ответить на второе. Поясню для непонятливых: вы говорите, что нужно для определения секции оптики смотреть секции апдейтов оружия, на которое вышается оптика, т.е. между апдейтом и типом дозволенной для установки оптики существует взаимно однозначное соответствие. Однако мой пример показывает, что это не так. Да и вообще, можно установить 5 разных типов оптик. И по вашему должно быть 5 разных секций апдейтов?

4. Последний байт из пакета проверял. Увы, всегда 0.

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

ТЧ v 1.0004

Вопрос по перемещению объектов от одного владельца к другому.

Как я понимаю, для этого есть ф-ция transfer_item ?

Пробую переместить калаш из инвентаря актора(ГГ) в инв. Волку:

local npc = db.actor
local ser_obj_to = alife():story_object(6)
if ser_obj_to then
    local obj_to = alife():object(ser_obj_to.id)
    if obj_to then
        local obj = npc:object("wpn_ak74")
        if obj then
            npc:transfer_item(obj, obj_to)
        end
    end
end

 

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

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

А вообще говоря в аргументах должны быть клиентские объекты. То бишь obj_to = level.object_by_id(ser_obj_to.id)

Изменено пользователем IQDDD
Ссылка на комментарий
То бишь obj_to = level.object_by_id(ser_obj_to.id)

В таком варианте все заработало.

Если приходится использовать level.object_by_id, значит отправить предмет с помощью transfer_item объекту, находящемуся на неактивной локации, не получится ?

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

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

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

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

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

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

Войти

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

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

×
×
  • Создать...