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

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


Svoboда

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

ColR_iT, Artos, спс :)

 

ColR_iT

 

Какой результат?

ну в смысле польза :)

 

Можешь глянуть в lua_help.script и в справочнике было какое-то описание этому.

да, я глядел, правда давненько это было

 

Artos

 

Vint@rь, странно, что этот метод(функцию) ты только сейчас заметил ;-)

заметил то я его давно, вот интерес(надобность), появился только сейчас :)

 

СтОит ли использовать этот метод "в свои целях"? Все опять же зависит от цели... Если аналогично "сторожить", или организовать свой автономный апдейтик для скрипта/класса - то конечно стОит, а вот для таймеров...

В своих целях в виде "сторожа", мб помнишь я писал про зависания биндера у меня?? вот для отлова этой "байды" :), а про свои таймера упомянул только из за того, что у меня не используются скрипты от xStream и Malandrinus

 

 

Практическое применение также давно можно видеть в действии. Например, давно в моде SIMBION различные апдейты рестрикторов, погоды, новостей, оффлайн-алайфа и т.п. переведены именно на независимые апдейты на базе level.add_call. Можно видеть их использование и в модулях m_netpk и se_stor. Как сказано выше - это дает независимость от зависаний акторского апдейта да и подразгружает его, хотя конечно же все равно Lua выполняет все потоки 'последовательно'...
Пишу это, не смотря на то, что у самого модуль таймеров именно на этом методе апдейтится. ;-)

а вот это погляну)) особенно по поводу таймеров, хотя ведь даже апдейт этой новой нити зависит от FPS???(где-то читал просто что частота апдейта на прямую зависит от FPS игрока) и тут возникает вопрос, тогда какие плюсы/минусы для таймеров с использованием такого метода?

Изменено пользователем Viнt@rь

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


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

serega-gamer, ты не подумал просто прервать цикл? Посмотри внимательнее, у тебя, цикл работает пока не переберет все объекты, которые есть в инвентаре, а по условию, если оно истинное, то выполняется действие, то есть, если 2 одинаковых объекта в инвентаре с тем, что в руках, то действие в цикле будет выполнятся 2 раза, если 3 обьекта - 3 раза и тп, поэтому, после выполнения нужного тебе действия, цикл нужно прервать!

Изменено пользователем Viнt@rь
  • Нравится 1

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


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

ColR_iT,

 

ну, оптимизация - личное дело каждого), хочет оптимизирует, хочет - нет, просто вот ты написал уже оптимизированный вид, так человек просто скопипастит, да и все, в итоге не научится оптимизации))

 

 

 

[spoiler= :offtopic: ]А я вот тоже изначально так думал, пока мне не продемонстрировали мой же код, только раз в пять короче и быстрее. Если человеку не с чем будет сравнивать, то и учиться будет не на чём.

ColR_iT

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

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


Ссылка на сообщение
Можно ли скриптом привязать партикл к модельке нпс(к ее какой то кости)?

 

Во-первых, вопрос не в тему.

Во-вторых, пиши с большой буквы.

В-третьих, электрохимера АМК.

ColR_iT

 

 

Прошу, прощения =)

 

Переформулирую вопросик так сказать "нормально" а не абы как...

 

Можно ли "прицепить" партикл к определенной кости модели, к примеру - нпс? и если да, то каким образом? Скажу даже для чего, для идеи с "паром изо рта нпс"

И сразу встречный вопрос, в последствии вот такого действия, не повлияет ли это на производительность?

 

ЗЫ

ColR_iT, ок гляну, чет забыл за химеру

Изменено пользователем Viнt@rь

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


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

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

 

 

if self.object.health <=0.3 and not has_alife_info("info") then
magnus1.hp_test1()
give_info("info")
end


function hp_test1()
local sactor = alife():actor() --получаем серверный объект актера
local cactor = level.object_by_id(sactor.id) --по его ID получаем клиентский объект актера
cactor:give_game_news("Свободу тушканам!\\nТушканчики всех стран, объединяйтесь!","ui\\ui_npc_monster",Frect():set(0,215,163,105),math.random(1000, 3000),5000)
disable_info("info")
end

 

зы has_alife_info("info") give_info("info") disable_info("info") -- функции из ЗП(_g.script)

в ТЧ не помню есть ли такие или нет

