Help with a highlight script

Iktomi
Posts: 46
Joined: Sat Sep 03, 2011 4:00 am

Help with a highlight script

Post by Iktomi »

Hey everyone, with much help from Rakon I've been working on script that will allow me to manually add a name to table, and then have tempTriggers created for each of those names which will highlight them. So far I've had success in adding and removing people from the table, and I've got a function to highlight the names, but it's only highlighting the first name in the table, and not going through the entire thing. Here's what I've got:

SCRIPT:
Code: [show] | [select all] lua
function highlight()
  for k,v in ipairs(listFriends) do
    highlight[v] = tempRegexTrigger("\\b(?i)"..v.."\\b", [[selectString("]]..v..[[", 1) fg("red") resetFormat()]])
  end
 end


Like I said, so far this is only creating a tempTrigger for the first item in the list. How do I tell it to do so for the entire table? Also, it should be giving the temp trigger the ID of highlight[v]... but how exactly does this really pan out? If v = Rikeshar, then is the ID highlightRikeshar? highlight[Rikeshar]? something else?

The alias I'm using for this is currently split into two different aliases, in order to isolate their effect. The one to add is:
Code: [show] | [select all] lua
PATTERN: ^adf (\w+)$

if table.contains(listFriends,matches[2]) == true then
  echo ("\n!! "..matches[2].." already in List !!")
else
  table.insert(listFriends,matches[2])
    echo ("\n!! "..matches[2].." added to the list !!")
end

table.save(getMudletHomeDir().."/highlights.lua", listFriends)
 
and the one to remove is:
Code: [show] | [select all] lua
 PATTERN: ^rmf (\w+)$

if table.contains(listFriends,matches[2]) == true then
  for k,v in ipairs(listFriends) do
    if v == matches[2] then
      table.remove(listFriends, k) 
  end
end
  echo ("\n!! "..matches[2].." removed from List !!")
    killRegexTrigger(highlight[matches[2]]) -- This doesn't work !!
else
  echo ("\n!! "..matches[2].." not in the list !!")
end

Does anyone have any ideas? I -think- the only thing I"m missing is how to get the script to cycle through every k,v pair in the table and create the temporary triggers when the function is called, and then I need to exactly what the tempTrigger ID being created with highlight[v] looks like.

Of course, after that I"ll have to put in something to check and see if a temporary trigger for [v] already exists, that way I dont' duplicate tempTriggers when the function is called, but if I can get these two things figure out first, then I can start looking at that.

Thank you in advance for your help!

User avatar
Rakon
Posts: 350
Joined: Tue Feb 16, 2010 7:41 pm
Contact:

Re: Help with a highlight script

Post by Rakon »

Can you run the highlight() function and paste the error that is in the error window, to here??

Also, paste us the listFriends display please.

The fact that only is highlighting the first one correctly leads me to believe there is an error in the for loop.
Like I said, so far this is only creating a tempTrigger for the first item in the list. How do I tell it to do so for the entire table? Also, it should be giving the temp trigger the ID of highlight[v]... but how exactly does this really pan out? If v = Rikeshar, then is the ID highlightRikeshar? highlight[Rikeshar]? something else?
Your script above is assigning the variable contents of 'v' in the highlight table to the tempRegex return (which is a timer id integer) value. So:

Lets assume the v variable in the loop was Rakon and the tempRegex returned the id of 12345. Your highlight table would be

Code: Select all

table {
  'Rakon': 12345
}
Make sense?
Then when you go to REMOVE a name from the listFriends you check this table for the existence of the name (key) and then use the id (value) to killTrigger(id) of that highlight!

User avatar
tsuujin
Posts: 695
Joined: Fri Feb 26, 2010 12:59 am
Location: California
Contact:

Re: Help with a highlight script

Post by tsuujin »

I'll post you an example from my system which may help you in this problem. This is the module I use for handling enemy/ally highlighting. There's stuff in there you probably won't want (for example, I store all my relations in a database for cross-session integrity) but the highlighting function is pretty solid.
Code: [show] | [select all] lua
--[[ Tracking system for player relations (enemies and allies) ]]--
require "dba"
require "php"

