• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

TFS 1.X+ Hide creature on batlelist

Decodde

New Member
Joined
Oct 8, 2018
Messages
31
Reaction score
0
Its possible hide a creature to be displayed in batlelist? (TFS 1.0)

EDIT to be more specific, im trying hide monsters that havent name and hp bar, like traps (\data\monster\Traps) and not all monsters in batlelist.

tfs10.png
 
Last edited:
Solution
In modules/game_battle/battle.lua

under

Lua:
function doCreatureFitFilters(creature)
  if creature:isLocalPlayer() then
    return false
  end
Add
Lua:
if creature:getHealthPercent() == 0 then
  return false
end
Paste into your Battle.Lua
Lua:
battleWindow = nil
battleButton = nil
battlePanel = nil
filterPanel = nil
toggleFilterButton = nil
lastBattleButtonSwitched = nil
battleButtonsByCreaturesList = {}
creatureAgeList = {}

mouseWidget = nil

sortTypeBox = nil
sortOrderBox = nil
hidePlayersButton = nil
hideNPCsButton = nil
hideSkullsButton = nil
hidePartyButton = nil

function init()
  g_ui.importStyle('battlebutton')
  battleButton = modules.client_topmenu.addRightGameToggleButton('battleButton', tr('Battle') .. ' (Ctrl+B)', '/images/topbuttons/battle', toggle)
  battleButton:setOn(true)
  battleWindow = g_ui.loadUI('battle', modules.game_interface.getRightPanel())
  g_keyboard.bindKeyDown('Ctrl+B', toggle)

  -- this disables scrollbar auto hiding
  local scrollbar = battleWindow:getChildById('miniwindowScrollBar')
  scrollbar:mergeStyle({ ['$!on'] = { }})

  battlePanel = battleWindow:recursiveGetChildById('battlePanel')

  filterPanel = battleWindow:recursiveGetChildById('filterPanel')
  toggleFilterButton = battleWindow:recursiveGetChildById('toggleFilterButton')

  if isHidingFilters() then
    hideFilterPanel()
  end

  sortTypeBox = battleWindow:recursiveGetChildById('sortTypeBox')
  sortOrderBox = battleWindow:recursiveGetChildById('sortOrderBox')
  hidePlayersButton = battleWindow:recursiveGetChildById('hidePlayers')
  hideNPCsButton = battleWindow:recursiveGetChildById('hideNPCs')
  hideSkullsButton = battleWindow:recursiveGetChildById('hideSkulls')
  hidePartyButton = battleWindow:recursiveGetChildById('hideParty')

  mouseWidget = g_ui.createWidget('UIButton')
  mouseWidget:setVisible(false)
  mouseWidget:setFocusable(false)
  mouseWidget.cancelNextRelease = false

  battleWindow:setContentMinimumHeight(80)

  sortTypeBox:addOption('Name', 'name')
  sortTypeBox:addOption('Distance', 'distance')
  sortTypeBox:addOption('Age', 'age')
  sortTypeBox:addOption('Health', 'health')
  sortTypeBox:setCurrentOptionByData(getSortType())
  sortTypeBox.onOptionChange = onChangeSortType

  sortOrderBox:addOption('Asc.', 'asc')
  sortOrderBox:addOption('Desc.', 'desc')
  sortOrderBox:setCurrentOptionByData(getSortOrder())
  sortOrderBox.onOptionChange = onChangeSortOrder

  connect(Creature, {
    onSkullChange = updateCreatureSkull,
    onEmblemChange = updateCreatureEmblem,
    onOutfitChange = onCreatureOutfitChange,
    onHealthPercentChange = onCreatureHealthPercentChange,
    onPositionChange = onCreaturePositionChange,
    onAppear = onCreatureAppear,
    onDisappear = onCreatureDisappear
  })

  connect(LocalPlayer, {
    onPositionChange = onCreaturePositionChange
  })

  connect(g_game, {
    onAttackingCreatureChange = onAttack,
    onFollowingCreatureChange = onFollow,
    onGameEnd = removeAllCreatures
  })

  checkCreatures()
  battleWindow:setup()
end

