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

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

_Призрак_,

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

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

_Призрак_

То, что машина спавнится точно по координатам - никогда не скажу. Т.к. если спавнится в all.spawn'е - то да, 'точно', если скриптом - о точности только помечтать можно ...

Что на нее не действуют законы физики? Хм, и да и нет, но точно, что именно после первого хита, она начинает подчиняется неким игровым 'законам физики'.

Будет ли она скатываться от первого хита? У горе-ковырялкина возможно ... Все зависит от собственно силы и импульса хита. Можно и в небо запулить. ;-)

 

По сути:

Если хочешь точно застопорить машину - то посмотри ранее посты, где давал уже варианты ступоров, т.е. или 'collide' или 'fixed_bones'.

Если же машина для 'езды' - то придется с нет-пакетами (иль еще как) поупражняться, например, отключая ступор(ы) при посадке и включая их при высадке ГГ.

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

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

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

_Призрак_

local obj = -- клиентский объект машины

xr_logic.mob_capture(obj, true) -- берём машину под логику

action(obj, move(move.handbrake, 100), cond(cond.time_end, 5000))

 

Поставив такое на апдейт, ты заставишь машину встать на тормоз, но это касается заведённой машины, насчёт выключенной хз будет работать или нет.

 

Ты можешь сам попробовать - в lua_help найди C++ class move { и пробуй различные варианты.

Методы отлично работают, даже если ГГ в машине.

 

 

 

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

Есть ли способ переместить объекты из инвентаря ГГ в только что заспавненный серверный объект-ящик?

Чтобы обойтись без отлова выхода в онлаин?

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

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

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

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

*Shoker*

Молодец, что и мне напомнил, а то как-то начал делать и ... не закончил.

Однако более правильным будет несколько иначе:

1. Функция/метод остановки и постановки на 'ручник' машины уже полностью реализована в схеме машин ( ph_car.script -> action_car:stop_car() ) и если объект под этой схемой - то и использовать встроенный функционал. Если же не под схемой (чего правда не встречал) - то и работать не будет.

2. В твоей строке задается некий аргумент =100? А это задание условной скорости - т.о. этот аргумент при остановке логично ставить в 0.

3. Дополнительно к 'move.handbrake' есть резон задавать константу остановки 'move.off', т.е. 'move.off + move.handbrake'.

Взятие же машины под контроль удобнее делать под апдейтом самой 'машинной схемы' ( action_car:update(delta) ), что-то типа:

--/ Управление 'ручником' автотранспорта
--/ oCar: game_object машины
--/ bAction: true=>'стоп', false=>'разрешено движение'
function Car_Handbrake(oCar,bAction)
  local st = db.storage[oCar:id()] --/ сторадж объекта
  if st and st.car_mgr then --/ менеджер схемы 'ph_car'
    st.car_mgr .on_handbrake = bAction --/ ставим флаг: вкл/откл ручника
  end
end

function action_car:update(delta) --/ из ph_car.script
  -- ...
  --/ внешнее управление 'ручником' (остановкой)
  if self.on_handbrake and (self.time_handbrake or 0) < time_global() then --/ включить ручник?
    self.time_handbrake = time_global() + 3000 --/ тайм-аут
    self:stop_car()
    self.state_moving = iState_moving_end
  end
end

Примечание: Машина должна быть 'забиндена' (иметь сторадж в db.storage). Постановка на ручник работает независимо от (от)включенного двигателя или отсутсвия актора внутри. При движении машины - естественно ручник (on_handbrake) должен быть 'снят'.

 

---------------------------------------

Переместить объекты из инвентаря ГГ в иной серверный объект (хотя бы и ящик) - невозможно.

Методы трансфера доступны только для гейм-объектов.

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

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

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

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

Всем привет!

 

Хочу поделиться тем что нашел. В конце функции pstor_retrieve в xr_logic есть заремленный 'abort', так вот если его раскоментить и поставить перед return nil, то вылезет очень много проблем с функциями pstor_retrieve. Наподобии этих...

 

! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'timers' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_1' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt1' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_1' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt1' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_2' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt2' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_2' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt2' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_3' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt3' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_3' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt3' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_4' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt4' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_4' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt4' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_5' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt5' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_5' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt5' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_6' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt6' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_6' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt6' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_7' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt7' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_7' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt7' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_8' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt8' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_8' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt8' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_9' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt9' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_9' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt9' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_10' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt10' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_10' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt10' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_11' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt11' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_gtimer_11' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'gt11' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'x_timer_12' does not exist
* Log file has been saved successfully!
! Cannot find saved game ~~~ xr_logic: pstor_retrieve: variable 'xt12' does not exist
* Log file has been saved successfully!
и т д

 

 

И это проблема почти всех модов на базе amk :(

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

Mass,

:))

