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

Скриптование


Svoboда

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

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.

Поделиться этим сообщением


Ссылка на сообщение

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

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

Поделиться этим сообщением


Ссылка на сообщение
Artos, в таких условиях ставится вопрос о существовании решения. Как вы считаете, должно ли существовать решение этой проблемы?

Поделиться этим сообщением


Ссылка на сообщение

Интересуют ограничения на размер хранимых данных в db.storage

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

Поделиться этим сообщением


Ссылка на сообщение

Люди, скажите, у меня где-то трабла, или такое в самом деле бывает.

function test(id)
    local obj = level.object_by_id(id)
    msg(obj:id())
    msg(obj:section())
end

 

Вылетов не вызывает, id верный. Секция отображается как 9x19.

function test_problem(id)
    local sobj = alife():object(id)
    if not sobj then abort([Что-нибудь]) end
    msg(sobj.id)
    msg(sobj:section_name())
end

 

Будучи вызанной сразу после test крашит игрут на вызове sobj.id (не на abort (!)). Как такое могет быть? По одному и тому же id клиент работает верно, а сервер вообще не адекватен.

 

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

В придачу: изменяются ли id'ы после сохранения/загрузки?

 

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

Отвечу на свой первый вопрос.

Следующий код будет работать (пусть id входной параметр (типа "number") - получение ближащей клиентской вещи)

local obj = level.object_by_id(id) -- получение клиента по number
local sobj = alife():object(id) -- получение сервера по number

 

Следующий код тоже будет работать:

local str_id = tostring(id) -- получение строкового представления id
local obj = level.object_by_id(str_id) -- получение по типу "number", который автоматически преобразовался из "string"
local sobj = alife():object(id) -- не меняем

 

Следующий код не будет работать:

local str_id = tostring(id) -- получение строкового представления id
local obj = level.object_by_id(str_id) -- получение по типу "number", который автоматически преобразовался из "string"
local sobj = alife():object(str_id) -- не изменяем

 

Если бы это было в ТЧ или ЧН - я бы не удивился, т.к. у класса alife_simulator метод object() перегружен:

    cse_alife_dynamic_object* object(int id, bool no_assert); // получение объекта по id. 
    cse_alife_dynamic_object* object(int id); // эквивалентно предыдущей функции с no_assert == true. 
    cse_alife_dynamic_object* object(string name); // получение объекта по имени. В ЗП нет!

 

Но в ЗП (в котором и тестируется этот пример) сей функции нет. Но тем не менее разработчики не потрудились убрать и "обёртку" маршалинга в вызов функции на C (или на чём там?). Я негодуэ.

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

Поделиться этим сообщением


Ссылка на сообщение

proger_Dencheek, смотря, какая модель вам ближе: "событийная" или "таймерная". Если событийная, то надо искать коллбек на изменение здоровья актора (по-моему, где-то уже обсуждалось, что даже если навесить биндер на актора, то не работает). Если таймерная, то с определённым периодом проверять здоровье ГГ, и если 0, то вроде есть метод получения последнего хита. Может ошибаюсь.

 

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

Struck, кури массивы и циклы. Создаёшь некоторую базу из точек, можно даже из областей (например, круг, прямоугольник и пр.). Вручную прописываешь сторону света, название и пр. Потом организуешь цикл.

 

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

4294967295 * count_time_fix

Здесь будет переполнение.

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

Поделиться этим сообщением


Ссылка на сообщение

Пфффф... Да не предлагаю я ни какие спейс рестрикторы. А если тебе нужно определить стороны света ПО ОТНОШЕНИЮ К ДРУГОМУ ОБЪЕКТУ, то тут простая математическая задача при условии, что координатные оси уровня располагаются с юга на север и с запада на восток. Если это не так, то нужно ещё вспоминать функции преобразования координат при повороте системы координат.

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

Поделиться этим сообщением


Ссылка на сообщение

7.9

А не, нифига там не будет переполнения. Вернее, оно может быть, а может и не быть. Lua - динамический язык, и не ясно, в какой структуре будет представлено то или иное число: с фиксированной или плавающей запятой. Поэтому тут некоторые проблемы наблюдаются. Например, число 2^32 представляется в формате с фиксированной запятой (не уверен, т.к. может быть, что это число преобразуется в формат с плавающей запятой без потери точности.). А 2^64 уже преобразуется в формат с плавающей запятой с потерей точности. Т.о. мы не можем утверждать точность численных операций при значениях, больших 2^32-1. Или даже 2^31-1.

 

Если я не прав, киньте в меня огнеупорный кирпич.

 

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

Struck, а давай ты это сделаешь сам, или обратишься на dxdy.ru.

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

Поделиться этим сообщением


Ссылка на сообщение

Как-то раз malandrinus высказывал своё недовольство по поводу того, что некоторые используют слово "дирекция" вместо "направление". Правильно вообще говорил. :)

Поделиться этим сообщением


Ссылка на сообщение

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

Поделиться этим сообщением


Ссылка на сообщение

1. Все userdata'ы (в том числе и объекты game_object) являются ссылочными типами, посему когда ты пишешь obj1 = obj2 - ты копируешь только ссылку (занимает 4/8 байта) на объект. Посему выигрыша в производительности нет.

2. Лучше использовать table.insert, т.к. даже если он и чуть медленнее, всё равно лучше поступиться производительностью во благо понятности кода.

