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

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


Svoboда

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

Gun12

Не очень понял в твоей реплике о какой проблеме с рандомом говоришь. В проыессе ответа дошло,... ты о том, что рандом затрудняет проверять дроп, отсекая немало апдейтов при здоровом и сильном акторе? Поэтому и дал совет ремить строки проверок ...

В последнем с 0.3 варианте рандом использован только для получения пары значений силы и здоровья и никаким образом не может дать сбой.

Иное дело, что я бы так НЕ делал. как по силе так и по здоровью зависеть от 2х100% рандома - конечно довольно глупо.

Тут не нужен рандом, а только задать свои константы. Ну или так:

'if oActor.power < math.random(50,70)*0.01 and oActor.health < math.random(50,70)*0.01 then'

 

Но ... т.к. первично найти причину НЕ рабочести кода - не стал залезать далеко ... ;-)

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

==========================================================================

 

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

panzyuza

Ой, я даже растерялся ... :blink:

Могу ошибаться, но ... если это и из OGSE, то ... исходно написано АМК, мною было модифицированно и вероятно кем-то адаптировано в OGSE (с рудиментами и моими комментами типа '--/#~#' ).

1. Постарайся задавать поменьше таких вопросов. Таких - это когда от тебя НИ ЕДИНОЙ мысли/вопроса не высказано. Все же, как понимаю ТЫ делаешь мод, а не 'дядя'. Понимаю, что тебя интересует почти все, ты сам не можешь что-то оптимизировать иль увидеть ошибку/неточность, но(!) все же должен думать своею головой хоть о чем-то! (пояснения дальше ...)

2. Тебе уже ранее дан вариант, где 'math.random(1,100)/100' заменен на 'math.random()'. Ну зачем для получения одного и того же результата задавать диапазои и выполнять дополнительно деление?

Это только для удобства чтения может быть удобно, что 100 - это 100%

То, что диапазон рандома ограничен снизу (0.01) здоровья - у меня вызывает вопрос - а зачем?

Это типа того, что у совсем дохлого (>0.01) ГГ руки сводит и он не может выронить оружие? :-)

3. Сейчас бы я, убрав все рудименты, написал для оптимизации и понимания так:

local oNPC = self.object --/ кешируем объект монстра
if oNPC:clsid() == clsid.controller_s and oNPC:alive() then --/ это контролер? живой?
  local oTarget = oNPC:get_enemy() --/ получаем объект врага - цель атаки
  if oTarget and IsStalker(oTarget) and oNPC:see(oTarget) then --/ есть цель, это сталкер или ГГ и контролер видит его
    if oTarget:id() ~= db.actor:id() then --/ это не актор (ГГ)?
      if oNPC:position():distance_to(oTarget:position()) < math.random(10,60) then --/ дистанция менее 10...60
        --/ проверки-подстраховки:
        local sObj = alife():object( oTarget:id() ) --/ серверный объект цели
        if sObj and sObj.online then --/ есть серверная цель и она в онлайне
          if oTarget:character_community() ~= "zombied" then --/ цель не зомбирована
            oTarget:set_character_community("zombied",0,0) --/ зомбируем цель
          end
        end
      end
    elseif oTarget:character_community() ~= "actor_zombied" then --/#?# актор не зомбирован?
      monster_effects.controller_attack() --/#># вызов сторонней функции #?#
    end
    if oTarget.psy_health < math.random() then
      local active_item = oTarget:active_item()
      local sSection = active_item and active_item:section()
      if sSection ~= "bolt" and sSection ~= "wpn_knife" then
        oTarget:drop_item(active_item)
      end
    end
  end
end

Обращаю внимание, что с группировкой "actor_zombied" (это именно из OGSE) нужно что-то решать исходя из твоих конкретных кодов:

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

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

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

Так же, без внешней функции из скрипта 'monster_effects.controller_attack()' это работать не будет!

 

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

==========================================================================

 

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

panzyuza, Gun12

Ответ на вопрос #2786: т.е. для чего параметр 'respawn_check' и можно ли его использовать?

 

Использовать можно.

Для чего?

В параметре 'respawn_section' респавнеров задаются секции объектов для респавна.