А зачем ты сделал, то что сделал? А если аборт переставить в начало функции, то вылезет очень много проблем и в оригинальной игре.

Скажи в чем по-твоему заключаются проблемы?

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

abramcumner

Он видимо имел ввиду, что вылезает очень много не найденных переменных в псторе.

 

Mass

Это нормально, т.к когда такая функция вызывается первый раз в игре, обычно вызываемая из пстора переменная ещё не была сохранена, и тогда возвращается не nil, а "значение по умолчанию"

    if defval ~= nil then
        return defval
    end

 

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

 

Иногда бывает что значение по умолчанию = nil, именно это происходит в твоём случае. и это тоже нормально.

 

Artos

Честно говоря я до конца не разбирался в этих функциях, спасибо что разъяснил.

 

1) Это верно, просто в ЧН/ЗП где то из них эти скрипты вырезали. Можно их вернуть конечно, а можно более мелким методом обойтись. Тут уже желание автора будет. :)

2) А где нибудь есть разъяснение, какие аргументы ещё можно передавать в другие move-действия? Ну и в догонку тогда уже интересует

cond(cond.time_end, 5000)

Я так понял, через 5 секунд машина прекратит выполнять это действие, или как? Просто во время моих тестов, насколько я помню, этот параметр ни на что не влиял.

 

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

 

Кстати, в ЧН никто не знает как определить начало\конец торговли? В pda.script из колбеков рабочий тока на открытие окна диалога, а при выходе в окно торговли, диалог считается закрытым, и вещи возвращаются ГГ. Пробовал через инфопоршни, но ui_trade возвращал false.

 

Терь думаю, можно ли присобачить на апдейт level.main_input_receiver(), и отлавливать там появление кнопки "Trade", не будет ли код глючить в игре.

 

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

const trade_start = 0;

const trade_stop = 1;

 

Нашёл такое, надеюсь сработают.

 

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

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

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

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

Подскажите, как можно удалить через скрипт всех имеющихся фантомов на локации?

 

Пример функции:

if (phantom_manager:phantom_count()>1) then 
--Удаление фантомов :-)
end
end

 

P.S. Для ЗП.

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

Jurok

А в чем заминка самому написать простенький скрипт удаления? Ведь все просто и очевидно:

if phantom_manager:phantom_count() > 1 then
  --/ Удаление фантомов
  local sim = alife()
  for id=1,65534 do
    local soObj = sim:object(id)
    if soObj and soObj:clsid() == clsid.phantom then
      alife():release(soObj, true) --/ удаляем
    end
  end
end

или для текущего уровня:

if phantom_manager:phantom_count() > 1 then
  --/ Удаление фантомов на текущем уровне
  local sim = alife()
  for id=1,65534 do
    local oObj = level.object_by_id(id) --/ на текущем уровне?
    if oObj and oObj:clsid() == clsid.phantom then
      local soObj = sim:object(id)
      if soObj then
        alife():release(soObj, true) --/ удаляем
      end
    end
  end
end

 

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

*Shoker*: А где нибудь есть разъяснение, какие аргументы ещё можно передавать в другие move-действия?

Ну и в догонку тогда уже интересует 'cond(cond.time_end, 5000)'

Кроме информации в 'lua_help.script' и кодах оригинальных игр - не встречал толковалок.

Немного сам поразбирался ... Вот что получилось:

move.none,                        --/ 1 
move.on + move.fwd,               --/ 256 +2 вперед
move.on + move.fwd  + move.left,  --/ 256 +2 +8 вперед-налево
move.on + move.fwd  + move.right, --/ 256 +2 +16 вперед-направо
move.on + move.back,              --/ 256 +4 назад
move.on + move.back + move.left,  --/ 256 +4 +8 назад-налево
move.on + move.back + move.right, --/ 256 +4 +16 назад-направо
move.off,                         --/ 512 стоп
move.off + move.handbrake         --/ 512 +128 стоп+постановка на ручник

 

Да и по 'cond.time_end' также только догадки. Судя по тестам - ты прав в догадке, что это таймер периода окончания действия, которое устанавливается строкою: action( object, move(const, speed), cond(const, time) ), после которого (судя по тестам) вызывается новая (пере)установка 'action'.

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

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

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

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

Переписываю схему heli hunter: в функции evaluator_shoot:evaluate() делаю проверку на огневую мощь НПС, при выполнении условия отправляю их в укрытие.