function terminate()
  g_keyboard.unbindKeyDown('Ctrl+B')
  battleButtonsByCreaturesList = {}
  battleButton:destroy()
  battleWindow:destroy()
  mouseWidget:destroy()

  disconnect(Creature, {
    onSkullChange = updateCreatureSkull,
    onEmblemChange = updateCreatureEmblem,
    onOutfitChange = onCreatureOutfitChange,
    onHealthPercentChange = onCreatureHealthPercentChange,
    onPositionChange = onCreaturePositionChange,
    onAppear = onCreatureAppear,
    onDisappear = onCreatureDisappear
  })

  disconnect(LocalPlayer, {
    onPositionChange = onCreaturePositionChange
  })

  disconnect(g_game, {
    onAttackingCreatureChange = onAttack,
    onFollowingCreatureChange = onFollow,
    onGameEnd = removeAllCreatures
  })
end

function toggle()
  if battleButton:isOn() then
    battleWindow:close()
    battleButton:setOn(false)
  else
    battleWindow:open()
    battleButton:setOn(true)
  end
end

function onMiniWindowClose()
  battleButton:setOn(false)
end

function getSortType()
  local settings = g_settings.getNode('BattleList')
  if not settings then
    return 'name'
  end
  return settings['sortType']
end

function setSortType(state)
  settings = {}
  settings['sortType'] = state
  g_settings.mergeNode('BattleList', settings)

  checkCreatures()
end

function getSortOrder()
  local settings = g_settings.getNode('BattleList')
  if not settings then
    return 'asc'
  end
  return settings['sortOrder']
end

function setSortOrder(state)
  settings = {}
  settings['sortOrder'] = state
  g_settings.mergeNode('BattleList', settings)

  checkCreatures()
end

function isSortAsc()
    return getSortOrder() == 'asc'
end

function isSortDesc()
    return getSortOrder() == 'desc'
end

function isHidingFilters()
  local settings = g_settings.getNode('BattleList')
  if not settings then
    return false
  end
  return settings['hidingFilters']
end

function setHidingFilters(state)
  settings = {}
  settings['hidingFilters'] = state
  g_settings.mergeNode('BattleList', settings)
end

function hideFilterPanel()
  filterPanel.originalHeight = filterPanel:getHeight()
  filterPanel:setHeight(0)
  toggleFilterButton:getParent():setMarginTop(0)
  toggleFilterButton:setImageClip(torect("0 0 21 12"))
  setHidingFilters(true)
  filterPanel:setVisible(false)
end

function showFilterPanel()
  toggleFilterButton:getParent():setMarginTop(5)
  filterPanel:setHeight(filterPanel.originalHeight)
  toggleFilterButton:setImageClip(torect("21 0 21 12"))
  setHidingFilters(false)
  filterPanel:setVisible(true)
end

function toggleFilterPanel()
  if filterPanel:isVisible() then
    hideFilterPanel()
  else
    showFilterPanel()
  end
end

function onChangeSortType(comboBox, option)
  setSortType(option:lower())
end

function onChangeSortOrder(comboBox, option)
  -- Replace dot in option name
  setSortOrder(option:lower():gsub('[.]', ''))
end

function checkCreatures()
  removeAllCreatures()

  if not g_game.isOnline() then
    return
  end

  local player = g_game.getLocalPlayer()
  local spectators = g_map.getSpectators(player:getPosition(), false)
  for _, creature in ipairs(spectators) do
    if doCreatureFitFilters(creature) then
      addCreature(creature)
    end
  end
end

function doCreatureFitFilters(creature)
  if creature:isLocalPlayer() then
    return false
  end

  local pos = creature:getPosition()
  if not pos then return false end

  local localPlayer = g_game.getLocalPlayer()
  if pos.z ~= localPlayer:getPosition().z or not creature:canBeSeen() then return false end

  local hidePlayers = hidePlayersButton:isChecked()
  local hideNPCs = hideNPCsButton:isChecked()
  local hideSkulls = hideSkullsButton:isChecked()
  local hideParty = hidePartyButton:isChecked()

  if hidePlayers and creature:isPlayer() then
    return false
  elseif hideNPCs and creature:isNpc() then
    return false
  elseif hideSkulls and creature:isPlayer() and creature:getSkull() == SkullNone then
    return false
  elseif hideParty and creature:getShield() > ShieldWhiteBlue then
    return false
  end

  return true
end

function onCreatureHealthPercentChange(creature, health)
  local battleButton = battleButtonsByCreaturesList[creature:getId()]
  if battleButton then
    if getSortType() == 'health' then
      removeCreature(creature)
      addCreature(creature)
      return
    end
    battleButton:setLifeBarPercent(creature:getHealthPercent())
  end
end

local function getDistanceBetween(p1, p2)
    return math.max(math.abs(p1.x - p2.x), math.abs(p1.y - p2.y))