При респавне считываются эти секции и проверяется в них наличие параметра 'custom_data'.

Если есть - читается указанный ltx-конфиг и читается из конфига секция 'smart_terrain', т.е. по сути, проверяется отвязка НПС от гулага.

Если обнаруживается запись: 'none = true' или 'respawn_check = false' - устанавливается флаг, который запретит гулаговые проверки для такого объекта.

Что это за 'гулаговая' проверка? Это означает, что в процессе спавна уже отреспавненный объекта проверяется его привязка к записанному в его логике гулагу. И, если гулаг прописан, но отсутствует, то объект удаляется из игры.

 

Т.о. параметр 'respawn_check' - это флаг, который запрещает (при значении 'false') удалять уже отреспавненного НПС в случае, если в игре отсутствует гулаг прописанный этому НПС. В противном случае, 'если гулаг прописан и отсутствует в игре - НПС, будучи уже заспавненным, УДАЛЯЕТСЯ.

Не указание параметра (что и делается в кодах) - приравнивается к 'respawn_check ~= false'.

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

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

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


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

PavelSnork

Несложно портянки организовать в циклы:

function remove_elements_3()
  local hud = get_hud()
  for i=1,24 do
    local sCustomStatic = "health_level_"..i --/ имя очередного
    if hud:GetCustomStatic(sCustomStatic) then --/ проверка наличия
      hud:RemoveCustomStatic(sCustomStatic) --/ удаление
    end
  end
end

function remove_elements_4()
  local hud = get_hud()
  for i=1,24 do
    local sCustomStatic = "power_level_"..i --/ имя очередного
    if hud:GetCustomStatic(sCustomStatic) then --/ проверка наличия
      hud:RemoveCustomStatic(sCustomStatic) --/ удаление
    end
  end
end

 

При удалении кастомстатика - делай проверки на его наличие!

Если с этими вариантами функций твои надписи про аптечки и сохранки не будут исчезать - ищи ошибки в других добавленных кодах.

 

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

P.S. Поправил ошибку в 4-ой строке: sName -> sCustomStatic (sorry)

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

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

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


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

*Shoker*

"Скриптово присвоить НПС какой то диалог" - можно.

Скриптово "как-то ... дописать ему ещё один <actor_dialog>" - нет, и тем более не в "список фраз".

 

(каков вопрос - таков ответ)

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

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

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


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

Gun12, PavelSnork

А почему совсем не снять шоры (зацикленность именно на стандартном подходе в таких ситуациях) и ...

Имеем здоровье актора: iHealth = db.actor.health , которое может лежать в диапазоне 0 ... 1

Имеем набор кастомстатиков строго в диапазоне 1 ... 24

Зависимость, судя по проверкам линейна!

Т.е. на каждые 0.04 - один элемент из списков статиков.

В итоге имеем:

  local iHealth = db.actor.health
  if iHealth < 0.94 and iHealth > 0.04 then
    local sHealth_Level = "health_level_"..(math.ceil(iHealth * 25)-1)
    local hud = get_hud()
    if not hud:GetCustomStatic(sHealth_Level) then
      hud:AddCustomStatic(sHealth_Level, true)
    end
  end

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

При совсем здоровом ГГ - только проверка "не приболел ли малость?"

 

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

P.S. Остается немного и ... переходим в следующий класс, если как полагаю, этот кастомстатик - некая шкала с переменной длиною.

Оставляем один кастомстатик дабы не плодить строк в конфиге иль даже текстур и ... меняем скриптом его длину. ;-)

Но .. не будем отвлекаться, вопрос пока в ошибке, которая как полагает PavelSnork именно в этих функциях.

 

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

P.P.S. Чуть поразмышлял (отвлекаясь от других дел ...):

PavelSnork, уточни, плз, диапазоны здоровья и силы актора 0...0.04 тебя совсем не волнуют?

Т.е. не важно что (есть/нет) кажут кастомстатики?

Вот полный вариант, совмещающий все твои функции, в котором при полных (почти) здоровье и силе актора выводятся твои 24-ые кастомстатики и при падении параметров - номера уменьшаются. При <=0.04 - удаляются.

