abramcumner 1 151 Опубликовано 7 Сентября 2011 Поделиться Опубликовано 7 Сентября 2011 (изменено) _Призрак_, у машины небось стоит маленькая масса, а у гранаты большой импульс - обычная физика Скажи спасибо, что машина вообще не взрывается. Изменено 7 Сентября 2011 пользователем abramcumner Ссылка на комментарий
Artos 99 Опубликовано 7 Сентября 2011 Поделиться Опубликовано 7 Сентября 2011 (изменено) _Призрак_ То, что машина спавнится точно по координатам - никогда не скажу. Т.к. если спавнится в all.spawn'е - то да, 'точно', если скриптом - о точности только помечтать можно ... Что на нее не действуют законы физики? Хм, и да и нет, но точно, что именно после первого хита, она начинает подчиняется неким игровым 'законам физики'. Будет ли она скатываться от первого хита? У горе-ковырялкина возможно ... Все зависит от собственно силы и импульса хита. Можно и в небо запулить. ;-) По сути: Если хочешь точно застопорить машину - то посмотри ранее посты, где давал уже варианты ступоров, т.е. или 'collide' или 'fixed_bones'. Если же машина для 'езды' - то придется с нет-пакетами (иль еще как) поупражняться, например, отключая ступор(ы) при посадке и включая их при высадке ГГ. Изменено 7 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
*Shoker* 322 Опубликовано 7 Сентября 2011 Поделиться Опубликовано 7 Сентября 2011 (изменено) _Призрак_ 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 мин.: Есть ли способ переместить объекты из инвентаря ГГ в только что заспавненный серверный объект-ящик? Чтобы обойтись без отлова выхода в онлаин? Изменено 7 Сентября 2011 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Artos 99 Опубликовано 8 Сентября 2011 Поделиться Опубликовано 8 Сентября 2011 (изменено) *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) должен быть 'снят'. --------------------------------------- Переместить объекты из инвентаря ГГ в иной серверный объект (хотя бы и ящик) - невозможно. Методы трансфера доступны только для гейм-объектов. Если же под 'перемещением' подразумевается возможность удаление предмета и воссоздание его копии в нужном месте - это иной разговор ... Думаю мороки будет поболе, чем дождаться перехода ящика в онлайн, если озаботиться точными копиями ... Изменено 8 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Mass 5 Опубликовано 8 Сентября 2011 Поделиться Опубликовано 8 Сентября 2011 (изменено) Всем привет! Хочу поделиться тем что нашел. В конце функции 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 Изменено 8 Сентября 2011 пользователем Mass Ссылка на комментарий
abramcumner 1 151 Опубликовано 8 Сентября 2011 Поделиться Опубликовано 8 Сентября 2011 Mass, ) А зачем ты сделал, то что сделал? А если аборт переставить в начало функции, то вылезет очень много проблем и в оригинальной игре. Скажи в чем по-твоему заключаются проблемы? Ссылка на комментарий
*Shoker* 322 Опубликовано 8 Сентября 2011 Поделиться Опубликовано 8 Сентября 2011 (изменено) 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; Нашёл такое, надеюсь сработают. Изменено 8 Сентября 2011 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Ссылка на комментарий
Painter 3 382 Опубликовано 8 Сентября 2011 Поделиться Опубликовано 8 Сентября 2011 (изменено) Подскажите, как можно удалить через скрипт всех имеющихся фантомов на локации? Пример функции: if (phantom_manager:phantom_count()>1) then --Удаление фантомов :-) end end P.S. Для ЗП. Изменено 8 Сентября 2011 пользователем Jurok Портфолио Ссылка на комментарий
Artos 99 Опубликовано 8 Сентября 2011 Поделиться Опубликовано 8 Сентября 2011 (изменено) 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'. Изменено 8 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
KASIMKA 0 Опубликовано 8 Сентября 2011 Поделиться Опубликовано 8 Сентября 2011 Доброго времени суток! Переписываю схему 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 НПС бегут в укрытие, но когда вертолет улетает\взрывается НПС так и остаются там стоять пока с ними не поговоришь. Как вернуть НПС под свою изначальную логику (или что я делаю неправильно)? Ссылка на комментарий
Artos 99 Опубликовано 8 Сентября 2011 Поделиться Опубликовано 8 Сентября 2011 (изменено) KASIMKA Твоя ошибка: в непонимании структуры и функционирования 'схемы'. Условно: схемы состоят из трех частей: - функции 'set/disable' (пресетов) - установка, сброс, биндер (активация), ... - методы 'evaluators' - проверки условий схемы - методы 'actions' - выполнение действий схемы Если схема активна для объекта - то эвалуаторы схемы вызываются постоянно(!) и в зависимост от проверок различных условий - на выход передают булево значение (истина/лож) о результате проверки. По этим результатам от эвалуаторов - могут запускаться/останавливаться экшены (выполнение действий схемы) и запускаться/блокироваться другие схемы. Ты вставил свой кусок кодов 'Проверка на огневую мощь' в эвалуатор схемы. По сути ты вставил кусок экшена (действия), которые должен выполнять объект при определенном тобою условии. При выпонении условия: 'self.fire_power < 3', которое постоянно(!) проверяется в активном эвалуаторе - ты вынуждаешь объект обязательно выполнять действие (бежать в укрытие). Что же удивляться, что твой НПС подчиняется твоим же указаниям? В эвалуаторе требуется только проверять условие! И уже по результату этой проверки - вызывать выполнение нужного действия. При чем(!) выполнение действия должно иметь окончание! Т.е. по достижении цели действия (в твоем случае - добежал до укрытия) - его выполнение должно быть прекращено. Примечание: По отсутстующему в оригинальной игре (heli_target) невозможно сказать сбрасывается ли у тебя 'self.fire_power', иль вообще принимает какие-то значения для отмены условия. Резюме: Перед правкой/созданием схем - требуется знать и понимать общую структуру схем и их взаимодействий и написать алгоритм работы схемы, который и воплощать в кодах (а не наоборот). Изменено 8 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Gektor 0 Опубликовано 9 Сентября 2011 Поделиться Опубликовано 9 Сентября 2011 (изменено) Добрый день. Такой вопрос, как регулировать положение точек из которых выходит запотевание в моде динамических худов противогаза от Bak'а (ссылка)? Помогите пожалуйста разобратся . Заранее спасибо. Запотевание (да и др. эффекты) достигается 'показом' соответствующих текстур. Нет 'точек из которых выходит запотевание'. Есть только координаты (экрана) по которым выводятся чередующиеся тектуры, которые прописаны в конфиг-файлах (см. xml-ки). --/ Artos Изменено 9 Сентября 2011 пользователем Artos Команда ReWrite Team. От сталкера отошли. Пересели за другую платформу. Ссылка на комментарий
Artos 99 Опубликовано 9 Сентября 2011 Поделиться Опубликовано 9 Сентября 2011 (изменено) Убедительная просьба к спрашивающим: Не пытаться продолжать обсуждение заданного в топике вопроса в ЛС без вестких на то причин. Топик на то и создан, чтобы задавать вопросы и разбираться с ними. Избегайте адресовать (без причины) вопросы(ы) конкретно кому-то. Вам могут дать на тот же вопрос и другие форумчане, а не только выбранный Вами адресат. Не адресуйте вопрос к 'толпе', типа: "Народ! ..." или "Люди! ...". Мы не в пустыне, вы не на трибуне и Нелюди вам все одно не ответят. А вот те, кто себя не ассоциирует с 'толпой' - могут промолчать ... Так же, задавая вопрос, не нужно (тем более кажды раз) 'здороваться'. Это все же форум, а не очная встреча. Ваше "Доброе утро", странно кому-то читать позней ночью, через пару дней, и может оно и не очень у кого-то 'доброе' ... Избегайне неинформативной 'дипломатии' и излишних 'расшаркиваний' ... Изменено 9 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
Gektor 0 Опубликовано 9 Сентября 2011 Поделиться Опубликовано 9 Сентября 2011 (изменено) В том то и дело что координаты точек запотевания ни где в конфигах этого мода я не нашел. 0. Ты и НЕ искал. 1. Уже было сказано, что НЕТ точек запотевания ... 2. Не стОит путать вопросы по теме с просьбами научить азам скриптования (LUA) или вообще с функционированием игры и обучению азам создания модификаций. В данном моде всего лишь 1 (один!) конфиг-файл 'ui_custom_msgs.xml' и не увидеть в нем отделенные комментарием '<!-- Dinamic HUD -->' записи именно мода - может только слепой или с лентяй. В папке текстур не так уж и много текстур и несложно просмотреть и увидеть, что к запотеванию относятчя 'breathN.dds' - тестуры (5 шт). К сведению само название говорит за себя: 'breath' -> 'дыхание' Т.о. найти и определить координаты, куда выводятся тесктуры - минутное дело и не требует сколь-нибудь заумных познаний. Если же тебе захотелось самому 'подвигать' скриптами эти тектуры - то врядли кто (думаю и сам автор мода) будет расписывать весь алгоритм вывода запотевания на экран ... Совет: 1. Выбирать похотелки себе 'по плечу', а не замахиваться на то, что не по силам и не по познаниям. 2. Изучай основы/азы, ФАКи, статьи. На форуме нет нянек и учителей, которые все в сотый раз кому-то персонально разжуют иль растолкуют. --/ Artos Изменено 9 Сентября 2011 пользователем Artos Команда ReWrite Team. От сталкера отошли. Пересели за другую платформу. Ссылка на комментарий
KASIMKA 0 Опубликовано 9 Сентября 2011 Поделиться Опубликовано 9 Сентября 2011 (изменено) Пытаюсь подредактировать схему 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 Изменено 9 Сентября 2011 пользователем Artos Ссылка на комментарий
Artos 99 Опубликовано 9 Сентября 2011 Поделиться Опубликовано 9 Сентября 2011 (изменено) 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). А в действии (экшене) перепроверять условие 'стрелять иль прятаться' (т.е. наличие нужного оружия) и выбирать соответствующую ветвь действия, что конечно потребует экшен разделить на две ветки (вторую ветку 'прятаться' самому написать на базе уже написанных кодов). Изменено 9 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
лнкс 0 Опубликовано 11 Сентября 2011 Поделиться Опубликовано 11 Сентября 2011 (изменено) Всем доброго времени суток. Возник такой вопрос: какой файл(скрипт, конфиг) запрещает на какой-либо локации спавнить нпс определённого ранга? Хочу при респавне на кордоне заспавнить бандюков в ранге "мастер", но простым редактированием spawn_sections.ltx это у меня не получается. Подскажите решение, пожалуйста. Задавайте вопросы более внятно. 1. 'Запрет' и 'не разрешение' - различные понятия. Нет нкаких запретов на (ре)спавн по рангам и по локациям. Имеются нте или иные конфиги/параметры. И если чего-то нет или параметр 'мал' - то не нужно путуть с запретом. 2. 'Респавном' - не спавнят, это 'автоматическое' событие, и тем более, при чем тут редактирование 'spawn_sections.ltx'? Разберись сам что же ты хочешь. Заспавнить кого-то - куда-то, иль настроить респавн. Во втором случае как минимум требуется информация где же тебе потребно чтобы респавнились. --/ Artos Добавлено через 84 мин.: Именно настроить респавн на кордоне, на АТП. В 'spawn_sections.ltx' прописывается ранг нпс при респавне и простое изменение новичков на мастеров не срабатывает. Почему? Потому что метод тыка в подобных вещах порочен и практически на 100% бесполезен. В 'spawn_sections.ltx' прописаны СЕКЦИИ объектос (НПС), в которых в отличии от исходной родительской секции, дополнительно прописываются треьуемые параметры, в том числе и ранг. Эти секции предназначены для любого спавна (само название файла говорит за себя!) и 'респавн' - это только частный случай. Респавны в игре НЕ читают рангов, а оперирует названиями секций и группировками. --/ Artos Изменено 11 Сентября 2011 пользователем Artos Лучше спросить глупость, чем её совершить. Ссылка на комментарий
=VENOM= 50 Опубликовано 12 Сентября 2011 Поделиться Опубликовано 12 Сентября 2011 лнкс, надо было выложить свою изменённую секцию, чтобы оценить, что к чему. В общем случае, если тебе нужно, чтобы на Кордоне спонились мастера-бандосы, сделай так: [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". Ссылка на комментарий
Artos 99 Опубликовано 12 Сентября 2011 Поделиться Опубликовано 12 Сентября 2011 (изменено) =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' и ограничение имеется только одно - по группировке. Т.е. любой бандит будет взят в гулаг при условии наличия свободной работы. Т.о. для 'заматерелости' АТП достаточно только правильно настроить респавнер этого гулага, внеся желаемые секции спавна (при недостатке - досоздать). Изменено 12 Сентября 2011 пользователем Artos "Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени Ссылка на комментарий
лнкс 0 Опубликовано 12 Сентября 2011 Поделиться Опубликовано 12 Сентября 2011 (изменено) Artos, а какие могут быть иные ограничения? Дописать секции в спавнере не проблема. Ну во первых не в 'спавнер', а в конфиг секций для спавна. 'Спавнером' все же называют иль скрипт иль схему (se_respawn). Во-вторых, имел ввиду в основном уже имеющиеся секции, которые могут иметь и кастомдату, иль в кодах игры именно этим секциям добавлена логика/ограничения. Дописанные новые - врядли будут иметь ограничения. Хотя дописывать? ... Упомянутые 'cit'- бандиты все одно являются рудиментами от вырезенной локации и ограничений для подобного спавна также не имеют. --/ Artos Добавлено через 37 мин.: Понял, теперь следующее, если удалить с локации смарты, то нпс, заспавненные на ней будут просто бродить везде, где позволяет сетка и реагировать на противника согласно своей стандартной логике? Если удалить смарты с локации, то как минимум потребуется скорректировать немало логики и скриптов ... Но НПС, заспавненные на локации, если им не прописано '[smart_terrains] none = true' - не будут бродить, а проследуют на те локации, где им найдется работенка. Конечно строго по сетке и отвлекаясь на опасности иль подобное. Добавлено через 21 мин.: Хорошо, тогда как сделать привязку нпс к определённой локации? Хм, ... привязать его к какому-либо смарту/гулагу на какой-либо локации. :-) И навязать ему работу из этого смарта/гулага (хоть на другой локации). Работа должна быть по координатам для нужной локации (не обязательно одной с гулагом ее дающим). --/ Artos Изменено 12 Сентября 2011 пользователем Artos Лучше спросить глупость, чем её совершить. Ссылка на комментарий
Рекомендуемые сообщения
Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий
Комментарии могут оставлять только зарегистрированные пользователи
Создать аккаунт
Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!
Зарегистрировать новый аккаунтВойти
Есть аккаунт? Войти.
Войти