module("player",package.seeall)

-- Private Variables
local list = {}
local trigs = {}
local priority = {}
local colors = {}

function init()
    dbInit()
    dbLoad()
    setCategoryPriority("ally,enemy")
    setFactionPriority()
end

function dbInit()
    dba.execute([[
        CREATE TABLE IF NOT EXISTS player_relations (
            name TEXT,
            ally TEXT,
            enemy TEXT,
            CONSTRAINT pk PRIMARY KEY (name) ON CONFLICT REPLACE
        );
    ]])
end

function dbLoad()
    local results = dba.query([[SELECT * FROM player_relations]])
    for num,tbl in results:pairs() do
        for _,i in pairs(string.split(tbl.ally,":")) do add("ally",tbl.name,i) end
        for _,i in pairs(string.split(tbl.enemy,":")) do add("enemy",tbl.name,i) end
    end
end

function dbSave()
    if not dba.begin() then
        tempTimer(1,[[player.dbSave()]])
        return false
    end
    for name,tbl in pairs(list) do
        dba.execute(string.format([[INSERT INTO player_relations VALUES ("%s","%s","%s")]],name,dbString(tbl["ally"]),dbString(tbl["enemy"])))
    end
    dba.commit()
end

function dbString(tbl)
    tbl = tbl or {}
    local str = ""
    local count = 0
    for faction,_ in pairs(tbl) do
        if count > 0 then str = str..":" end
        str = str..faction
        count = count + 1
    end
    return str
end

-- User functions to set colors and priorities
function setPriority(cat,pTable,delim)
    if type(pTable) == "string" then pTable = pTable:split(delim or ",") end
    priority[cat] = pTable or {}
end
function getPriority(cat) return priority[cat] end
function setCategoryPriority(pTable) setPriority("category",pTable) end
function setFactionPriority(pTable) setPriority("faction",pTable) end

function setColor(cat,faction,color)
    if not colors[cat] then colors[cat] = {} end
    colors[cat][faction] = color
end
function setAllyColor(faction,color) setColor("ally",faction,color) end
function setEnemyColor(faction,color) setColor("enemy",faction,color) end
function getColor(cat,faction) return colors[cat][faction] or false end

function add(cat,name,faction)
    -- if the player doesn't yet exist in the table, add it, and create the trigger.
    if not list[name] then list[name] = {} end
    if not trigs[name] then trigs[name] = tempTrigger(name,string.format([[player.highlight("%s")]],name)) end
    if not list[name][cat] then list[name][cat] = {} end
    list[name][cat][faction:lower()] = true
end

function drop(cat,name,faction)
    list[name][cat][faction] = nil
end

-- Clear the list of enemies or allies of particular factions
function clear(cat,faction)
    for name,relation in pairs(list) do
        if relation[cat] then
            for i,_ in pairs(relation[cat]) do
                if i == faction then drop(cat,name,i) end
            end
        end
    end
end

-- TOTAL purge of system. Deletes all information. Clears the database.
function purge()
    for player,relations in pairs(list) do
        killTrigger(trigs[player])
        list[player] = nil
    end
    dba.execute([[DELETE FROM player_relations]])
end

function is(cat,name,faction)
    if not list[name] then return nil end
    if not list[name][cat] then return nil end

    faction = faction or "any"

    -- Just check to see if the person is an enemy -period-
    if faction == "any" then
        local count = 0
        for i,v in pairs(list[name][cat]) do return true end
        return false
    end

    -- Otherwise, check to see if the person is an enemy of a particular faction
    if list[name][cat][faction] then return true end
    return false
end