local sHealth_Save = nil
local sPower_Save  = nil

function check_params()
  local hud = get_hud()
  --/ clear
  function Clear(sName)
    for i=1,24 do
      if hud:GetCustomStatic(sName..i) then --/ проверка наличия
        hud:RemoveCustomStatic(sName..i) --/ удаление
      end
    end
  end
  --/ health
  local iHealth = db.actor.health --/ здоровье актора
  if iHealth > 0.04 then --/ если есть здоровье
    --/ вычисляем нужный индикатов
    sHealth_Level = "health_level_"..(math.ceil(iHealth * 25)-1)
    if sHealth_Level ~= (sHealth_Save or "") then --/ индикатор уровня не прежний?
      if sHealth_Save then
        Clear("health_level_") --/ чистим
      end
      hud:AddCustomStatic(sHealth_Level, true) --/ выводим нужный
      sHealth_Save = sHealth_Level --/ запоминаем
    end
  elseif sHealth_Save then --/ нет здоровья и при наличии индикатора
    Clear("health_level_") --/ чистим
    sHealth_Save = nil --/ обнуляем, дабы не чистить постоянно
  end
  --/ power
  local iPower = db.actor.health --/ сила актора
  if iPower > 0.04 then --/ если есть сила
    --/ вычисляем нужный индикатов
    sPower_Level = "power_level_"..(math.ceil(iHealth * 25)-1)
    if sPower_Level ~= (sPower_Save or "") then --/ индикатор уровня не прежний?
      if sPower_Save then
        Clear("power_level_") --/ чистим
      end
      hud:AddCustomStatic(sPower_Level, true) --/ выводим нужный
      sPower_Save = sPower_Level --/ запоминаем
    end
  elseif sHealth_Save then --/ нет силы и при наличии индикатора
    Clear("power_level_") --/ чистим
    sPower_Save = nil --/ обнуляем, дабы не чистить постоянно
  end
end

 

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

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

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


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

Real Wolf

Если для объекта применять методы, которые не предусмотрены его классом - странно вообще ожидать работы кода, не говоря о стабильной работе ...

Для объектов класса 'CUIMessageBoxEx' не предусмотрен метод 'Init(string)', но зато есть 'InitMessageBox(string)' (ЧН!).

(беря коды из ТЧ - следует проверять - а не изменилось ли чего в ЧН/ЗП?)

 

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

PavelSnork: ... как мне сделать, чтоб поверх этих 2х полосок выводилась еще одна текстура?

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

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

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

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

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

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

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


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

Real Wolf

Ну что- же если решил, так это хорошо ...

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

ИМХО, если это в ТЧ, то твоя проблема в том, что вместо однократного создания объекта, что обычно делают при инициализации схемы/скрипта, ты плодишь объекты окон с каждым вызовом, а не "Несколько раз вызвав окно". Вот и ... -> нехватка памяти.

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

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

 

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

panzyuza

Заменить класс бюрера на собачий (собачьИ) ...

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

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

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


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

*Shoker*

Если старый объект (UI в частности) имеет локальный характер - его (если уже не востребован) с некоторой периодичностью уничтожает 'сборщик мусора' LUA.

Отступление: Если хочется побыстрее избавиться от мусора - смотрим как это делают SGC:

collectgarbage('collect') --/ performs a full garbage-collection cycle

 

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

Примечание(важно!): GUI объекты сохраняются даже при перезагрузке игры (т.е. без выхода в ОС), что может сослужить плохую службу и приводить к вылетам. Такие объекты, которые должны в игре, запущеной заново, создаваться 'c ноля' - следует удалять (нанилять их переменные) в обязательном порядке.

 

(сорри за пространное пояснение, но оно бельше 'для всех', а не как ответ на конкретный вопрос)

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

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

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


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

*Shoker*

Без довольно глубоких опусканий к основам - такое объяснить и понять сложновато ...

Чуть подробнее и не на абстракии , а на практическом примере:

В Simbion'e есть модуль, который выводит окна доп.слотов (нож,бинокль, ...)

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

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

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

Принудительное деаттачивание и удаление созданных объектов в методе '__finalize()' при выходе из игры - сняло все проблемы.

