Determining the colour of a single character at a time

Posted by Twisol on Thu 09 Apr 2009 04:37 PM — 11 posts, 38,178 views.

USA #0
I know there's some black magic out there called style runs, but I can't seem to understand how to use them properly. I have some output from a MAP command (in Achaea), which looks like this.


\
-[ ]-[ ]
      | 
      |      [ ]-[ ]-[+]
\     |       | x | x | 
 [ ]-[ ]     [ ]-[ ]-[ ]-[ ]
/     |     / | x | x |   | 
     [ ]-[ ] [ ]-[ ]-[ ] [ ]
      | x |                 \
     [ ]-[ ]                 [ ]-[ ]-[ ]
          |                 /
         [ ] [ ]-[ ]     [ ]
          | \ | x |     /
         [ ]-[ ]-[ ]-[ ]
            \ | /     | \


Each of the [ and ] marks are coloured, as well as some of the line connections. My plugin parses this and puts it in a miniwindow, where it looks like this.


\
-#-#
   |
   |   #-#-#
\  |   |x|x| 
 #-#   #-#-#-#
/  |  /|x|x| | 
   #-# #-#-# #
   |x|        \
   #-#         #-#-#
     |        /
     # #-#   #
     |\|x|  /
     #-#-#-#
      \|/  |\


I want to copy the colour of the [ ] marks onto the corresponding # mark, and maintain the colour of the line connections. I have no idea how to do this, however. A simple example would be a great starting point for me.
Australia Forum Administrator #1
This thread should help:

http://mushclient.com/forum/?id=7818

Perhaps if you show your current plugin I could advise how to incorporate that into copying the map into the miniwindow.
USA #2
I found that topic before, and I've been using it to try to work on the colouring myself. It would be very nice if there was a documentation page on style runs detailing the relevant variables and functions and whatnot, like TriggerStyleRuns (which I couldn't find anything on outside that topic).

I'm actually surprised... with a lot of effort and a lot of debugging, I got colours into the map. The problem now is that the colours are wrong. Here's what my miniwindow map shows: http://img17.imageshack.us/img17/6247/map2s.jpg

It's based on the MAP output I put in the first post. You can't tell from it, but all of the rooms are purple except for the 3x3 block in the center of the output, which are green (forest rooms). For some reason it's pushing the purple and green and green over too far. I know it's outputting properly, and all of the information is coming from one trigger, so here's the trigger's script:


-- runs for each row in the MAP output

local line = "%0"
local row = {} -- contains {char, colour} pairs for each cell

-- store the first style run
local style = GetStyle(TriggerStyleRuns, 1)
-- mark where the next run begins
local styleEnd = style.length

-- Increment by two to skip over unnecessary spaces
-- from the original (including the [ and ] marks)
for i = 1, line:len(), 2 do
  -- move to the next style if we need to
  if i > styleEnd then
    style = GetStyle(TriggerStyleRuns, styleEnd+1)
    styleEnd = styleEnd + style.length
  end

  -- if this is true, we know it's a "[ ]"
  if (i % 4 == 3) and (line:sub(i-1, i-1) == "[") then
    -- replace it with a # of the same colour
    table.insert(row, {"#", style.textcolour})
  else
    -- keep the same character that was there
    table.insert(row, {line:sub(i, i):upper(), style.textcolour})
  end
end

-- after the entire map is processed, it draws the
-- entire grid, so we store each row for later
table.insert(grid, row)


Well, I'm making progress, heh.
Amended on Fri 10 Apr 2009 07:27 AM by Twisol
USA #3
You're using Lua... The simplest thing to do is change the Script declaration to add a fourth parameter (name, line, wcards, sruns)

MushClient passes in a table to sruns with all the stylerun information.

function MapMunger (name, line, wcards, sruns)
 for a,b in ipairs(sruns) do
  local newtext = b.text:gsub("%[[ +]%]", "#"):gsub(" ([%/%\%|x]) ", "%1"):gsub("  "," ")
  ColourTell(RGBColourToName(b.textcolour), RGBColourToName(b.backcolour), newtext )
 end
 print()
end



In a Miniwindow, after you have set up your WindowCreate and WindowFont, you can do something like:


