IQDDD 5 Опубликовано 18 Августа 2012 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. Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 18 Августа 2012 (изменено) А вообще говоря в аргументах должны быть клиентские объекты. То бишь obj_to = level.object_by_id(ser_obj_to.id) Изменено 18 Августа 2012 пользователем IQDDD Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 18 Августа 2012 Да, не получится. Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 19 Августа 2012 Artos, в таких условиях ставится вопрос о существовании решения. Как вы считаете, должно ли существовать решение этой проблемы? Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 19 Августа 2012 (изменено) Интересуют ограничения на размер хранимых данных в db.storage Изменено 19 Августа 2012 пользователем IQDDD Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 19 Августа 2012 (изменено) Люди, скажите, у меня где-то трабла, или такое в самом деле бывает. 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 (или на чём там?). Я негодуэ. Изменено 19 Августа 2012 пользователем IQDDD Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 19 Августа 2012 (изменено) proger_Dencheek, смотря, какая модель вам ближе: "событийная" или "таймерная". Если событийная, то надо искать коллбек на изменение здоровья актора (по-моему, где-то уже обсуждалось, что даже если навесить биндер на актора, то не работает). Если таймерная, то с определённым периодом проверять здоровье ГГ, и если 0, то вроде есть метод получения последнего хита. Может ошибаюсь. Добавлено через 2 мин.: Struck, кури массивы и циклы. Создаёшь некоторую базу из точек, можно даже из областей (например, круг, прямоугольник и пр.). Вручную прописываешь сторону света, название и пр. Потом организуешь цикл. Добавлено через 2 мин.: 4294967295 * count_time_fix Здесь будет переполнение. Изменено 19 Августа 2012 пользователем IQDDD Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 19 Августа 2012 (изменено) Пфффф... Да не предлагаю я ни какие спейс рестрикторы. А если тебе нужно определить стороны света ПО ОТНОШЕНИЮ К ДРУГОМУ ОБЪЕКТУ, то тут простая математическая задача при условии, что координатные оси уровня располагаются с юга на север и с запада на восток. Если это не так, то нужно ещё вспоминать функции преобразования координат при повороте системы координат. Изменено 19 Августа 2012 пользователем IQDDD Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 19 Августа 2012 (изменено) 7.9 А не, нифига там не будет переполнения. Вернее, оно может быть, а может и не быть. Lua - динамический язык, и не ясно, в какой структуре будет представлено то или иное число: с фиксированной или плавающей запятой. Поэтому тут некоторые проблемы наблюдаются. Например, число 2^32 представляется в формате с фиксированной запятой (не уверен, т.к. может быть, что это число преобразуется в формат с плавающей запятой без потери точности.). А 2^64 уже преобразуется в формат с плавающей запятой с потерей точности. Т.о. мы не можем утверждать точность численных операций при значениях, больших 2^32-1. Или даже 2^31-1. Если я не прав, киньте в меня огнеупорный кирпич. Добавлено через 1 мин.: Struck, а давай ты это сделаешь сам, или обратишься на dxdy.ru. Изменено 19 Августа 2012 пользователем IQDDD Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 19 Августа 2012 Как-то раз malandrinus высказывал своё недовольство по поводу того, что некоторые используют слово "дирекция" вместо "направление". Правильно вообще говорил. Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 20 Августа 2012 Как по мне, так апдейты актора и пр. не имеют к этому отношения. Как засунул в _G, так сразу и будет доступна. Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 20 Августа 2012 1. Все userdata'ы (в том числе и объекты game_object) являются ссылочными типами, посему когда ты пишешь obj1 = obj2 - ты копируешь только ссылку (занимает 4/8 байта) на объект. Посему выигрыша в производительности нет. 2. Лучше использовать table.insert, т.к. даже если он и чуть медленнее, всё равно лучше поступиться производительностью во благо понятности кода. Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 20 Августа 2012 Не надо засорять код и свою голову всякими мелочными оптимизациями. Пишите код так, чтобы было в первую очередь "понятно, чётко и лаконично". Если работает медленно, надо искать возможность оптимизировать в первую очередь - структуру алгоритма, а потом уже его написание. Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 20 Августа 2012 В bind_stalker'е есть функция update(delta). Она периодически вызывается через определённый промежуток времени (период delta зависит от производительности и составляет в среднем 15-20 мс). На этой основе и делай. Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 21 Августа 2012 net_spawn и net_destroy - это не коллбеки, а переопределённые методы. Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 21 Августа 2012 Если это ТЧ/ЧН, то смотрите treasure_manager. Там всё есть, в т.ч. и таблица информации о всех тайниках, в т.ч. и о контейнерах тайников. Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 7 Сентября 2012 (изменено) 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 Работает только для ЗП. Изменено 7 Сентября 2012 пользователем ColR_iT Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 7 Сентября 2012 (изменено) Да, это для "одноразового" вызова. Зачем это ставить в апдейт (при какой ситуации) - для меня загадка. В "одноразовых" циклах перебора всех вещей ГГ работает нормально. Изменено 7 Сентября 2012 пользователем IQDDD Поделиться этим сообщением Ссылка на сообщение
IQDDD 5 Опубликовано 7 Сентября 2012 Под "нормально" я имею ввиду что производительность страдает в пределах нормы (если вешать не на апдейт, а на коллбеки). Ну наблюдаем небольшую задержку при взятии бальшой-бальшой кучи предметов. Терпимо. Как при переходе нескольких сталкеров в онлайн. А чтобы пачек патронов слишком много не было, то надо перепаковщик. И никак не будет сотен пачек патронов. "Работает нормально" - не находишь подобное определение смахивающим на "лишь бы работало - а остальное не важно"? Нахожу. И чё дальше? Поделиться этим сообщением Ссылка на сообщение