Т.о. имеет важность именно объект, а не переменная, о чем выше не совсем внятно написал.

 

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

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

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

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


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

PavelSnork

Вот этот:

local iHealthIdx = nil
local iPowerIdx  = nil

function check_params()
  local hud = get_hud()
  --/ clear: чистка всех кастом-статиков указанного маской имени (sMaskName)
  function Clear(sMaskName)
    for i=1,24 do
      if hud:GetCustomStatic(sMaskName..i) then --/ проверка наличия
        hud:RemoveCustomStatic(sMaskName..i) --/ удаление
      end
    end
  end
  --/ health: вычисляем индекс здоровья актора
  local iIdx = math.ceil(db.actor.health * 25)-1 --/ индекс здоровья (1...24)
  if iIdx > 0 then --/ если есть здоровье
    if iIdx ~= iHealthIdx then --/ индекс уровня сменился?
      if iHealthIdx and hud:GetCustomStatic("health_level_"..iHealthIdx) then --/ проверка наличия
        hud:RemoveCustomStatic("health_level_"..iHealthIdx) --/ удаление
       end
      hud:AddCustomStatic("health_level_"..iIdx, true) --/ выводим нужный
      iHealthIdx = iIdx --/ запоминаем
    end
  elseif iHealthIdx then --/ нет здоровья и при наличии индикатора
    Clear("health_level_") --/ чистим все кастом-статики здоровья
    iHealthIdx = nil --/ обниляем, дабы не чистить постоянно
  end
  --/ power: вычисляем индекс силы актора
  iIdx = math.ceil(db.actor.health * 25)-1 --/ индекс силы (1...24)
  if iIdx > 0 then --/ если есть сила
    if iIdx ~= iPowerIdx then --/ индекс уровня сменился?
      if iPowerIdx and hud:GetCustomStatic("power_level_"..iPowerIdx) then --/ проверка наличия
          hud:RemoveCustomStatic("power_level_"..iPowerIdx) --/ удаление
        end
      end
      hud:AddCustomStatic("power_level_"..iIdx, true) --/ выводим нужный
      iPowerIdx = iIdx --/ запоминаем
    end
  elseif iPowerIdx then --/ нет силы и при наличии индикатора
    Clear("power_level_") --/ чистим все кастом-статики силы
    iPowerIdx = nil --/ обниляем, дабы не чистить постоянно
  end
end

- более оптимизирован. Убраны отдельные излишества и заменены сравнения строк на численные, которые гораздо быстрее выполняются.

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

 

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

=VENOM=

Несколько размышлений на тему:

в некоторой степени лишат игру "симуляционной миграции" NPC между локациями
Каждый респавнер имеет время паузы. Каждый гулаг, выдав кому-то работу - резервирует эту работу за наемным НПС.

Т.о. даже при достаточном кол-ве активных респавнеров на текущей локации можно наблюдать, как на текущую локацию приходят НПС с других локация. А то, что и на текущей активны - дает эффект ухода НПС с текущей локации на другие.

Причем, если активно работает 'оффлайн-алайф', т.е. НПС сражаются между собою и с монстрами и гибнут - эффект ухода 'вперед' актора довольно неплохо смотрится.

Можно даже более разнообразить. В своих пробах ставил респавнер за блок постом на Кордоне и давал 75м дистанции до актора и условием спавна солдан на БП < 3 - после выноса актором БП на Кордон с внешней сторона Зоны начинали подтягиваться новички. Вот такой получается "симуляционная миграция" при активных респавнерах на текущей локации. ;-)

 

у себя я сделал отслеживание продвижения игрока по локациям

Аналогично, и хотел бы посоветовать единомышленнику не только 'линейное' отслеживание прохождения вглубь Зоны, но и более мудреное. ГГ может и возвращаться (и не раз) на тот же Кордон ... Встречать опять на Кордоне новичков не интересно, встречать после малого круга на ТД (по сюжету) только мастеров - тоже несколько странно, во фриплее - самое оно. Если ввести условие в респавнеры спавнить ранги в зависимости от кол-ва посещенных актором локаций - имеем эффект постоянно усложняющий игру.

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

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

 