end

function onCreaturePositionChange(creature, newPos, oldPos)
  if creature:isLocalPlayer() then
    if oldPos and newPos and newPos.z ~= oldPos.z then
      checkCreatures()
    else
      -- Distance will change when moving, recalculate and move to correct index
      if getSortType() == 'distance' then
        local distanceList = {}
        for _, battleButton in pairs(battleButtonsByCreaturesList) do
          table.insert(distanceList, {distance = getDistanceBetween(newPos, battleButton.creature:getPosition()), widget = battleButton})
        end

        if isSortAsc() then
          table.sort(distanceList, function(a, b) return a.distance < b.distance end)
        else
          table.sort(distanceList, function(a, b) return a.distance > b.distance end)
        end

        for i = 1, #distanceList do
          battlePanel:moveChildToIndex(distanceList[i].widget, i)
        end
      end

      for _, battleButton in pairs(battleButtonsByCreaturesList) do
        addCreature(battleButton.creature)
      end
    end
  else
    local has = hasCreature(creature)
    local fit = doCreatureFitFilters(creature)
    if has and not fit then
      removeCreature(creature)
    elseif fit then
      if has and getSortType() == 'distance' then
        removeCreature(creature)
      end
      addCreature(creature)
    end
  end
end

function onCreatureOutfitChange(creature, outfit, oldOutfit)
  if doCreatureFitFilters(creature) then
    addCreature(creature)
  else
    removeCreature(creature)
  end
end

function onCreatureAppear(creature)
  if creature:isLocalPlayer() then
    addEvent(function()
      updateStaticSquare()
    end)
  end

  if doCreatureFitFilters(creature) then
    addCreature(creature)
  end
end

function onCreatureDisappear(creature)
  removeCreature(creature)
end

function hasCreature(creature)
  return battleButtonsByCreaturesList[creature:getId()] ~= nil
end

function addCreature(creature)
  local creatureId = creature:getId()
  local battleButton = battleButtonsByCreaturesList[creatureId]

  -- Register when creature is added to battlelist for the first time
  if not creatureAgeList[creatureId] then
    creatureAgeList[creatureId] = os.time()
  end

  if not battleButton then
    battleButton = g_ui.createWidget('BattleButton')
    battleButton:setup(creature)

    battleButton.onHoverChange = onBattleButtonHoverChange
    battleButton.onMouseRelease = onBattleButtonMouseRelease

    battleButtonsByCreaturesList[creatureId] = battleButton

    if creature == g_game.getAttackingCreature() then
      onAttack(creature)
    end

    if creature == g_game.getFollowingCreature() then
      onFollow(creature)
    end

    local inserted = false
    local nameLower = creature:getName():lower()
    local healthPercent = creature:getHealthPercent()
    local playerPosition = g_game.getLocalPlayer():getPosition()
    local distance = getDistanceBetween(playerPosition, creature:getPosition())
    local age = creatureAgeList[creatureId]

    local childCount = battlePanel:getChildCount()
    for i = 1, childCount do
      local child = battlePanel:getChildByIndex(i)
      local childName = child:getCreature():getName():lower()
      local equal = false
      if getSortType() == 'age' then
        local childAge = creatureAgeList[child:getCreature():getId()]
        if (age < childAge and isSortAsc()) or (age > childAge and isSortDesc()) then
          battlePanel:insertChild(i, battleButton)
          inserted = true
          break
        elseif age == childAge then
          equal = true
        end
      elseif getSortType() == 'distance' then
        local childDistance = getDistanceBetween(child:getCreature():getPosition(), playerPosition)
        if (distance < childDistance and isSortAsc()) or (distance > childDistance and isSortDesc()) then
          battlePanel:insertChild(i, battleButton)
          inserted = true
          break
        elseif childDistance == distance then
          equal = true
        end
      elseif getSortType() == 'health' then
          local childHealth = child:getCreature():getHealthPercent()
          if (healthPercent < childHealth and isSortAsc()) or (healthPercent > childHealth and isSortDesc()) then
            battlePanel:insertChild(i, battleButton)
            inserted = true
            break
          elseif healthPercent == childHealth then
            equal = true
          end
      end

      -- If any other sort type is selected and values are equal, sort it by name also
      if getSortType() == 'name' or equal then
          local length = math.min(childName:len(), nameLower:len())
          for j=1,length do
            if (nameLower:byte(j) < childName:byte(j) and isSortAsc()) or (nameLower:byte(j) > childName:byte(j) and isSortDesc()) then
              battlePanel:insertChild(i, battleButton)
              inserted = true
              break
            elseif (nameLower:byte(j) > childName:byte(j) and isSortAsc()) or (nameLower:byte(j) < childName:byte(j) and isSortDesc()) then
              break
            elseif j == nameLower:len() and isSortAsc() then
              battlePanel:insertChild(i, battleButton)
              inserted = true
            elseif j == childName:len() and isSortDesc() then
              battlePanel:insertChild(i, battleButton)
              inserted = true
            end
          end
      end

      if inserted then
        break
      end
    end

    -- Insert at the end if no other place is found
    if not inserted then
      battlePanel:insertChild(childCount + 1, battleButton)
    end
  else
    battleButton:setLifeBarPercent(creature:getHealthPercent())
  end

  local localPlayer = g_game.getLocalPlayer()
  battleButton:setVisible(localPlayer:hasSight(creature:getPosition()) and creature:canBeSeen())