Изменено пользователем Viнt@rь

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


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

Artos, точняк, проморгал))(или мне показалось что функция новостей вызывается через время...)

 

if self.object.health <=0.3 and not has_alife_info("info") then
magnus1.hp_test1()
give_info("info")
end


function hp_test1()
local sactor = alife():actor() --получаем серверный объект актера
local cactor = level.object_by_id(sactor.id) --по его ID получаем клиентский объект актера
cactor:give_game_news("Свободу тушканам!\\nТушканчики всех стран, объединяйтесь!","ui\\ui_npc_monster",Frect():set(0,215,163,105),math.random(1000, 3000),5000)
end

disable_info("info") -- через какое то время(с помощью таймеров) либо при каком-то событии

 

а по поводу

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

 

Shadows, ну захотелось человеку)) или кто-то порекомендовал так....

Изменено пользователем Viнt@rь

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


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

Jein, не пробывал время выводить не через кастом статик, а через CUIStatic()? сам пытался сделать подобное(только в окне инвентаря на ЗП) то кастом статиком ничего не добился, в смысле добился, но мой текст был под окном инвентаря...

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


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

Artos,

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

обновлял(на апдейте актора постоянно, но статик не вылазил на верх...) потому ИМХО самый лучший выход это

...тут уже через CUIStatic()...и приаттачивать...

Jein, я точно не уверен, но по идее должно помочь:

 

пример(ЗП)
class "CSpNotepad" (CUIScriptWnd)
...
function CSpNotepad:Update()
  CUIScriptWnd.Update(self)
  self.wClock:TextControl():SetText(GetTime())
end
...

 

Вот примерно таким методом можно обновлять свой эелемент/окошко

Изменено пользователем Viнt@rь

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


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

Jein, да он это и имеет ввиду) обновлять с апдейта актора раз в 1 мин игрового времени(тебе же секунды не надо выводить)

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


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

так мб, если разница в не совпадении времени с погодой, стоит просто поправить погоду? это куда проще

Изменено пользователем Viнt@rь

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


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

Jein, только скриптами, только ХардКор

:grin2: :grin2: :grin2: :grin2: :crazy: :crazy:

 

ПДА - чего и в помине нет в чистом СТалкере. Я вообще был удивлен что в чистом Сталкере нет даже скриптов ПДАх

Потому что он вшит в двигло!

Изменено пользователем Viнt@rь

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


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

(ЗП)Нужно добавить текст в текстовое поле(CUITextWnd)

...
self.dList = cXml:InitTextWnd("dialog:func_text",self.oDialog)
self:Register(self.dList, "func_text")
...

-- добавляю
self.dList:SetText(self.dList:GetText()..sText .. "\\n")

по идее так оно должно переносить "каретку" на строку ниже, но...

в итоге получаю что то типо

"фывфы \n"

 

ЗЫ смотрел как сделано в ui_load_dialog.script (функция file_data(fname)), и делал так же, там все ок, у меня нет...

ЗЫЫ "\n" тоже не катит... правда символ сам не выводит, но и строку не переносит

Изменено пользователем Viнt@rь

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


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

Artos, ошибаешься))) все получилось) и перенесло, когда я добавил в тег complex_mode="1"

 

Хотя если делать с использованием SetTextComplexMode(boolean), то ничего не меняется

 

а на самом деле используешь тот же CScriptXmlInit.

да, скорей всего ты прав, я забыл дописать

local oCXml = CScriptXmlInit()
...
self.dList = oCXml:InitTextWnd("dialog:func_text",self.oDialog) -- но все же это создается обьект класса CUITextWnd
self:Register(self.dList, "func_text")
...

Изменено пользователем Viнt@rь

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


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

*Shoker*, ты хотел сохранять в файл(текстовый и тп) свои переменные, и делать название файла таким же, как и название сейва?

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

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

Изменено пользователем Viнt@rь

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


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

Привет всем. Вопрос, (прошу сразу - не пинайте, только начинаю осваивать нет пакеты )))), как можно сохранить(на сохранении актора) нет пакет (local packet = net_packet()) и загрузить(прочитать)(на загрузке актора) ?? не прибегая к таким методам, какие используются в хранилищах Malandrius и xStream???

к примеру мне надо сохранить данные таймера

 

 

-- сохранение
local packet = net_packet()
local n = #aTimers.aHigh
packet:w_u8(n)

