polarfox0

EVENT_UNIT_DESPAWNED что не так?

8 posts in this topic

Пытаюсь получить имя пропавшего юнита самым ростым способом

на EVENT_UNIT_DESPAWNED вешаю слушателя и

 local objectName = object.GetName( params.unitId )

в ответе

Цитата

 UI::LuaObjectGetName: interactive object not found: 43976

что я делаю не так?

Share this post


Link to post
Share on other sites

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

local players = {}
local aid=params.unitId

table.insert(players, {
	id = aid,
	name = object.GetName(aid),
	level = unit.GetLevel( aid ),
	}

for k,v in pairs(players) do
	if players[k] and players[k].id==target then
		LogInfo(players[k].name)
		players[k]=nil -- удаляем из таблицы
		-- или if v and v.id==target then
		-- LogInfo(v.name)
		-- v=nil
	end
end

код не проверял, так пример на скорую руку

Share this post


Link to post
Share on other sites
1 минуту назад, logg сказал:

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


local players = {}
local aid=params.unitId

table.insert(players, {
	id = aid,
	name = object.GetName(aid),
	level = unit.GetLevel( aid ),
	}

for k,v in pairs(players) do
	if players[k] and players[k].id==target then
		LogInfo(players[k].name)
		players[k]=nil -- удаляем из таблицы
		-- или if v and v.id==target then
		-- LogInfo(v.name)
		-- v=nil
	end
end

код не проверял, так пример на скорую руку

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

думала, что можно сделать поаккуратнее

 

Share this post


Link to post
Share on other sites

Со спавнами и деспавнами отдельная еще история, они могут как приходить, так и не приходить, тогда начинается веселье... А еще один и тот же персонаж может иметь разные unitId если он выходит из поле зрения и появляется, при этом EVENT_UNIT_DESPAWNED  может не прийти)

Share this post


Link to post
Share on other sites
2 часа назад, polarfox0 сказал:

мда... инкостыляция - это искусство

можно не заморачиваться со спавном и деспавном, а каждую секунду по EVENT_SECOND_TIMER получать  avatar.GetUnitList()

Share this post


Link to post
Share on other sites
9 часов назад, logg сказал:

можно не заморачиваться со спавном и деспавном, а каждую секунду по EVENT_SECOND_TIMER получать  avatar.GetUnitList()

это как то совсем костыльно и сильно увеличивает ресурсозатраты

Share this post


Link to post
Share on other sites

Могу предложить два варианта:

Первый вариант для всех юнитов

do -- советую положить себе куда-то эти две полезные функции
  function table.normalize(t)
    if t[0] ~= nil then
      table.insert(t, 0, nil)
    end
    return t
  end
  --[[
  function table.denormalize(t)
    if t[0] == nil and t[1] ~= nil then
      t[0] = table.remove(t, 1)
    end
    return t
  end
  --]]
end

local units = {}

common.RegisterEventHandler(function(p)
  if not units[p.unitId] then -- необязательная проверка для параноиков
    units[p.unitId] = {
      name = object.GetName(p.unitId)
    }
    -- chat(units[p.unitId].name, p.unitId, 'spawned')
  end
end, 'EVENT_UNIT_SPAWNED')

common.RegisterEventHandler(function(p)
  if units[p.unitId] then
    -- chat(units[p.unitId].name, p.unitId, 'despawned')
    units[p.unitId] = nil
  end
end, 'EVENT_UNIT_DESPAWNED')

local function InitAvatar(avatarId)
  for _, unitId in ipairs(table.normalize(avatar.GetUnitList())) do
    units[unitId] = {
      name = object.GetName(unitId)
    }
  end
end

local function Init()
  if avatar.IsExist() then
    InitAvatar(avatar.GetId())
  else
    local function onAvatarCreated(p)
      common.UnRegisterEventHandler(onAvatarCreated, 'EVENT_AVATAR_CREATED')
      InitAvatar(p.id)
    end
    common.RegisterEventHandler(onAvatarCreated, 'EVENT_AVATAR_CREATED')
  end
end

Init()

Второй вариант с фильтрацией по имени

do -- советую положить себе куда-то эти две полезные функции
  function table.normalize(t)
    if t[0] ~= nil then
      table.insert(t, 0, nil)
    end
    return t
  end
  --[[
  function table.denormalize(t)
    if t[0] == nil and t[1] ~= nil then
      t[0] = table.remove(t, 1)
    end
    return t
  end
  --]]
end

local units = {}
local names = {
  ['Клыкастый кабан'] = true,
}

local function filter(name)
  -- можно воспользоваться common.CompareWString(text1, text2)
  return names[userMods.FromWString(name)]
end

common.RegisterEventHandler(function(p)
  if not units[p.unitId] then -- необязательная проверка для параноиков
    local name = object.GetName(p.unitId)
    if filter(name) then
      units[p.unitId] = {
        name = name
      }
      -- chat(units[p.unitId].name, p.unitId, 'spawned')
    end
  end
end, 'EVENT_UNIT_SPAWNED')

common.RegisterEventHandler(function(p)
  if units[p.unitId] then
    -- chat(units[p.unitId].name, p.unitId, 'despawned')
    units[p.unitId] = nil
  end
end, 'EVENT_UNIT_DESPAWNED')

local function InitAvatar(avatarId)
  for _, unitId in ipairs(table.normalize(avatar.GetUnitList())) do
    local name = object.GetName(unitId)
    if filter(name) then
      units[unitId] = {
        name = name
      }
    end
  end
end

local function Init()
  if avatar.IsExist() then
    InitAvatar(avatar.GetId())
  else
    local function onAvatarCreated(p)
      common.UnRegisterEventHandler(onAvatarCreated, 'EVENT_AVATAR_CREATED')
      InitAvatar(p.id)
    end
    common.RegisterEventHandler(onAvatarCreated, 'EVENT_AVATAR_CREATED')
  end
end

Init()

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now