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

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


Svoboда

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

Пустая трата времени. Есть же таблица db.creatures, её и перебирайте:

for id, npc in pairs(db.creatures) do
if  IsStalker(npc) then
...
end
end

Правда есть одно но! Данная таблица есть в АМК, но ее нет в чистом 1.004. Куфзук

Изменено пользователем Куфзук

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


Ссылка на сообщение
Во-первых, эта таблица создается не мгновенно при старте игры, а динамически пополняется/чистится по мере появления объектов в он-лайне.

В предлагаемом автором вопроса скрипте был перебор именно онлайновых объектов, так что именно это и нужно.

 

Во-вторых, в более сложных случаях можно нарваться и на момент, когда серверный объект уже удален из игры, а в таблице 'db.creatures' он еще не удален

В se_stalker и se_monster в функцию on_unregister добавить

db.creatures[self.id] = nil

должно помочь.

 

На чистой игре, где нет этой таблицы (только сейчас об этом узнал O_o) нужно добавить в db вот это:

creatures = {} --' Это в самом начале, перед всеми функциями

function add_obj(obj)
    if obj then
        creatures[obj:id()] = obj
    end
end

function del_obj( obj )
    if obj then
        storage [obj:id()] = nil
        creatures[obj:id()] = nil
    end
end

И в bind_monster и xr_motivator в функции net_spawn после вот этого

    if not object_binder.net_spawn(self, sobject) then
        return false
    end

добавить такую строку:

    db.add_obj(self.object)

В net_destroy в самом начале добавить

    db.del_obj(self.object)

После этого перебор таблицы должен заработать.

Изменено пользователем Полтергейст

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


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

Кто-нибудь знает, почему в se_stalker при таком составлении функций значение self.wounded всегда считывается как true?

 

function se_stalker:STATE_Write (packet)

cse_alife_human_stalker.STATE_Write (self, packet)

if self.script_version >= 6 then

local ddw=0

if self.death_droped then ddw=ddw+1 end

if self.wounded then ddw=ddw+2 end

packet:w_u8(ddw)

end

end

 

function se_stalker:STATE_Read (packet, size)

cse_alife_human_stalker.STATE_Read (self, packet, size)

if self.script_version >= 6 then

local ddw=packet:r_u8()

self.death_droped=bit_and(ddw,1)==1

self.wounded=bit_and(ddw,2)==2

end

end

 

 

 

Даже если привести их к такому виду

 

function se_stalker:STATE_Write (packet)

cse_alife_human_stalker.STATE_Write (self, packet)

packet:w_bool(self.death_droped)

packet:w_bool(self.wounded)

end

 

function se_stalker:STATE_Read (packet, size)

cse_alife_human_stalker.STATE_Read (self, packet, size)

self.death_droped = packet:r_bool()

self.wounded = packet:r_bool()

end

 

 

то всё равно получается то же самое. Что делать?

Изменено пользователем Полтергейст

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


Ссылка на сообщение
Как видно из выше изложенного (или можешь взглянуть на структуру нет-пакета сталкера в том де бардаковском ACDC) ты вместо заключительного байта 'death_droped' пытаешься перепрописывать 'job_online'

Вот это я не совсем понял. Я ведь удалил все эти поля (job_online*, was_in_smart_terrain), они не записываются (см. функцию STATE_write). Естественно, я начинаю новую игру, а не гружу сохранения. Переменные те же, потому что АМК мод.

Изменено пользователем Полтергейст

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


Ссылка на сообщение
возможно ли как-то изменить отношение непися к игроку в оффлайне?

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

 

В крайнем случае, в оффлайне можно сделать примерно то же самое, только перегрузить функцию community() в se_stalker и подставлять ей принудительные значения. Не знаю правда, как это понравится движку. Можно через net_packet'ы, в amk.script есть соотв. функции.

 

Вообще непонятно, зачем разрабы сделали такие параметры, как health, community и т.п. в виде функций - проще же сделать в виде переменной, и менять её удобнее.

 

xr_logic.script:126: attempt to index local 'st'

Это бывает, когда для какого-то npc не создана таблица db.storage. Бороться с этим бесполезно, надо искать изменения, повлёкшие эти последствия.

Изменено пользователем Полтергейст

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


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

У меня такой вопросик - как сделать, чтобы предметы не прописывались в smart_terrain? Не знаю, как так получается, но в какой-то смарт пытается прописаться какой-нибудь предмет, например, пачка патронов (вызывает register_npc()). Этот глюк, похоже, был и раньше, только smart_terrain.script до редактирования пропускал этот баг (не было отложенного заполнения npc_info -> не вызывались методы, которые есть только у живности), но его ловил amk_offline_alife при вызове npc:alive() (писал, что нет такого метода). Тогда я не обращал на это внимание и просто поставил проверку на наличие функции alive и закрыл на это глаза, оказалось, что зря. Как с этим можно бороться? Фильтрация в suitable(), enabled() и register_npc() не помогает.

 

 

проверять пока он не помрёт и после смерти удалить труп и заспавнить его по новой. И так по кругу

Тогда это нужно делать через se_stalker.script. Отследить по имени секции и при вызове on_death() удалить объект и создать заново. Естественно, удалять только через планировщик отложенного удаления (как в теме про вылеты без логов, только поправить ошибки). Спавнить скорее всего тоже таким же способом, иначе он заспавнится ещё до удаления.

Изменено пользователем Полтергейст

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


Ссылка на сообщение
Заспавнил несколько зомбей на кордоне скриптом. Поймал вылет:

Попробуйте выключить amk_offline_alife. С этими смартами вообще бардак какой-то творится - мало того, что прописывается в них чёрте знает что (предметы, к примеру), так ещё и убрать зависимость онлайн-статуса непися от статуса смарта - куча проблем.

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


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

PavelSnork, надо в самом начале функции дописать вот так:

function parse_condlist(npc, section, field, src)
if npc == nil or src == nil then
   return
end

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


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

Подскажите кто-нибудь, куда поставить колбеки типа

 

callback.zone_enter

callback.zone_exit

 

чтобы срабатывали при входе/выходе из space restrictor. Хочу заменить ими постоянные вызовы zone:inside(position) при обновлении, чтобы кушать меньше рескрсов. :)

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


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

Что понимать под активацией? Если просто использование, то можно написать биндер и в нём поставить callback.use_object. Можно сделать активацию при подборе, тогда уже нужно в bind_stalker править callback на поднятие предмета. А можно вообще заменять им класс на II_ANTIR и далее вешать скрипты также, как на спальный мешок.

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


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

Кто-нибудь пробовал убрать сохранение работ и объектов в смарте, чтобы они каждый раз заново регистрировались при загрузке из сохранения? Реально ли это вообще сделать?

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


Ссылка на сообщение
но проблема в том что когда костюм достигает нулевой кондиции эти сообщения появлются одно за другим эквивалент появления примерно доля сотой секунды

Так это нужно прописывать не в update, а в функцию, вызываемую при попадании (hit_callback). Тогда никаих лишних переменных вводить не придётся.

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


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

Недавно в "ковырялке" кто-то писал про срабатывание коллбеков на выкладывание/взятие предмета при переходах между локациями. Нашёл решение (теоретически, на практике пока не проверялось) этой проблемы.

В некоторых местах разрабы ставили проверку на "чёрный экран", т.е. видит ли игрок что-нибудь, или же ещё идёт загрузка. Чтобы коллбеки вызывались только ПОСЛЕ появления первого кадра игры, надо сделать в bind_stalker.script такие изменения:

 

1. Добавляем переменную, которая показывает, установлены ли коллбеки

function actor_binder:__init (obj) super(obj)
              ...
              self.callbackset = false
              ...
end

2. Переносим в функцию update() все коллбеки, которые не должны вызываться до окончания загрузки.

function actor_binder:update(delta)
              object_binder.update(self, delta)
              ...
              if device().precache_frame >1 then
                            return
              end
              if self.callbackset == false then
                            self.object:set_callback(callback.on_item_take, self.on_item_take, self)
                            self.object:set_callback(callback.on_item_drop, self.on_item_drop, self)
                            self.object:set_callback(callback.trade_sell_buy_item, self.on_trade, self)
                            self.object:set_callback(callback.take_item_from_box, self.take_item_from_box, self)
                            self.object:set_callback(callback.article_info, self.article_callback, self)
              end
              ...

3. В функции reinit должны остаться все остальные коллбеки:

self.object:set_callback(callback.inventory_info, self.info_callback, self)
self.object:set_callback(callback.task_state, self.task_callback, self)
self.object:set_callback(callback.level_border_enter, self.level_border_enter, self)
self.object:set_callback(callback.level_border_exit, self.level_border_exit, self)

Изменено пользователем Полтергейст

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


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

Да, небольшое дополнение: после установки коллбеков (которые в update) надо присвоить self.callbackset = true.

Изменено пользователем Полтергейст

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


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

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

 

Почти весь код реализован в одной функции. Формат таблицы self.anomaly:

self.anomaly[anom_id] = name

anom_id - id аномалии, name - её имя.

function motivation_binder:hear_callback(npc, who, sound_type, sound_position, sound_power)
    if npc == nil or obj == nil then
        return
    end
    local who_id = who:id()
    if who_id == npc:id() or sound_position == nil then
        return
    end
    local cls = who:clsid()
    if cls == clsid.zone_mbald_s or cls == clsid.zone_mincer_s or cls == clsid.zone_galant_s then
        local who_name = who:name()
        local dist = sound_position:distance_to(npc:position())
        if dist <= 45 and self.anomaly[who_id] == nil then
--' Аномалия уже близко, но ещё не добавлена в рестрикторы - добавляем.
            self.anomaly[who_id] = who_name
            self.object:add_restrictions("", who_name)
        elseif dist > 55 and self.anomaly[who_id] ~= nil then
--' Аномалия была добавлена в рестрикторы, но уже далеко - удаляем
            self.object:remove_restrictions("", who_name)
            self.anomaly[who_id] = nil
        end
    end
end

 

 

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

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

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


Ссылка на сообщение
Вероятно ошибся и должно использоваться who из входных аргументов.

Исправил - всё равно не работает. Судя по тому, что выводилось в лог, коллбек "воспринимает" только сталкеров, монстров и (почему-то) детектор игрока. Поэтому такой способ определения аномалий, к сожалению, не годится. :(

 

 

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


Ссылка на сообщение
Можно ли заставить НПС смотреть в ту сторону, в которую я захочу (direction в all.spawn), если спавниш его через скрипт

Это только начальное направление взгляда при спавне. Как-то можно это сделать через net_packet'ы, но проще воспользоваться функцией set_desited_direction(вектор_направления_взгляда). Вот только не знаю, относительно чего этот вектор задаётся - посмотри в логических схемах (скриптах) или в том же state_mgr примеры использования.

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


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

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