if self.fire_power < 3 then
    self.object:set_detail_path_type(move.line)
    self.object:set_path_type(game_object.level_path)
    local hide,lvid = nearest_hide(self.object)
    utils.send_to_nearest_accessible_vertex(self.object,lvid)
    state_mgr.set_state(self.object,"sprint")
    return false
end

--[[------------------------------------------------------------------------------------------------------------------
Схема "Охотник за вертолётами"
Чугай Александр
--------------------------------------------------------------------------------------------------------------------]]

local def_attack_dist = 200 -- расстояние, на котором вертолёт может быть атакован
local def_actor_dist  = 50  -- расстояние, на котором игрок может быть атакован

function get_nearest_heli(npc_position, attack_dist_sqr)
--    print_table(db.heli)

    local heli = nil

    for k,v in pairs(db.heli) do
        if v:position():distance_to_sqr(npc_position) <= attack_dist_sqr and
           (heli == nil or
           v:position():distance_to_sqr(npc_position) < heli:position():distance_to_sqr(npc_position))
        then
            heli = v
        end
    end

    return heli
end
---------------------------------------------------------------------------------------------------------------------
-- Эвалуатор свойства "можно пострелять по вертолёту"
---------------------------------------------------------------------------------------------------------------------
local overrides

class "evaluator_shoot" ( property_evaluator )

function evaluator_shoot:__init( name, a ) super( nil, name )
    self.a = a
end

function evaluator_shoot:evaluate()

        if self.delay and self.delay >= time_global() then
            return false
        end

        self.a.heli = get_nearest_heli(self.object:position(), self.a.attack_dist_sqr)
        self.fire_power = heli_target.get_target_priority(self.object)
        
        if self.a.heli == nil then
            self.delay = time_global() + 500
            return false
        end
        
        --проверка на группировку
        if db.storage[self.a.heli:id()].community ~= nil and (db.storage[self.a.heli:id()].community == self.object:character_community()) then
            return false
        end

        --Проверка на огневую мощь
        if self.fire_power < 3 then
            self.object:set_detail_path_type(move.line)
            self.object:set_path_type(game_object.level_path)
            hide,lvid,dist = blowout_scheme.nearest_hide(self.object)
            utils.send_to_nearest_accessible_vertex(self.object,lvid)
            state_mgr.set_state(self.object,"sprint")
            return false
        end

        -- Проверка на то, что вертолет еще живой.
        if not bind_heli.is_heli_alive(self.a.heli) then
            self.a.heli = nil
            return false
        end

        -- проверка не потерялся ли вертолет.
--        if db.heli[self.a.heli:id()] ~= nil and
--        printf( "dist=%d", self.a.heli:position():distance_to_sqr(self.object:position()) )
        if self.a.heli:position():distance_to_sqr(self.object:position()) > self.a.attack_dist_sqr then
            self.a.heli = nil
            return false
        end

        -- Проверка на то, что враг-игрок не подошел слишком близко
        local best_enemy = self.object:best_enemy()
        if best_enemy and
           best_enemy:id() == db.actor:id()
        then
            if db.actor:position():distance_to_sqr(self.object:position()) < self.a.attack_actor_sqr then
                return false
            end
        end

        -- Проверка на то, что денжер-игрок не подошел слишком близко
        local best_danger = self.object:best_danger()
        if best_danger then
           local bd_object = best_danger:object()
           if bd_object ~= nil and
              bd_object:id() == db.actor:id()
           then
                if best_danger:position():distance_to_sqr(self.object:position()) < self.a.attack_actor_sqr then
                    return false
                end
           end
        end
        return true
end

----------------------------------------------------------------------------------------------------------------------
-- Действие "стрелять по вертолёту"
----------------------------------------------------------------------------------------------------------------------
class "action_shoot" ( action_base )

function action_shoot:__init( name, a )  super ( nil, name )
    self.a = a
end

function action_shoot:initialize()
    action_base.initialize( self )

end

function action_shoot:execute()
    action_base.execute( self )
    
        state_mgr.set_state( self.object, "threat_fire", nil, nil,
                         {look_object = self.a.heli}, nil, nil, {yaw_delta=10} )    

end

function action_shoot:finalize()
    action_base.finalize( self )
    --self.fire_power = nil
    self.camp = nil
    self.need_cover = nil
self.object:movement_enabled(true)
end

----------------------------------------------------------------------------------------------------------------------