end

function removeAllCreatures()
  creatureAgeList = {}
  for _, battleButton in pairs(battleButtonsByCreaturesList) do
    removeCreature(battleButton.creature)
  end
end

function removeCreature(creature)
  if hasCreature(creature) then
    local creatureId = creature:getId()

    if lastBattleButtonSwitched == battleButtonsByCreaturesList[creatureId] then
      lastBattleButtonSwitched = nil
    end

    battleButtonsByCreaturesList[creatureId].creature:hideStaticSquare()
    battleButtonsByCreaturesList[creatureId]:destroy()
    battleButtonsByCreaturesList[creatureId] = nil
  end
end

function onBattleButtonMouseRelease(self, mousePosition, mouseButton)
  if mouseWidget.cancelNextRelease then
    mouseWidget.cancelNextRelease = false
    return false
  end
  if ((g_mouse.isPressed(MouseLeftButton) and mouseButton == MouseRightButton)
    or (g_mouse.isPressed(MouseRightButton) and mouseButton == MouseLeftButton)) then
    mouseWidget.cancelNextRelease = true
    g_game.look(self.creature, true)
    return true
  elseif mouseButton == MouseLeftButton and g_keyboard.isShiftPressed() then
    g_game.look(self.creature, true)
    return true
  elseif mouseButton == MouseRightButton and not g_mouse.isPressed(MouseLeftButton) then
    modules.game_interface.createThingMenu(mousePosition, nil, nil, self.creature)
    return true
  elseif mouseButton == MouseLeftButton and not g_mouse.isPressed(MouseRightButton) then
    if self.isTarget then
      g_game.cancelAttack()
    else
      g_game.attack(self.creature)
    end
    return true
  end
  return false
end

function onBattleButtonHoverChange(battleButton, hovered)
  if battleButton.isBattleButton then
    battleButton.isHovered = hovered
    updateBattleButton(battleButton)
  end
end

function onAttack(creature)
  local battleButton = creature and battleButtonsByCreaturesList[creature:getId()] or lastBattleButtonSwitched
  if battleButton then
    battleButton.isTarget = creature and true or false
    updateBattleButton(battleButton)
  end
end

function onFollow(creature)
  local battleButton = creature and battleButtonsByCreaturesList[creature:getId()] or lastBattleButtonSwitched
  if battleButton then
    battleButton.isFollowed = creature and true or false
    updateBattleButton(battleButton)
  end
end

function updateStaticSquare()
  for _, battleButton in pairs(battleButtonsByCreaturesList) do
    if battleButton.isTarget then
      battleButton:update()
    end
  end
end

function updateCreatureSkull(creature, skullId)
  local battleButton = battleButtonsByCreaturesList[creature:getId()]
  if battleButton then
    battleButton:updateSkull(skullId)
  end
end

function updateCreatureEmblem(creature, emblemId)
  local battleButton = battleButtonsByCreaturesList[creature:getId()]
  if battleButton then
    battleButton:updateSkull(emblemId)
  end
end

function updateBattleButton(battleButton)
  battleButton:update()
  if battleButton.isTarget or battleButton.isFollowed then
    -- set new last battle button switched
    if lastBattleButtonSwitched and lastBattleButtonSwitched ~= battleButton then
      lastBattleButtonSwitched.isTarget = false
      lastBattleButtonSwitched.isFollowed = false
      updateBattleButton(lastBattleButtonSwitched)
    end
    lastBattleButtonSwitched = battleButton
  end
end