Загляни в топик "Universal ACDC и другие perl-скрипты" - с последней версией можно достаточно легко в нужное время удалять любой респавн и заново спавнить по его секции из алл.спавна, причем индексы секций не требуется ручками прописывать, а можно брать скриптом из секции с именем объекта. Это дает возможность наделать в all.spawn'е нужное кол-во респавнеров и задействовать/отключать их прямо из скриптов в любое время и в зависимости от динамических условий.

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

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

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


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

FANAT

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

Например, под спойлером указал бы какие коды в каких конфигах вставлял. Раз волнует веc - хотя бы какие параметры веса в своих 'новшествах' использовал следует указать.

Например, я, на безграмотные и/или безинформативные вопросы стараюсь не давать ответов ...

 

2. Тебе было посоветовано первоначально обратиться с этим вопросом в топик соответствующего мода. В данном случае в топики по НС (Народной Солянке). Ты ленишься получать ответы от первоисточника или тех, кто хорошо знает мод?

Лень часто приводит к потере времени, чем к его экономии ...

 

3. Вариант самостоятельного поиска причины ошибки:

3.1. Убираешь все свои добавки и проверяешь, что проблемы с весом нет.

3.2. Добавляешь 1 (один!) свой ствол и проверяешь - нет ли проблем с весом.

3.3. Так добавляешь по одиночке остальное. Как только появится проблема с весом - изучаешь последний добавленный конфиг в поисках ошибок/описок.

Если не смог ничего найти 'криминального' - выкладываешь этот конфиг под спойлером тут - постараемся помочь.

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

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

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


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

Ренсон

'play_at_pos' - не самый удачный выбор метода проигрывания звука в твоем случае.

Если звук должен звучать именно для актора (игрока) и звучать постоянно - то для чего проигрывать его именно по позиции актора?

Есть метод 'play_no_feedback' - который НЕ расходует лишних ресурсов, т.к. не требуется постоянное обновление по координатам объекта и не ожидает никакого управления. Т.е. запустил звук - и сам играет пока не закончится. Используя параметр зацикливания - проигрывается 'по кругу'.

Типа: geiger_snd:play_no_feedback(db.actor, sound_object.s2d+sound_object.looped, 9, vector():set(0,0,0), 1.0)

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

А вообще (ИМХО) - занести в амбиент локации и не париться со скриптами ...

 

*Shoker*

'amount' - это именно величина хита, т.е. та величина, которая должна нанести объекту указанное значение урона.

В твои размышления и тем более выводы "это довольно поверхностное значение" - не верны.

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

1. Урон, который наносится объекту, в данном случае сталкеру, раскладывается на несколько элементов. Часть урона берет на себя его 'защита' (костюм/визуал). Т.о. уровень здоровья сталкера упадет само собою на меньшее значение.

2. Нанеся хит и замерив в этот момент уровень здоровья, ты следиющее измерение здоровья производишь через некоторый интервал времени! Тобою совершенно упущено то, сталкеры имеют свойство ВОССТАНАВЛИВАТЬ свое здоровье и, что получив хит - это здоровье начинаает восстанавливаться. Т.о. в момент твоего повторного измерения уроовень здоровья, упавший до некоторого уровня, успеет восстановиться на некоторую величину.

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

Так что ... твои вычисления грешат , твоими же словами, именно 'поверхностностью'.

 

Если и расчитывать (не знаю для чего?), то:

- получать значение получаемого хита. В этот же момент запоминать текущее значение здоровья и текущее игровое время.

- на следуюшем (2-ом) апдейта получать 2-ое значение здоровья (-хит +восстановление) и дельту времени между апдейтами.

- на следующем (3-ем) апдейте, при условии отсутствия нового хита, опять получать значение здоровья (+восстановление) и дельты времени.

Ну и дальше расчитать, без учета восстанавливаемости здровья объекта, но и без значения хита, поглащенного костюмом. В принципе, если не грешить не "приближенность" параметра 'amount' - можно приближенно расчитать сколько урона НЕ ушло на здоровье актора, т.е. косвенно - поглащено защитой.

 

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