function add_to_binder( npc, ini, scheme, section, storage )
    printf( "DEBUG: add_to_binder: scheme='%s'", scheme )

    local manager = npc:motivation_action_manager()

    manager:add_evaluator( xr_evaluators_id.chugai_heli_hunter_base, evaluator_shoot( "heli_hunter", storage ) )

    local action = this.action_shoot( "action_shoot", storage )
    action:add_precondition( world_property(stalker_ids.property_alive,               true  ) )
    action:add_precondition( world_property(xr_evaluators_id.chugai_heli_hunter_base, true  ) )
    action:add_effect      ( world_property(xr_evaluators_id.chugai_heli_hunter_base, false ) )
    manager:add_action( xr_actions_id.chugai_heli_hunter_base, action )

    action = manager:action( xr_actions_id.alife )
    action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) )

    action = manager:action( stalker_ids.action_combat_planner )
    action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) )

    action = manager:action( stalker_ids.action_danger_planner )
    action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) )
end

function set_scheme( npc, ini, scheme, section )
    printf( "DEBUG: set_scheme: scheme='%s' section='%s'", scheme, utils.to_str(section) )

    local a = xr_logic.assign_storage_and_bind( npc, ini, scheme, section )

    a.attack_dist_sqr = math.pow( utils.cfg_get_number( ini, section, "dist", npc, false, def_attack_dist ), 2 )
    a.attack_actor_sqr = math.pow( utils.cfg_get_number( ini, section, "actor_dist", npc, false, def_actor_dist ), 2 )
    a.heli = nil
    a.enabled = true
end

function disable_scheme(npc, scheme)
    local st = db.storage[npc:id()][scheme]
    if st then
        st.enabled = false
    end
end

 

 

НПС бегут в укрытие, но когда вертолет улетает\взрывается НПС так и остаются там стоять пока с ними не поговоришь.

Как вернуть НПС под свою изначальную логику (или что я делаю неправильно)?

 

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

KASIMKA

Твоя ошибка: в непонимании структуры и функционирования 'схемы'.

Условно: схемы состоят из трех частей:

- функции 'set/disable' (пресетов) - установка, сброс, биндер (активация), ...

- методы 'evaluators' - проверки условий схемы

- методы 'actions' - выполнение действий схемы

 

Если схема активна для объекта - то эвалуаторы схемы вызываются постоянно(!) и в зависимост от проверок различных условий - на выход передают булево значение (истина/лож) о результате проверки. По этим результатам от эвалуаторов - могут запускаться/останавливаться экшены (выполнение действий схемы) и запускаться/блокироваться другие схемы.

 

Ты вставил свой кусок кодов 'Проверка на огневую мощь' в эвалуатор схемы. По сути ты вставил кусок экшена (действия), которые должен выполнять объект при определенном тобою условии. При выпонении условия: 'self.fire_power < 3', которое постоянно(!) проверяется в активном эвалуаторе - ты вынуждаешь объект обязательно выполнять действие (бежать в укрытие).

Что же удивляться, что твой НПС подчиняется твоим же указаниям?

В эвалуаторе требуется только проверять условие! И уже по результату этой проверки - вызывать выполнение нужного действия. При чем(!) выполнение действия должно иметь окончание! Т.е. по достижении цели действия (в твоем случае - добежал до укрытия) - его выполнение должно быть прекращено.

 

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

 

Резюме: Перед правкой/созданием схем - требуется знать и понимать общую структуру схем и их взаимодействий и написать алгоритм работы схемы, который и воплощать в кодах (а не наоборот).

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

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

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

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

Заранее спасибо.

 

Запотевание (да и др. эффекты) достигается 'показом' соответствующих текстур. Нет 'точек из которых выходит запотевание'. Есть только координаты (экрана) по которым выводятся чередующиеся тектуры, которые прописаны в конфиг-файлах (см. xml-ки).

--/ Artos

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

Команда ReWrite Team. От сталкера отошли. Пересели за другую платформу.

 

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

Убедительная просьба к спрашивающим:

Не пытаться продолжать обсуждение заданного в топике вопроса в ЛС без вестких на то причин.

Топик на то и создан, чтобы задавать вопросы и разбираться с ними.

 

Избегайте адресовать (без причины) вопросы(ы) конкретно кому-то.

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

 

Не адресуйте вопрос к 'толпе', типа: "Народ! ..." или "Люди! ...".

Мы не в пустыне, вы не на трибуне и Нелюди вам все одно не ответят. А вот те, кто себя не ассоциирует с 'толпой' - могут промолчать ...

 

Так же, задавая вопрос, не нужно (тем более кажды раз) 'здороваться'.

Это все же форум, а не очная встреча. Ваше "Доброе утро", странно кому-то читать позней ночью, через пару дней, и может оно и не очень у кого-то 'доброе' ...