and this into your Battle.Otui
CSS:
BattleIcon < UICheckBox
  size: 20 20
  image-color: white
  image-rect: 0 0 20 20

  $hover !disabled:
    color: #cccccc

  $!checked:
    image-clip: 0 0 20 20

  $hover !checked:
    image-clip: 0 40 20 20

  $checked:
    image-clip: 0 20 20 20

  $hover checked:
    image-clip: 0 60 20 20

  $disabled:
    image-color: #ffffff88

BattlePlayers < BattleIcon
  image-source: /images/game/battle/battle_players

BattleNPCs < BattleIcon
  image-source: /images/game/battle/battle_npcs

BattleSkulls < BattleIcon
  image-source: /images/game/battle/battle_skulls

BattleParty < BattleIcon
  image-source: /images/game/battle/battle_party

MiniWindow
  id: battleWindow
  !text: tr('Battle')
  height: 166
  @onClose: modules.game_battle.onMiniWindowClose()
  &save: true

  Panel
    id: filterPanel
    margin-top: 26
    anchors.top: parent.top
    anchors.left: parent.left
    anchors.right: miniwindowScrollBar.left
    height: 45

    Panel
      anchors.top: parent.top
      anchors.horizontalCenter: parent.horizontalCenter
      height: 20
      width: 120
      layout:
        type: horizontalBox
        spacing: 5

      BattlePlayers
        id: hidePlayers
        !tooltip: tr('Hide players')
        @onCheckChange: modules.game_battle.checkCreatures()

      BattleNPCs
        id: hideNPCs
        !tooltip: tr('Hide Npcs')
        @onCheckChange: modules.game_battle.checkCreatures()

      BattleSkulls
        id: hideSkulls
        !tooltip: tr('Hide non-skull players')
        @onCheckChange: modules.game_battle.checkCreatures()

      BattleParty
        id: hideParty
        !tooltip: tr('Hide party members')
        @onCheckChange: modules.game_battle.checkCreatures()

    Panel
      anchors.top: prev.bottom
      anchors.horizontalCenter: parent.horizontalCenter
      height: 20
      width: 128
      margin-top: 6

      ComboBox
        id: sortTypeBox
        width: 74
        anchors.top: parent.top
        anchors.left: prev.right
        anchors.horizontalCenter: parent.horizontalCenter
        margin-left: -28

      ComboBox
        id: sortOrderBox
        width: 54
        anchors.top: parent.top
        anchors.left: prev.right
        margin-left: 4

  Panel
    height: 18
    anchors.top: prev.bottom
    anchors.left: parent.left
    anchors.right: miniwindowScrollBar.left
    margin-top: 5

    UIWidget
      id: toggleFilterButton
      anchors.top: prev.top
      width: 21
      anchors.horizontalCenter: parent.horizontalCenter
      image-source: /images/ui/arrow_vertical
      image-rect: 0 0 21 12
      image-clip: 21 0 21 12
      @onClick: modules.game_battle.toggleFilterPanel()
      phantom: false

  HorizontalSeparator
    anchors.top: prev.top
    anchors.left: parent.left
    anchors.right: miniwindowScrollBar.left
    margin-right: 1
    margin-top: 11

  MiniWindowContents
    anchors.top: prev.bottom
    margin-top: 6

    Panel
      id: battlePanel
      anchors.left: parent.left
      anchors.right: parent.right
      anchors.top: parent.top
      margin-top: 5
      padding-right: 5
      layout:
        type: verticalBox
        fit-children: true
 
I need hide specific monsters not all, im trying hide monsters that havent name and hp bar, like traps (\data\monster\Traps)
 
You can try to add here another elseif statement edubart/otclient
Lua:
elseif creature:isMonster() then
 for i = 1, #monsterNames do
   if creature:getName(monsterNames.[i]) then
      return false
  end
 end
Probably will do, didn't tested.
 
In modules/game_battle/battle.lua

under

Lua:
function doCreatureFitFilters(creature)
  if creature:isLocalPlayer() then
    return false
  end
Add
Lua:
if creature:getHealthPercent() == 0 then
  return false
end
 
Solution
In modules/game_battle/battle.lua

under

Lua:
function doCreatureFitFilters(creature)
  if creature:isLocalPlayer() then
    return false
  end
Add
Lua:
if creature:getHealthPercent() == 0 then
  return false
end

Thank you, the code worked, is possible remove this black square when something that havent name/hp displaying, attacks?

a.png
 
Back
Top