Поделиться этим сообщением


Ссылка на сообщение

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

Поделиться этим сообщением


Ссылка на сообщение

В bind_stalker'е есть функция update(delta).

Она периодически вызывается через определённый промежуток времени (период delta зависит от производительности и составляет в среднем 15-20 мс). На этой основе и делай.

Поделиться этим сообщением


Ссылка на сообщение

net_spawn и net_destroy - это не коллбеки, а переопределённые методы.

Поделиться этим сообщением


Ссылка на сообщение

Если это ТЧ/ЧН, то смотрите treasure_manager. Там всё есть, в т.ч. и таблица информации о всех тайниках, в т.ч. и о контейнерах тайников.

Поделиться этим сообщением


Ссылка на сообщение
function get_weight_item(item) --получает вес предмета item
    local ini=system_ini()
local result=0
local sect=item:section()
local class=ini:r_string(sect,"class")
local id=item:id()
-------------------это пачка патронов
if class=="AMMO_S" then
local sobj = alife():object(id)
if sobj then
result = get_weight_ammo(sect, get_ammo_in_box(alife():object(id)))
end
-------------------это ствол
elseif string.find(class,"WP_") and class ~= "WP_BINOC" and class ~= "WP_KNIFE" and class ~= "WP_SCOPE" and class ~= "WP_SILEN" and class ~= "WP_GLAUN" then
result = ini:r_float(sect, "inv_weight")
local typeAmmo = get_type_ammo(item)
result=result+get_weight_ammo(typeAmmo, item:get_ammo_in_magazine())
result=result+get_upgrade_weight(id)
-------------------это броня
elseif class=="E_STLK" or class=="E_HLMET" then
result=ini:r_float(sect,"inv_weight")
result=result+get_upgrade_weight(id)
-------------------это другой предмет
else
if ini:line_exist(sect,"inv_weight") then
result=ini:r_float(sect,"inv_weight")
end
end
return result
end

function get_weight_ammo(class_ammo, count)--находит вес пачки патронов
local curWeight=count*system_ini():r_float(class_ammo,"inv_weight")/system_ini():r_float(class_ammo,"box_size")
return curWeight
end

function get_ammo_in_box(sobj) --находит количество патронов в пачке
local np = net_packet()
np:w_begin(0)
sobj:STATE_Write(np)
np:r_seek(np:w_tell() - 2)
return np:r_u16()
end

function get_type_ammo(obj) -- находит тип патронов в стволе
local types = split_params(system_ini():r_string(obj:section(), "ammo_class"))
return types[get_index_ammo(obj:id())+1]
end

function get_index_ammo(id)--находит id патронов в стволе
local sobj = alife():object(id)
local np = net_packet()
np:w_begin(0)
sobj:STATE_Write(np)
np:r_seek(np:w_tell() - 2)
return np:r_u8()
end

function split_params(str, sep) -- strP = string вида item1,item2,item3... return = {[1]=item1,[2]=item2,[3]=item3...} (в строках, даже если число)
local res = {}
local ind, last_ind
if sep == nil then
sep = {",", " "}
end
if type(sep) == "string" then
sep = { sep }
end

-- Случай с пустой строкой
if str == "" then
return res
end
ind = find_symb(str, sep, 1)
last_ind = 1

-- Случай только с одним параметром
if ind == nil then
return { [1] = str }
end
repeat
local sub_str = string.sub(str, last_ind, ind-1)
if sub_str ~= nil and sub_str ~= "" then
table.insert(res, sub_str)
end
last_ind = ind+1
ind = find_symb(str, sep, ind+1)
until ind == nil

-- Последний параметр
local sub_str = string.sub(str, last_ind, string.len(str))
if sub_str ~= nil and sub_str ~= "" then
table.insert(res, sub_str)
end

return res
end

function get_table_upgrade(se_item)
local t = {}
--Добавленные персонажем
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() --upgrade_count
for i=1,count do
table.insert(t,np:r_stringZ())
end

--Встроенные изначально
local ini = system_ini()
if ini:line_exist(se_item:section_name(), "installed_upgrades") then
local upgs_str = ini:r_string(se_item:section_name(), "installed_upgrades")
if upgs_str ~= nil then
for upg in string.gmatch(upgs_str, "[%d%a%-%._]+") do
table.insert(t, upg)
end
end
end

return t
end

function get_upgrade_weight(id_item) --получает вес апгрейдов брони
local upgrades=get_table_upgrade(alife():object(id_item))
local ini=system_ini()
local result=0

for k,v in ipairs(upgrades) do
local sect=ini:r_string(v,"section")
if ini:line_exist(sect,"inv_weight") then
result=result+ini:r_float(sect,"inv_weight")
end
end
return result
end

 

 

Работает только для ЗП.

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

Поделиться этим сообщением


Ссылка на сообщение

Да, это для "одноразового" вызова. Зачем это ставить в апдейт (при какой ситуации) - для меня загадка. В "одноразовых" циклах перебора всех вещей ГГ работает нормально.

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

Поделиться этим сообщением


Ссылка на сообщение

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

 

"Работает нормально" - не находишь подобное определение смахивающим на "лишь бы работало - а остальное не важно"?

Нахожу. И чё дальше?

Поделиться этим сообщением


Ссылка на сообщение
  • Недавно просматривали   1 пользователь

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