Избегайне неинформативной 'дипломатии' и излишних 'расшаркиваний' ...

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

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

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

:russian_ru: В том то и дело что координаты точек запотевания ни где в конфигах этого мода я не нашел.

 

0. Ты и НЕ искал.

1. Уже было сказано, что НЕТ точек запотевания ...

2. Не стОит путать вопросы по теме с просьбами научить азам скриптования (LUA) или вообще с функционированием игры и обучению азам создания модификаций.

В данном моде всего лишь 1 (один!) конфиг-файл 'ui_custom_msgs.xml' и не увидеть в нем отделенные комментарием '<!-- Dinamic HUD -->' записи именно мода - может только слепой или с лентяй.

В папке текстур не так уж и много текстур и несложно просмотреть и увидеть, что к запотеванию относятчя 'breathN.dds' - тестуры (5 шт). К сведению само название говорит за себя: 'breath' -> 'дыхание'

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

Если же тебе захотелось самому 'подвигать' скриптами эти тектуры - то врядли кто (думаю и сам автор мода) будет расписывать весь алгоритм вывода запотевания на экран ...

Совет:

1. Выбирать похотелки себе 'по плечу', а не замахиваться на то, что не по силам и не по познаниям.

2. Изучай основы/азы, ФАКи, статьи. На форуме нет нянек и учителей, которые все в сотый раз кому-то персонально разжуют иль растолкуют.

--/ Artos

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

Команда ReWrite Team. От сталкера отошли. Пересели за другую платформу.

 

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

Пытаюсь подредактировать схему heli hunter.

В своем предыдущем посте я пытался вызвать реакцию НПС на вертолет прямо из эвалуатора. Т.к. это неправильно - перенес действия в action: если раньше они хотя бы убегали, то теперь стеляют по вертолету вообще игнорируя условия:

--[[------------------------------------------------------------------------------------------------------------------
Схема "Охотник за вертолётами"
Чугай Александр
--------------------------------------------------------------------------------------------------------------------]]

local def_attack_dist = 200 -- расстояние, на котором вертолёт может быть атакован
local def_actor_dist  = 50  -- расстояние, на котором игрок может быть атакован

function get_nearest_heli(npc_position, attack_dist_sqr)
--    print_table(db.heli)

    local heli = nil

    for k,v in pairs(db.heli) do
        if v:position():distance_to_sqr(npc_position) <= attack_dist_sqr and
           (heli == nil or
           v:position():distance_to_sqr(npc_position) < heli:position():distance_to_sqr(npc_position))
        then
            heli = v
        end
    end

    return heli
end
---------------------------------------------------------------------------------------------------------------------
-- Эвалуатор свойства "можно пострелять по вертолёту"
---------------------------------------------------------------------------------------------------------------------
local overrides

class "evaluator_shoot" ( property_evaluator )

function evaluator_shoot:__init( name, a ) super( nil, name )
    self.a = a
end

function evaluator_shoot:evaluate()


        if self.delay and self.delay >= time_global() then
            return false
        end

        self.a.heli = get_nearest_heli(self.object:position(), self.a.attack_dist_sqr)

        --провека на существование вертолета
        if self.a.heli == nil then
            self.delay = time_global() + 500
            self.hide = nil
            return false
        end
        
        --проверка на группировку
        if db.storage[self.a.heli:id()].community ~= nil and (db.storage[self.a.heli:id()].community == self.object:character_community()) then
            return false
        end

        -- проверка на то, что вертолет еще живой.
        if not bind_heli.is_heli_alive(self.a.heli) then
            self.a.heli = nil
            return false
        end


        self.fire_power = heli_target.get_target_priority(self.object)

        --Проверка на огневую мощь
        if self.fire_power < 3 then
            self.hide = true
            --return false
        end

        -- проверка не потерялся ли вертолет.
--        if db.heli[self.a.heli:id()] ~= nil and
--        printf( "dist=%d", self.a.heli:position():distance_to_sqr(self.object:position()) )
        if self.a.heli:position():distance_to_sqr(self.object:position()) > self.a.attack_dist_sqr then
            self.a.heli = nil
            return false
        end

        -- Проверка на то, что враг-игрок не подошел слишком близко
        local best_enemy = self.object:best_enemy()
        if best_enemy and
           best_enemy:id() == db.actor:id()
        then
            if db.actor:position():distance_to_sqr(self.object:position()) < self.a.attack_actor_sqr then
                return false
            end
        end

        -- Проверка на то, что денжер-игрок не подошел слишком близко
        local best_danger = self.object:best_danger()
        if best_danger then
           local bd_object = best_danger:object()
           if bd_object ~= nil and
              bd_object:id() == db.actor:id()
           then
                if best_danger:position():distance_to_sqr(self.object:position()) < self.a.attack_actor_sqr then
                    return false
                end
           end
        end
        
        return true