*Shoker*: У компания-разработчик (признана нежелательной)* нигде реально amount не используется, тока как проверка, что урон был вообще

Что же ты так любишь приписывать компания-разработчик (признана нежелательной)*'никам свои предполагалки?

Смотрим в 'xr_motivator.script' (SCoP):

function motivator_binder:hit_callback(obj, amount, local_direction, who, bone_index)
  --/...
  -- Если пришел смертельный хит, с некоторой вероятностью делаем чувака раненым.
  if bone_index ~= 15 and amount > self.object.health*100 then
    --printf("DEADLY HIT %s %s", amount, self.object.health*100)
    self.object.health = 0.15
  end
  --/...
end

- т.е. именно по 'amount'-у проверяется не помрет ли НПС и ему заранее корректируется здовье. Иной вопрос действенность и реализация данного варианта ...

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

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

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


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

*Shoker*, когда у человеке в голове 'каша' - то и его слова и выводы носят 'кашеобразный' характер.

Трудно написать более кашеобразно:

*Shoker*: amount точно отвечает за нанесённый урон и зависет от силы этого урона, но его значение не соответствует реальности.

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

В общем ставим кобылу позади телеги и рассуждаем как телега везет кобылу ... ;-)

 

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

И то, что что-то появилость только, например в ЗП, и не говорит о том, что этого нельзя было сделать в ТЧ/ЧН, и уж никак о том, что "нигде реально amount не используется". Аккуратнее в словах, уже не первый раз попадаешь в просак.

 

Ну и, не стОит формулировать некие куски подвопросов/размышлений, выдернутых из контекста. Пока не поняткна конечная цель - опровергать/советовать чаще всего напрасная трата времени. Пояснил бы в начале, что конкретно интересует ... А то даже в конце о "системе перков" нечто, как будто всем ясно о чем речь.

 

*Shoker*: Если есть идеи более точного варианта, я буду тока рад

Если уж поминаешь про точность - потрудись ТОЧНО поставить задачу или хотя бы по-возможности конкретно и без жаргонария (типа 'перков'?), описать пожелалку. А пока - только критиковать твое нынешнее имеется возможность ... :crazy:

 

=================================================

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

panzyuza

Да, в таск-менеджере учитывается параметр 'prior' -- приоритет квеста.

Из однотипных доступных квестов выдается с меньшим весом параметра приоритета.

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

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

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


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

*Shoker*

Если для тебя "это уже так, чисто из интереса", то, например для меня и напрягаться ради удовлетворения такого интереса - неинтересно ...

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

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

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

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


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

*Shoker*, учитывая, что все монстры 'биндятся', а это значит, что заносятся в таблицу db.storage, итерировать по всему списку игровых ID расточительно. Достаточно:

for id,v in pairs(db.storage) do
  if level.object_by_id(id) then
    local sobj = alife():object(id)
    if sobj and IsMonster(sobj) and not sobj:alive() then 
      alife():release(sobj, true)
    end
  end
end

 

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

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

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

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

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


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

лнкс

Разберись о чем говоришь и что отключать хочешь - тогда переформулируй вопрос.

Loot - ограбление/грабить/мародерствовать

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

Т.о. "удалить лут из инвентаря" невозможно, т.к. это действие (удаление+спавн).

Игроки, часто употребояют под 'лутом' именно то, что доспавнивается в труп, что тем более удалить невозможно, т.к. еще и не спавнилось.

 

Можно - а) не удалять предметы из трупа, можно - б) не спавнить предметы в труп, можно - с) и то и другое (т.е. отменить лут).

Соответственно и пути решения различны.

 

 

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

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


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

лнкс

Для однозначного понимания вопроса нехватает еще малости - читаем в шапке:

6. ПОЖАЛУЙСТА! Указывайте, для какой игры Вам необходима информация (ТЧ, ЧН, ЗП), если стоит мод - укажите название мода;

Поэтому привожу только один вариант применительно к версии игры ТЧ:

В скрипте 'death_manager.script' в строке 177 (в самом конце функции 'keep_item') закомментируй (поставь впереда строки '--') так:

 

--alife():release(alife():object(item:id()), true)

 