vPos = 0
function MapMover (name, line, wcards, sruns)
 local hPos = 0
 for a,b in ipairs(sruns) do
  local hPos = 0
  local newtext = b.text:gsub("%[[ +]%]", "#"):gsub(" ([%/%\%|x]) ", "%1"):gsub("  "," ")
 
  hPos = WindowText("Map", "fontID", newtext, hPos, vPos, 0,0, b.textcolour, false)
 end
 vPos = vPos + WindowFontInfo("fontID", 1)
end


In your triggers, when you re-initialize grid, you'd call WindowRectOp("Map", 2, 0,0,0,0, 0,0) to blank the miniwindow, and vPos = 0 to reset the map's drawing coordinates.
Amended on Fri 10 Apr 2009 08:07 AM by WillFa
USA #4
It's not that simple, because the [ ] takes up three spaces and the replacement # only takes up one. The rest of the original output relies on that three-to-one ratio, as you can see by comparing the original to the output in my first post, so I just skip over every other column (since those skipped columns contain nothing but spaces, ['s, and ]'s)

Running that gsub chain above, over the first line below, yields the second line, which isn't what I want. I do want to be able to use the symbols between the [ ] marks eventually, so I also don't want to just strip them out.

     [ ]- - -[<]- - -[+]- - -[ ]-[ ]-[ ]-[x]
   #- - -[<]- - -#- - -#-#-#-[x]



Is TriggerStyleRuns not the same as the fourth argument? For the record this code is in the trigger Send box, not defined in its own function.

Anyways, I managed to "fix" it by just using GetStyle inline in the insert calls instead, although I still wish I knew what was messing the first version up. Here's the final code, even though it feels pretty inefficient.


-- runs for each row in the MAP output

local line = "%0"
local row = {} -- contains {char, colour} pairs for each cell

-- Increment by two to skip over unnecessary spaces
-- from the original (including the [ and ] marks)
for i = 1, line:len(), 2 do
  -- if this is true, we know it's a "[ ]"
  if (i % 4 == 3) and (line:sub(i-1, i-1) == "[") then
    -- replace it with a # of the same colour
    table.insert(row, {"#", (GetStyle(TriggerStyleRuns, i-1)).textcolour})
  else
    -- keep the same character that was there
    table.insert(row, {line:sub(i, i):upper(), (GetStyle(TriggerStyleRuns, i)).textcolour})
  end
end

-- after the entire map is processed, it draws the
-- entire grid, so we store each row for later
table.insert(grid, row)
Amended on Fri 10 Apr 2009 08:52 AM by Twisol
Australia Forum Administrator #5
Quote:

Is TriggerStyleRuns not the same as the fourth argument?


Yes, it is the 4th argument. I think it is only set up for send-to-script-after-omit.

Are the groups of 3 always the same colour? I would be tempted to turn the batches of 3 characters into a single table entry, along with its colour, and then render that.
USA #6
That's what I figured, thanks.

Apparently, the [ and ] are the same colour, but the symbol in the middle (whether it be space or otherwise) usually isn't. That's why I have to check backwards a style (or forwards, come to think of it) when I translate a [ ] to a #. (I'm effectively ignoring the style in the middle, but everything else needs to be coloured the same)

If I understand what you meant, you're asking if the styles change every three columns? Unforunately not, the styles aren't easily predictable, except that bracket pairs are the same colour.

EDIT: Here's a good example of what the MAP output looks like, coloured. It's the same one from the first post, except moved south a bit. http://img17.imageshack.us/img17/3551/mapmnd.png
Amended on Sat 11 Apr 2009 07:20 AM by Twisol
Australia Forum Administrator #7
If I may suggest, it wouldn't take a heap of work to convert the style runs into a simple table of one character each, along with its associated colour.

In other words, style runs are simply sequences of one or more characters, all in the some colour, boldness etc. This is done to save space in the client more than anything.

For a single line, you could expand the style run into a table of characters/colours.

Then a simple run-through would let you convert batches of 3 entries into a suitable character to put into your miniwindow.


USA #8
So you're suggesting I make two passes, one to expand the style runs and another to convert the line? I.e., I have the line and a "run" here, where the number denotes a "colour" and the start of the run (since each run has a length):


Line:  - - - - -[+]- - -[ ]-
Style: 1        2321    2121


And convert the style into, say, this, "filling the blanks" so to speak so I can just index into a table for the style I want?


Style: 111111111232111112121


I suppose that could work too. Or did I misunderstand?
Australia Forum Administrator #9
Yes I think you understood. :-)

Let me illustrate ...