end

----------------------------------------------------------------------------------------------------------------------
-- Действие "стрелять по вертолёту"
----------------------------------------------------------------------------------------------------------------------
class "action_shoot" ( action_base )

function action_shoot:__init( name, a )  super ( nil, name )
    self.a = a
end

function action_shoot:initialize()
    action_base.initialize( self )

end

function action_shoot:execute()
    action_base.execute( self )
    
    if self.hide == true then
        self.object:set_detail_path_type(move.line)
        self.object:set_path_type(game_object.level_path)
        hide,lvid,dist = blowout_scheme.nearest_hide(self.object)
        utils.send_to_nearest_accessible_vertex(self.object,lvid)
        state_mgr.set_state(self.object,"sprint")
    else
        state_mgr.set_state( self.object, "threat_fire", nil, nil,
                         {look_object = self.a.heli}, nil, nil, {yaw_delta=10} )    
    end

end

function action_shoot:finalize()
    action_base.finalize( self )
    self.fire_power = nil
    self.camp = nil
    self.hide = nil
self.object:movement_enabled(true)
end

----------------------------------------------------------------------------------------------------------------------

function add_to_binder( npc, ini, scheme, section, storage )
    printf( "DEBUG: add_to_binder: scheme='%s'", scheme )

    local manager = npc:motivation_action_manager()
    manager:add_evaluator( xr_evaluators_id.chugai_heli_hunter_base, evaluator_shoot( "heli_hunter", storage ) )

    local action = this.action_shoot( "action_shoot", storage )
    action:add_precondition( world_property(stalker_ids.property_alive,               true  ) )
    action:add_precondition( world_property(xr_evaluators_id.chugai_heli_hunter_base, true  ) )
    action:add_effect      ( world_property(xr_evaluators_id.chugai_heli_hunter_base, false ) )
    manager:add_action( xr_actions_id.chugai_heli_hunter_base, action )

    action = manager:action( xr_actions_id.alife )
    action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) )

    action = manager:action( stalker_ids.action_combat_planner )
    action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) )

    action = manager:action( stalker_ids.action_danger_planner )
    action:add_precondition( world_property( xr_evaluators_id.chugai_heli_hunter_base, false ) )
end

function set_scheme( npc, ini, scheme, section )
    printf( "DEBUG: set_scheme: scheme='%s' section='%s'", scheme, utils.to_str(section) )

    local a = xr_logic.assign_storage_and_bind( npc, ini, scheme, section )

    a.attack_dist_sqr = math.pow( utils.cfg_get_number( ini, section, "dist", npc, false, def_attack_dist ), 2 )
    a.attack_actor_sqr = math.pow( utils.cfg_get_number( ini, section, "actor_dist", npc, false, def_actor_dist ), 2 )
    a.heli = nil
    a.enabled = true
end

function disable_scheme(npc, scheme)
    local st = db.storage[npc:id()][scheme]
    if st then
        st.enabled = false
    end
end

function get_target_priority(obj)
    if not obj then return 0 end
    --qqq(obj:section())
    local prior = 1
    if IsMonster(obj) then
    --    qqq("monster")
        prior = 1
    elseif IsStalker(obj) then -- максимум - 5
        local wpn = obj:item_in_slot(obj:active_slot())
        if wpn then
            local ammo, fm
            if system_ini():line_exist(wpn:section(), "ammo_class") then
                ammo = system_ini():r_string(wpn:section(), "ammo_class")
                if (string.find(ammo, "9x18") -- пистолетные патроны
                    or string.find(ammo, "9x19")
                    or string.find(ammo, "7.62x25")
                    or string.find(ammo, "11.43x23")
                    or string.find(ammo, "357")
                    or string.find(ammo, "samopal") --  + патроны к самопалу
                    or string.find(ammo, "bolt") --  + арбалетные болты
                    or string.find(ammo, "12x7")) --  + патроны для дробовиков
                    then
                    prior = prior + 1
                elseif (string.find(ammo, "5.45x39") -- промежуточные патроны
                    or string.find(ammo, "5.56x45") 
                    or string.find(ammo, "7.62x39")
                    or string.find(ammo, "9x39"))
                    then
                    prior = prior + 2
                elseif (string.find(ammo, "7.62x51") -- винтовочные патроны
                    or string.find(ammo, "7.62x54")
                    or string.find(ammo, "7.92x75"))
                    then
                    prior = prior + 3
                else
                    prior = prior + 4
                end
            end
            if system_ini():line_exist(wpn:section(), "fire_modes") then
                fm = system_ini():r_string(wpn:section(), "fire_modes")
                if string.sub(fm,-2,-1) == "-1" then
                    prior = prior + 1 -- автоматическое оружие - приоритет цели выше на 1
                end
            end
        --qqq(wpn:section())
        end
    elseif string.find(obj:name(),"btr") then
        prior = 6
    elseif (string.find(obj:section(),"helicopter") or string.find(obj:section(),"mi2")) then
        prior = 7
    end
    
    --qqq(prior)
    return prior