function highlight(name)
    if not list[name] then return nil end

    local color = nil
    -- Grab the color needed
    for _,cat in pairs(priority["category"]) do
        if color then break end
        if list[name][cat] then
            for _,faction in pairs(priority["faction"]) do
                if list[name][cat][faction] then
                    color = colors[cat][faction]
                    break
                end
            end
        end
    end

    local c = 1
    while selectString(name,c) > -1 do
        local tLen = name:len()
        local pos = selectString(name,c)
        local sChar = line:sub(pos,pos)
        local eChar = line:sub(pos+tLen+1,pos+tLen+1)
        if eChar:match("[^A-Za-z]") or eChar == "" then
            fg(color)
        end
        c = c + 1
    end

    resetFormat()
end

-- End user utility functions for enemy declaration.
function addEnemy(name,faction) add("enemy",name,faction) end
function dropEnemy(name,faction) drop("enemy",name,faction) end
function isEnemy(name,faction) return is("enemy",name,faction) end
function clearEnemies(faction) clear("enemy",faction) end
-- End user utility functions for ally declaration.
function addAlly(name,faction) add("ally",name,faction) end
function dropAlly(name,faction) drop("ally",name,faction) end
function isAlly(name,faction) return is("ally",name,faction) end
function clearAllies(faction) clear("ally",faction) end
init()

Phoenix
Posts: 92
Joined: Tue Feb 15, 2011 3:23 am

Re: Help with a highlight script

Post by Phoenix »

Aright, first off - the for k,v in ipairs() that you have, that should be working. If it isn't, check the error log?

Second: highlight[v] = tempRegexTrigger() -- This is not setting the id of the temp trigger, it's setting the table value TO the id. tempRegexTrigger will return the ID, and you are setting it. Make sure that highlight is already a table! This is the same as any table for access... highlight.Rikeshar, highglight["Rikeshar"] are the two ways to get the triggers ID. Again, you're setting the key in the table to the triggers ID, not vice versa! You can not do things the other way around.

Additionally, the script you are using to highlight - this will only work on the first thing in a line... And it'll highlight badly, selecting, say "Lyn" in Lynara if you have Lyn highlighted, and Lynara, then Lyn on the line (it'll match off Lyn, but select the first Lyn which ISN'T guarded by \b)

This colouring function is more exact -
Code: [show] | [select all] lua
 function colorAll(word, color, back, italic, under,bold, noCase)
--word is the string to search for
--color is fg color, either in name or "r,g,b" string
--back is bg color, either in name of "r,g,b" string
--italic is boolean italics
--under is boolean underlining
--bold is boolean bold format
--noCase is boolean. if true, matches word on a no-case pattern

   if noCase then word = word:genNocasePattern() end
   local startpos = 0
   local endpos = 0
   while true do
      startpos, endpos = string.find(line, "%f[%w]"..word.."%f[%W]", endpos)
      if not startpos then break end
      selectSection(startpos-1, endpos-startpos+1)
      if color then
         if color_table[color] then
            fg(color)
         else
             local c = color:split(",")
             setFgColor(c[1],c[2],c[3])
         end
      end
      if back then
         if color_table[back] then
            bg(back)
         else
             local b = back:split(",")
             setBgColor(b[1],b[2],b[3])
         end
      end
      if under then
         setUnderline(true)
      end
      if italic then
         setItalics(true)
      end
      if bold then
         setBold(true)
      end
   end
   resetFormat()
end

User avatar
Omni
Posts: 131
Joined: Fri Feb 12, 2010 10:26 am

Re: Help with a highlight script

Post by Omni »

Code: [show] | [select all] lua
function highlight()
  for k,v in ipairs(listFriends) do
    highlight[v] = tempRegexTrigger("\\b(?i)"..v.."\\b", [[selectString("]]..v..[[", 1) fg("red") resetFormat()]])
  end
 end
The name of your function is the same name of your table. And killRegexTrigger() is not a function. You use killTrigger() for all trigger types.

Iktomi
Posts: 46
Joined: Sat Sep 03, 2011 4:00 am

Re: Help with a highlight script

Post by Iktomi »