Standard Smaug has a coloured prompt, so if I make a trigger that matches on it, and displays the style runs it looks like this:


<triggers>
  <trigger
   enabled="y"
   match="&lt;*&gt;*"
   script="prompt"
   sequence="100"
  >
  </trigger>
</triggers>


Script:

function prompt (name, line, wildcards, styles)
  require "tprint"
  
  tprint (styles)	

end


Output:

<10000hp 25000m 110mv> <#10300> 

1:
  "textcolour"=12632256
  "backcolour"=0
  "length"=1
  "style"=0
  "text"="<"
2:
  "textcolour"=65535
  "backcolour"=0
  "length"=8
  "style"=1
  "text"="10000hp "
3:
  "textcolour"=16776960
  "backcolour"=0
  "length"=7
  "style"=1
  "text"="25000m "
4:
  "textcolour"=65280
  "backcolour"=0
  "length"=5
  "style"=1
  "text"="110mv"
5:
  "textcolour"=12632256
  "backcolour"=0
  "length"=11
  "style"=0
  "text"="> <#10300> "



Now if we change the trigger function to expand the styles:


function prompt (name, line, wildcards, styles)
  require "tprint"
  
  tprint (styles)	

  chars = {}
  
  for _, style in ipairs (styles) do
    for i = 1, style.length do
      table.insert (chars, { char = style.text:sub (i, i), 
                             textcolour = style.textcolour,
                             backcolour = style.backcolour,
                            }
                   ) 
                            
                            
    end -- for each style run
  
  end -- for all styles
  
  
  tprint (chars)
  
end



We now see each character in its own table entry:


1:
  "char"="<"
  "textcolour"=12632256
  "backcolour"=0
2:
  "char"="1"
  "textcolour"=65535
  "backcolour"=0
3:
  "char"="0"
  "textcolour"=65535
  "backcolour"=0
4:
  "char"="0"
  "textcolour"=65535
  "backcolour"=0
5:
  "char"="0"
  "textcolour"=65535
  "backcolour"=0
6:
  "char"="0"
  "textcolour"=65535
  "backcolour"=0
7:
  "char"="h"
  "textcolour"=65535
  "backcolour"=0
8:
  "char"="p"
  "textcolour"=65535
  "backcolour"=0
9:
  "char"=" "
  "textcolour"=65535
  "backcolour"=0
10:
  "char"="2"
  "textcolour"=16776960
  "backcolour"=0
11:
  "char"="5"
  "textcolour"=16776960
  "backcolour"=0
12:
  "char"="0"
  "textcolour"=16776960
  "backcolour"=0
13:
  "char"="0"
  "textcolour"=16776960
  "backcolour"=0
14:
  "char"="0"
  "textcolour"=16776960
  "backcolour"=0
15:
  "char"="m"
  "textcolour"=16776960
  "backcolour"=0
16:
  "char"=" "
  "textcolour"=16776960
  "backcolour"=0
17:
  "char"="1"
  "textcolour"=65280
  "backcolour"=0
18:
  "char"="1"
  "textcolour"=65280
  "backcolour"=0
19:
  "char"="0"
  "textcolour"=65280
  "backcolour"=0
20:
  "char"="m"
  "textcolour"=65280
  "backcolour"=0
21:
  "char"="v"
  "textcolour"=65280
  "backcolour"=0
22:
  "char"=">"
  "textcolour"=12632256
  "backcolour"=0
23:
  "char"=" "
  "textcolour"=12632256
  "backcolour"=0
24:
  "char"="<"
  "textcolour"=12632256
  "backcolour"=0
25:
  "char"="#"
  "textcolour"=12632256
  "backcolour"=0
26:
  "char"="1"
  "textcolour"=12632256
  "backcolour"=0
27:
  "char"="0"
  "textcolour"=12632256
  "backcolour"=0
28:
  "char"="3"
  "textcolour"=12632256
  "backcolour"=0
29:
  "char"="0"
  "textcolour"=12632256
  "backcolour"=0
30:
  "char"="0"
  "textcolour"=12632256
  "backcolour"=0
31:
  "char"=">"
  "textcolour"=12632256
  "backcolour"=0
32:
  "char"=" "
  "textcolour"=12632256
  "backcolour"=0


Now it would be a simple matter to walk through that table (eg. in lots of 3) and extract out each character and its associated colour.
USA #10
Right, right. Thanks for the help =)