if next(aTimers.aHigh) then
for sName, oTimer in pairs(aTimers.aHigh) do
if type(sName) == 'string' then
packet:w_bool(true)
packet:w_stringZ(sName)
else
packet:w_bool(false)
packet:w_u32(sName)
end
packet:w_bool(oTimer.bGameType or false)
if oTimer.bGameType then
utils.w_CTime(packet, oTimer.iTriggerTime)
else
packet:w_stringZ(oTimer.iTriggerTime)
end
packet:w_bool(oTimer.bOnce or false)
if not oTimer.bOnce then
packet:w_stringZ(oTimer.iInterval)
end
packet:w_stringZ(oTimer.oFunc)
packet:w_bool(true)
end
end

-- загрузка
local packet = net_packet()
local n = packet:r_u8()

for i = 1, n do
local bIsStrName = packet:r_bool()
if bIsStrName then
local sName = packet:r_stringZ()
else
local sName = packet:r_u32()
end

local oTimer = oTimers(sName)

oTimer.bGameType = packet:r_bool()
if oTimer.bGameType then
oTimer.iTriggerTime = utils.r_CTime()
else
oTimer.iTriggerTime = packet:r_stringZ()
end
oTimer.bOnce = packet:r_bool()
if oTimer.bOnce then
oTimer.iInterval = packet:r_stringZ()
end
oTimer.oFunc = packet:r_stringZ(oTimer.oFunc)

local bHighPrior = packet:r_bool()
oTimer:Start(bHighPrior)
end

 

 

 

ЗЫ я понимаю, что скорее всего, я понаписывал бред, помогите разобраться, плз

ЗЫЫ Всех с наступающим)

Изменено пользователем Viнt@rь

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


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

Если сохранить число методом packet:w_stringZ(num), то при его чтении, оно будет строкой, верно? и что бы оно снова стало числом, нужно применить функцию tonumber?

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


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

за пояснение спс, по поводу экономии, возможно вопрос глуповат, но как определить ско

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

 

Что "Shift" не работает?

ColR_iT

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

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


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

Artos, спасибо за пояснение :), в общем, можно смело использовать метод w_float и не париться...

ЗЫ такие большие числа мне уж точно запоминать не надо)))

ColR_iT, с планшета писал, потому и забыл про клавишу shift

Изменено пользователем Viнt@rь

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


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

Плз хелп, решил сделать "упрощенное"(даже очень упрощенное) хранилище своих данных, на основе наработок xStream и Malandrius...

вот содержимое скрипта - хранилища:


--]] ------------------------------------------------------------------------------------------------
--/ Variables
--]] ------------------------------------------------------------------------------------------------
storage = {}
local save_markers = {}
local bStReg
local type2marker = {
['boolean'] = 1,
['number'] = 2,
['string'] = 3,
['table'] = 4
}
local marker2type = {
[1] = 'boolean',
[2] = 'number',
[3] = 'string',
[4] = 'table'
}
--]] ------------------------------------------------------------------------------------------------
--/ Initialize
--]] ------------------------------------------------------------------------------------------------
function Init()
event("ActorSave"):register(CreateStorageObj)
end
--]] ------------------------------------------------------------------------------------------------
--/ Callback`s
--]] ------------------------------------------------------------------------------------------------
function CreateStorageObj()
if not bStReg then
local oStorage = alife():create("custom_storage", vector(), 0, 0)
-- никогда не выйдет в онлайн
oStorage:can_switch_online(false)
oStorage:can_switch_offline(true)
bStReg = true
end
end

--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-- * se_custom_storage *
--* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
class "se_custom_storage" (cse_alife_dynamic_object)
function se_custom_storage:__init(section) super(section)
end

function se_custom_storage:on_register()
cse_alife_dynamic_object.on_register(self)
bStReg = true
end

function se_custom_storage:STATE_Read(packet, size)
cse_alife_dynamic_object.STATE_Read(self, packet, size)
_printf("Storage Load")
while not packet:r_eof() do
local k = packet:r_stringZ()
_printf("Load Key:[%s]",tostring(k))
LoadValue = function(tbl)
local v
local tv = marker2type[packet:r_u8()]
if tv == 'string' then
v = packet:r_stringZ()
elseif tv == 'boolean' then
v = packet:r_bool()
elseif tv == 'number' then
v = packet:r_float()
elseif tv == 'table' then
v = {}
local n = packet:r_u8()
local b = packet:r_bool()
if n > 0 then
if b then
for i = 1, n do
LoadValue(v[i])
end
else
for i = 1, n do
local kk = packet:r_stringZ()
LoadValue(v[kk])
end
end
end
end
tbl = v
end
LoadValue(storage[k])
end
alife():release(self)
event("StorageLoad"):trigger(--[[{packet = packet}--]])
end

function se_custom_storage:STATE_Write(packet)
cse_alife_dynamic_object.STATE_Write(self, packet)
_printf("Storage Save")
event("StorageSave"):trigger(--[[{packet = packet}--]])
if next(storage) then
for k,v in pairs(storage) do
packet:w_stringZ(k)
_log_db("Save Key:[%s]",tostring(k))
SaveValue = function(Value)
local tv = type(Value)
if type2marker[tv] then
packet:w_u8(type2marker[tv])
if tv == 'string' then
packet:w_stringZ(Value)
elseif tv == 'boolean' then
packet:w_bool(Value)
elseif tv == 'number' then
packet:w_float(Value)
elseif tv == 'table' then
packet:w_u8(#Value)
packet:w_bool(IsList(Value))
if IsList(Value) then
for i = 1, #Value do
SaveValue(Value[i])
end
else
for kk,vv in pairs(Value) do
packet:w_stringZ(kk)
SaveValue(vv)
end
end
end
else
_log_db("Save:->:<!Warning!>:->:Do not save type:=[%s]",tv)
end
end
SaveValue(v)
end
end
end

-- этот объект всегда будет сохраняться
function se_custom_storage:can_save()
return true
end

--]] ------------------------------------------------------------------------------------------------
--/ Functions
--]] ------------------------------------------------------------------------------------------------
--[[
-- Проверка типа таблицы:'список' или нет?
-- @param table tTbl таблица
-- @return boolean
--]]
function IsList(tTbl)
local bList = false
local iCntIdx = #tTbl
if iCntIdx > 0 then
if next(tTbl) == 1 and not next(tTbl,iCntIdx) then
for i=2,iCntIdx-1 do
if tTbl[i] == nil then
return false
end
end
bList = true
end
end
return bList
end

 

 

В итоге, вроде бы и сохраняет и загружает переменные нормально, но, если глянуть на выводимые логи сейва/загрузки, то получается что то странное, сохраняет переменные из массива storage замечательно, ничего лишнего в лог не выводит:

Storage Save

Save Key:[iSleep] -- переменная

Save Key:[iCntNrg] -- переменная

Save Key:[spawnBar] -- переменная

Save Key:[tTimers] -- таблица с под таблицами

Save Key:[tActorStats] -- таблица с ключами

Save Key:[iActScore] -- переменная

Save Key:[FirstRun] -- переменная

 

 

а вот при загрузке:

Storage Load

Load Key:[iSleep] -- переменная

Load Key:[iCntNrg] -- переменная

Load Key:[spawnBar] -- переменная

Load Key:[tTimers] -- таблица с под таблицами aHigh & aLow, которые ниже, вместе с их ключами, они не должны быть тут, лог загрузки по идее должен быть такой же, как и лог сохранения...

Load Key:[aHigh]

Load Key:[type]

Load Key:[int]

Load Key:[args]

Load Key:[id]

Load Key:[once]

Load Key:[func]

Load Key:[rem]

Load Key:[aLow]

Load Key:[tActorStats] --таблица с ключами, которые ниже

Load Key:[iHeadShots]

Load Key:[iKnifeKills]

Load Key:[iGrenadeKills]

Load Key:[iVodkaCnt]

Load Key:[iActScore] -- переменная

Load Key:[FirstRun] -- переменная

 

 

сравнив этот лог с логом сейва, видно, что лишнее...

Изменено пользователем Viнt@rь

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


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

malandrinus,

1. ИМХО, готовое решение - слишком громоздкое, в смысле, лично для меня, мне не нужно столько разных методов и тп, мне хватит того, что я сделал, в итоге получилось "простенько и со вкусом" :)

2. захотелось самому сделать нечто подобное, поработать с нет-пакетами, саморазвитие и тп... :)

Изменено пользователем Viнt@rь

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


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

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