Если иная версия игры иль правленый файл (из мода) - делай по аналогии. Понятно?

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

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

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


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

dark_stalker

Это один из трудно выявляемых типов ошибки. Поиск причины возможен только на конкретных кодах мода.

Где-то в кодах у тебя образовалась зацикленность, что приводит к переполнению стека.

Искать и разрывать цикл. Подспорьем может быть определение объекта (имени) в том эвалуаторе из 'state_mgr.script' на который указывает запись в логе и искать циклы связанные с этим объектом.

Но, вполне возможно, что спавнится некий объект (НПС/моб) по некорректной позиции (типа "в стене") и не может выбраться ...

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

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

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


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

Не 'какой', а 'как'. Тебе нужен именно тот, для которого зациклились вызовы стейт-менеджера. Какой именно - только самому смотреть и анализировать.

Выведи в лог имя объекта 'self.object:name()' в том эвалуаторе, к которому принадлежит строка указанного в логе ошибки - получишь всех, которые движутся. По часто и/или последнему упоминающемуся имени и ищи ...

 

Ну и естественно, сменив сетку AI следует перепроверить/скорректировать все координаты ...

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

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

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


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

_Призрак_

Прочитать файл 'user.ltx' и из него взять значение интересующего тебя параметра (bind wpn_2 k2).

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

 

function Read_ScreenResolution()
  get_console():execute("cfg_save tmp") --/ копия/запись настроек из 'user.ltx' в файл 'tmp.ltx'
  local f = getFS() --/ объект класса FS
  local oFile = f:exist("$app_data_root$","tmp.ltx")
  local iSize = oFile and oFile.size_real --/ размер файла (байт)
  if iSize and iSize > 0 and iSize < 8192 then --/ ограничитель размера 'читалки'
    local oReader = f:r_open(oFile.name) --/ объект/линк 'читалки файла'
    if oReader then
      local tSymbols,iByte,i = {},0,0 --/ временный массив и переменные для чтения
      --/ последовательно по-байтно читаем от начала и до конца файла (или до NULL)
      oReader:r_seek(0) --/ устанавливаем 'читалку' в начало
      for i=1,iSize do
        iByte = oReader:r_u8() --/ читаем текущий байт
        if iByte == 0 then --/ нуль-терминатор? (NULL == 0x00)
          break --/ прерываем чтение
        end
        table.insert(tSymbols, string.char(iByte)) --/ конвертируем байт в символ и добавляем в таблицу
      end
      local sStr = table.concat(tSymbols) --/ конкатенация всех символов в единую строку
      --/ вырезаем из строки файла значение искомого параметра
      local sVidMode = sStr:match('vid_mode%s*(%w+)')
      if sVidMode and sVidMode ~= "" then --/ обнаружен?
        print("Read_ScreenResolution:VidMode=[%s]:[%s]", sVidMode, sVidMode, ">") --/> Прочитали!!!
      end
    end
    f:file_delete(oFile.name) --/ удаляем tmp-файл
  end
end

 

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

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

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


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

Ulman, так ты будешь о-о-очень долго спрашивать.

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

Ну а пока немного общей теории и далее ковыряй самостоятельно:

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

Однако, если величина увеличения здоровья ('eat_health'), которую дает съеденная аптечка недостаточна для достижения порогового значения, по которому определяется ранен ли НПС - то вновь включится схема ранения и НПС примет соответствующую позу.

"Резиновая аптечка", как помнится, именно и предназначена для затягивания процесса выздоравливания (хотя вроде только для актора). Если она (аптечка) в своем конфиге имеет малое значение 'eat_health' - то и не будет вылечивать 'за раз'.

 

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

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

Строка лога ошибки: 'xr_logic.script:939: bad argument #1 to 'gfind' (string expected, got nil)' - говорит о том, что в функцию xr_logic.parse_condlist(npc, section, field, src) не был передан аргумент 'src' (т.е. некое значение параметра для некоей схемы).

Попробуй в начало функции 'parse_condlist' поставить вывод в лог значений npc:name(), section, field - тогда сможешь понять, для какого НПС из какой схемы и в каком параметре у тебя ошибка.

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

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

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


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

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