end

 

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

 

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

 

Используйте тэги

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

--/ Artos

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

KASIMKA

1. Применяя конструкции типа: 'self.var_name = ...' следует учитывать, к чему относится 'self'.

Устанавливая в эвалуаторе 'self.hide = true' - бессмыслено проверять значение этой переменной в экшене, т.е. она всегда будет равна 'nil'.

В данном случае 'self.hide' - это переменная, область которой ограничена классом эвалуактора 'evaluator_shoot' и вне его она недоступна.

Для того, чтобы использовать нужную переменную и в экшене ('action_shoot') можно или вынести эту переменную на уровень локальной/глобальной переменной корня скрипт-файла или же использовать типовой прием: 'self.a.hide = true', помещая ее в единый сторадж ('self.a') данной схемы и читать из экшена этой же схемы аналогично: 'if self.a.hide == true then'

 

2. Из контекста вопроса(ов), можно сделать вывод, что тебе хочется, чтобы при отсутствии необходимого оружия для стрельбы по вертолетем - НПС убегал в укрытие, если же 'имеет' - неясно ... (вероятно не должен убегать, а стрелять по вертушке/сражаться).

Данная схема имеет только один эвалуатор и один экшен:

- проверка - "можно пострелять по вертолёту"

- действие - "стрелять по вертолёту"

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

Если, как в 1-ый раз, вставлять проверку и действие в общий эвалуатор - ресурсоемкая проверка будет съедать немало ресурсов и будет приводить к тому, что НПС при отсутствии подходящего оружия и при наличии 'живого' вертолета на локации - всегда будут бежать прятаться.

 

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

 

3. Функция 'get_target_priority(obj)' очень неоптимальна. Использовать постоянные прямые перечтения файлов конфигурации - значительная нагрузка на русурсы. Тем более для эвалуаторов (по сути как апдейт НПС) эта функция мягко говоря 'тяжела'.

а) Можно заранее один раз прочитать все конфиги оружия и патронов к нему и занести в таблицу, из которой и пользоваься;

б) Постепенное чтение (по мере смены активного оружия) с запоминанием в таблицу нужных значений;

в) Можно один раз проверить и запомнить активное оружие и, если оно не менялось - не перепроверять его каждым вызовом функции;

г) Комбинация а), б), в).

 

P.S. В дополнение к п.2

Можно попробовать обойтись и имеющейся парой в схеме.

В проверке (эвалуаторе) определять необходимость действия (стрелять или прятаться => true).

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

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

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

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

Всем доброго времени суток. Возник такой вопрос: какой файл(скрипт, конфиг) запрещает на какой-либо локации спавнить нпс определённого ранга? Хочу при респавне на кордоне заспавнить бандюков в ранге "мастер", но простым редактированием spawn_sections.ltx это у меня не получается. Подскажите решение, пожалуйста.

 

Задавайте вопросы более внятно.

1. 'Запрет' и 'не разрешение' - различные понятия. Нет нкаких запретов на (ре)спавн по рангам и по локациям. Имеются нте или иные конфиги/параметры. И если чего-то нет или параметр 'мал' - то не нужно путуть с запретом.

2. 'Респавном' - не спавнят, это 'автоматическое' событие, и тем более, при чем тут редактирование 'spawn_sections.ltx'?

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

--/ Artos

 

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

Именно настроить респавн на кордоне, на АТП. В 'spawn_sections.ltx' прописывается ранг нпс при респавне и простое изменение новичков на мастеров не срабатывает. Почему?

 

Потому что метод тыка в подобных вещах порочен и практически на 100% бесполезен.

В 'spawn_sections.ltx' прописаны СЕКЦИИ объектос (НПС), в которых в отличии от исходной родительской секции, дополнительно прописываются треьуемые параметры, в том числе и ранг. Эти секции предназначены для любого спавна (само название файла говорит за себя!) и 'респавн' - это только частный случай.

Респавны в игре НЕ читают рангов, а оперирует названиями секций и группировками.

