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.
--[[ 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()