The error I'm getting when the function is called says:
[ERROR:] object:<Display> function:<Alias256>
<[string "function highlight()..."]:3: attempt to index global 'highlight' (a function value)>
I changed the highlight[v] at the beginning of the temp trigger to hlName[v] and ran it again, and got an error that it was attempting to index to hlName'' which is a nil value, so I went back again and, taking a queue from Phoenix, defined hlName as a table first. Then, after running the function a third time, all the names in the table listFriends are being highlighted like they should.

No on to killing the trigger... doing display(listFriends) shows:
Code: [show] | [select all] lua
table {
  1: 'Bahtell'
  2: 'Lynara'
}
doing display(hlName) whos:
Code: [show] | [select all] lua
table {
  'Lynara': 2092
  'Bahtell': 2091
}
in the hlName table, "Lynara" is the value, and 2092 is the ID, right? I'm trying to do something like the following now, and it's removing the name from listFriends table, but it's not removing anything from the hlName table or killing the trigger:
Code: [show] | [select all] lua
who = matches[2]

if table.contains(listFriends,who) == true then
  for k,v in ipairs(listFriends) do
    if v == who then table.remove(listFriends, k) end
    echo ("\n!! "..who.." removed from Friends list !!")  
      for v,k in ipairs(hlName) do
        if v == who then table.remove(hlName, v) end
        killTrigger(k)
    end
  end
end
I'm sure my for statement is probably wrong... but I"m not sure what to make it.

Edit: Correcting where I said I changed highlight[v] to hlName to read it was changed to hlName[v]

Iktomi
Posts: 46
Joined: Sat Sep 03, 2011 4:00 am

Re: Help with a highlight script

Post by Iktomi »

Omni wrote:
Code: [show] | [select all] lua
function highlight()
  for k,v in ipairs(listFriends) do
    highlight[v] = tempRegexTrigger("\\b(?i)"..v.."\\b", [[selectString("]]..v..[[", 1) fg("red") resetFormat()]])
  end
 end
The name of your function is the same name of your table. And killRegexTrigger() is not a function. You use killTrigger() for all trigger types.

Yep! Figured that one out, thanks. Also, I changed the killRegextTrigger to just killTrigger because I figured it probably wasn't a valid command either :P

Phoenix
Posts: 92
Joined: Tue Feb 15, 2011 3:23 am

Re: Help with a highlight script

Post by Phoenix »

Haha!! Good effin catch. Can't have two things that have the same name... even three seperate things (function, variable, table). It's the way Lua saves them... Hehehe...

For your "Kill", use this:
Code: [show] | [select all] lua
 if highlight and highlight[matches[2]] then
  killTrigger(highlight[matches[2]])
  echo ("\n!! "..matches[2].." removed from List !!")
else 
  echo ("\n!! "..matches[2].." not in the list !!")
end

User avatar
Rakon
Posts: 350
Joined: Tue Feb 16, 2010 7:41 pm
Contact:

Re: Help with a highlight script

Post by Rakon »

Phoenix wrote:Haha!! Good effin catch. Can't have two things that have the same name... even three seperate things (function, variable, table). It's the way Lua saves them... Hehehe...

For your "Kill", use this:
Code: [show] | [select all] lua
 if highlight and highlight[matches[2]] then
  killTrigger(highlight[matches[2]])
  echo ("\n!! "..matches[2].." removed from List !!")
else 
  echo ("\n!! "..matches[2].." not in the list !!")
end
Might want to add in a matches:title() for those checks and killTrigger.

Iktomi
Posts: 46
Joined: Sat Sep 03, 2011 4:00 am

Re: Help with a highlight script

Post by Iktomi »

Hey Rakon, I haven't had the chance to try things out with the killTrigger yet, but matches:title() does just that? Checks to see if the trigger title matches that? Would it go like this?
Code: [show] | [select all] lua
if hlName and matches:title(hlName(matches[2]))
What is the benefit of using the matches:title() over jus the checks in the post above?

Thank you all for the help so far, I really appreciate it!

Post Reply