--/ Artos

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

Лучше спросить глупость, чем её совершить.

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

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

[esc_bandit_respawn_2]:stalker
$spawn =  "respawn\esc_bandit_respawn_2"
character_profile = sim_bandit_master
spec_rank = master
community = bandit

И респонер при срабатывании выдаст тебе бандюгу-мастера. Но учти, что бандюги-мастера на Кордоне "жить" не смогут (в оргинале смарт "esc_fabrika_bandit"), т.к. в настройках сталкеры такого ранга не берутся в смарты Кордона (файл smart_terrain_presets.ltx). Поэтому, такой NPC заспонится только в случае, если где-то в каком-то "бандитском" смарте на бескрайних просторах Зоны имеется свободное место, подходящее по параметрам (группировка - бандит, ранг - мастер), и тогда, после своего "рождения", свеженький NPC тут же отправится в путешествие на ту локацию, где расположен пресловутый смарт.

А если тебе нужно, чтобы мастера-бандюги "жили" на Кордоне, в файле smart_terrain_presets.ltx измени (добавь) в секцию [l01_escape] бандитов-мастеров:

[l01_escape]
...
bandit = novice, experienced, master
...

 

Другое дело, как это скажется на общей картине (мастера на Кордоне крутовато-с :)), но тебе виднее, конечно... С другой стороны, можно, наверное, "поселить" одного бандюгу-мастера на Кордоне (ну, типа, это, "пахана" ;)). Как это сделать? Сделать это можно, добавив условие на какую-нибудь одну работу в гулаге смарта бандюков на АТП (файл gulag_escape.script), допускающее, что на эту самую работу может быть назначен либо сталкер (бандит) с рангом "мастер", либо, например, только NPC с именем "sim_bandit_master".

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

=VENOM=

Возражу и поправлю.

Файл 'smart_terrain_presets.ltx' является конфигом, который предназначен только для универсальных гулагов типа 'general_lager'.

Гулаг, о котором и в вопросе и ты говоришь - 'esc_fabrika_bandit' - именнОй.

1. Именно для этого гулага в all.spawn'е организован респавнер 'esc2_respawn_bandits_fabrika', в котором и прописаны секции, которые будут спавниться (esc_bandit_respawn_1, esc_bandit_respawn_2). Т.е. если в респавнер добавить секции бандитов с рангом мастеров - то они и заспавнятся (если не будет иных ограничений). Изменять в исходных секциях я очень бы не рекомендовал, т.к. изменять секции, предназначенные для всей Зоны, ради одного гулага - ну очень недальновидно. Ни что не мешает просто добавить секции 'esc_bandit_respawn_3' и 'esc_bandit_respawn_4' с рангами ветерана и мастера, если не устраивают готовые (cit_bandit_respawn_1, cit_bandit_respawn_2 - ветеран и мастер).

2. Условия приема для этого гулага прописаны в 'gulag_escape.script' и ограничение имеется только одно - по группировке. Т.е. любой бандит будет взят в гулаг при условии наличия свободной работы.

Т.о. для 'заматерелости' АТП достаточно только правильно настроить респавнер этого гулага, внеся желаемые секции спавна (при недостатке - досоздать).

 

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

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

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

Artos, а какие могут быть иные ограничения? Дописать секции в спавнере не проблема.

Ну во первых не в 'спавнер', а в конфиг секций для спавна. 'Спавнером' все же называют иль скрипт иль схему (se_respawn).

Во-вторых, имел ввиду в основном уже имеющиеся секции, которые могут иметь и кастомдату, иль в кодах игры именно этим секциям добавлена логика/ограничения.

Дописанные новые - врядли будут иметь ограничения. Хотя дописывать? ... Упомянутые 'cit'- бандиты все одно являются рудиментами от вырезенной локации и ограничений для подобного спавна также не имеют.

--/ Artos

 

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

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

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

Но НПС, заспавненные на локации, если им не прописано '[smart_terrains] none = true' - не будут бродить, а проследуют на те локации, где им найдется работенка. Конечно строго по сетке и отвлекаясь на опасности иль подобное.

 

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

Хорошо, тогда как сделать привязку нпс к определённой локации?

Хм, ... привязать его к какому-либо смарту/гулагу на какой-либо локации. :-)

И навязать ему работу из этого смарта/гулага (хоть на другой локации).

Работа должна быть по координатам для нужной локации (не обязательно одной с гулагом ее дающим).

--/ Artos

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

Лучше спросить глупость, чем её совершить.

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

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

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

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

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

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

Войти

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

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

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

AMK-Team.ru

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