Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2018
172
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
XML 49.80 KB | None | 0 0
  1. <?xml version="1.0" encoding="iso-8859-1" ?>
  2. <!DOCTYPE muclient>
  3. <muclient>
  4. <plugin name="LotJRaceBrowser" author="@Johnson" id="a4e8153e52b1b6d490ed4b10" language="Lua" purpose="Browse LotJ Races" save_state="y" requires="4.84" version="1.00">
  5. <description trim="y">
  6. <![CDATA[
  7.  
  8. Sections of this plugin are based on work by Fiendish of Aardwolfmud and other community members.
  9. See 'http://www.gammon.com.au/forum/?id=9385'
  10.  
  11. To use this plugin:
  12.  
  13. Type 'racescan' to gather information from the game and populate into the browser.
  14. Type 'raceshow' to display the browser if you previously closed it.
  15. Type 'racehide' or click the X to close the browser.
  16. Type 'raceclear' to clear the stored race information.
  17.  
  18. This plugin creates a visual index of all current LotJ races. The race list can be sorted by
  19. right clicking anywhere in the window and choosing filters to apply.
  20.  
  21.  ]]>
  22.   </description>
  23.   </plugin>
  24. <!--   Get our standard constants   -->
  25.     <include name="constants.lua" />
  26. <!--   Triggers    -->
  27. <triggers>
  28.  
  29.   <trigger match="^([\s\d]+)\((\d)\)\> (.*) (\d+)\((\d)\)\> (.*) (\d+)\((\d)\)\> (.*) (\d+)\((\d)\)\> (.*)$" script="raceListScanAdd" regexp="y" enabled="n" group="RacelistScan"  omit_from_output="y" omit_from_log="y" sequence="100" />
  30.   <trigger match="^([\s\d]+)\((\d)\)\> (.*) (\d+)\((\d)\)\> (.*) (\d+)\((\d)\)\> (.*)$" script="raceListScanAdd" regexp="y" enabled="n" group="RacelistScan"  omit_from_output="y" omit_from_log="y" sequence="100" />
  31.   <trigger match="^([\s\d]+)\((\d)\)\> (.*) (\d+)\((\d)\)\> (.*)$" script="raceListScanAdd" regexp="y" enabled="n" group="RacelistScan"  omit_from_output="y" omit_from_log="y" sequence="100" />
  32.   <trigger match="^([\s\d]+)\((\d)\)\> (.*)$" script="raceListScanAdd" regexp="y" enabled="n" group="RacelistScan"  omit_from_output="y" omit_from_log="y" sequence="100" />
  33.  
  34.   <trigger name="RacelistScanStart" match="^\(L\)egend\: Race Number \(Era Restriction or 0 for none\)\> Race Name $" script="enableRaceListScan" regexp="y" enabled="n"  omit_from_output="y" omit_from_log="y" sequence="100" />
  35.   <trigger name="RacelistScanStop" match="^$" script="stopRacelistScan" regexp="y" enabled="n"  omit_from_output="y" omit_from_log="y" sequence="100" />
  36.  
  37.   <trigger lines_to_match="6"
  38.   match="\(R\)ace\: (.*)\nStr Plus\:([\s\d,-]+)Dex Plus\:([\s\d,-]+)Wis Plus\:([\s\d,-]+)Int Plus\:([\s\d,-]+)\nCon Plus\:([\s\d,-]+)Cha Plus\:([\s\d,-]+)Lck Plus\:([\s\d,-]+)\nHit Pts\:([\s\d]+)AC Mod\:([\s\d,-]+)Frc Plus\:([\s\d,-]+)\nPrice\:([\s\d]+)Deposit\:([\s\d]+)App Only\:(.*)\Z"
  39.   script="addRaceScanFirst"
  40.   multi_line="y"
  41.   regexp="y"
  42.   enabled="n"
  43.   group="raceScanFirst" omit_from_output="y" omit_from_log="y"
  44.   sequence="100" />
  45.  
  46.   <trigger match="^Players of this race must pick (.*) as their main\.$" script="addRaceMainClass" regexp="y" enabled="n" group="raceScanSecond"  omit_from_output="y" omit_from_log="y" sequence="100" />
  47.  
  48.   <trigger lines_to_match="2" match="\(D\)efault Language\: (.*)\n\(P\)ossible Skincolors\: \Z" script="addRaceScanSecond" multi_line="y" regexp="y" enabled="n" group="raceScanSecond" omit_from_output="y" omit_from_log="y" sequence="100" />
  49.  
  50.   <trigger match="^\((\d+)\)([\w\s]+)\((\d+)\)([\w\s]+)$" script="addSkinColors" regexp="y" group="SkinColors" enabled="n"  omit_from_output="y" omit_from_log="y" sequence="100" />
  51.   <trigger match="^\((\d+)\)([\w\s]+)$" script="addSkinColors" regexp="y" group="SkinColors" enabled="n"  omit_from_output="y" omit_from_log="y" sequence="100" />
  52.   <trigger match="^$" script="stopSkinColors" regexp="y" group="SkinColors" enabled="n"  omit_from_output="y" omit_from_log="y" sequence="100" />
  53.   <trigger match="^(.*) \- (.*)$" script="addExtraAttrib" regexp="y" group="ExtraAttribs" enabled="n"  omit_from_output="y" omit_from_log="y" sequence="100" />
  54.   <trigger match="^$" script="stopExtraAttribs" regexp="y" group="ExtraAttribs" enabled="n"  omit_from_output="y" omit_from_log="y" sequence="100" />
  55.   <trigger match="^(.*)    (.*)$" script="addRaceLevels" regexp="y" group="RaceLevels" enabled="n"  omit_from_output="y" omit_from_log="y" sequence="100" />
  56.   <trigger match="^$" script="stopRaceLevels" regexp="y" group="RaceLevels" enabled="n"  omit_from_output="y" omit_from_log="y" sequence="100" />
  57.   <trigger name="gagAll" match="^(.*)$" regexp="y" keep_evaluating="y" omit_from_output="y" omit_from_log="y" enabled="n" sequence="100" />
  58. </triggers>
  59.  
  60. <aliases>
  61.  
  62.     <alias match="racescan" script="startRacelistScan" enabled="y" regexp="n" ignore_case="y" group="LotJRaceBrowser" sequence="100" />
  63.     <alias match="raceclear" script="clearTable" enabled="y" regexp="n" ignore_case="y" group="LotJRaceBrowser" sequence="100" />
  64.     <alias match="raceshow" script="showWindow" enabled="y" regexp="n" ignore_case="y" group="LotJRaceBrowser" sequence="100" />
  65.     <alias match="racehide" script="hideWindow" enabled="y" regexp="n" ignore_case="y" group="LotJRaceBrowser" sequence="100" />
  66.   <alias match="raceprint *" script="printRace" enabled="y" regexp="n" ignore_case="y" group="LotJRaceBrowser" sequence="100" />
  67.  
  68.  
  69.  
  70. </aliases>
  71. <!--   Script    -->
  72. <script>
  73. <![CDATA[
  74.  
  75. require "movewindow"
  76. require "copytable"
  77. require "serialize"
  78. require "tprint"
  79. require "pairsByKeys"
  80.  
  81. -- enable these to ensure everything works smooth
  82. SetOption("enable_triggers", true)
  83. SetOption("enable_scripts", true)
  84.  
  85. local AUTHOR = GetPluginInfo(GetPluginID(), 2) -- author info
  86. local VERSION = string.format("%1.2f", GetPluginInfo(GetPluginID(), 19)) -- version info
  87. local win = "win_" .. GetPluginID()  -- unique window name
  88. local font = "f"
  89. local default_font_name = GetInfo(20)
  90. local default_font_size = GetInfo(243)
  91. local font_name = GetVariable("font_name") or default_font_name
  92. local font_size = tonumber(GetVariable("font_size")) or default_font_size
  93. local RESIZE_TAG_SIZE = 10
  94. local visible = GetVariable("visible") or "true"
  95. local MIN_WIDTH   = 50
  96. local MIN_HEIGHT  = 50
  97. local MIN_SPLIT   = 75
  98. local redraw_scheduled = false
  99.  
  100.  
  101. -- default config
  102. local default_config = {  height = 300,
  103.            width = 750,
  104.            split = 150, -- location from left for window split
  105.            backcolor = "black",
  106.            }
  107.  
  108. -- replace default with loaded config
  109. loadstring(GetVariable("config") or "") ()
  110.  
  111. local SCROLL_BACKGROUND_COLOUR = 0xE8E8E8
  112. local SCROLL_BAR_COLOUR = 0x111111
  113. local SCROLL_DETAIL_COLOUR = 0x000000
  114. local SCROLL_BAR_WIDTH = 15
  115.  
  116. local titleHeight = 0
  117.  
  118. local lastRefresh = 0
  119.  
  120. local filter_main_class = ""
  121. local filter_classes = {}
  122. local filter_stats = {}
  123.  
  124. races = {}
  125. local newRace = {}
  126.  
  127. local raceSelected = -1
  128.  
  129. local raceDisplayedStart = 0
  130. local raceDisplayedEnd = 0
  131. local raceLineHeight = 0
  132. local spacer = 3
  133.  
  134. local currentRace = {}
  135. local currentRaceIndex = 0
  136. local skinColors = {}
  137. local extraAttribs = {}
  138. local raceLevels = {{}}
  139.  
  140. local text = {}
  141. local textStart = 0
  142. local textEnd = 0
  143.  
  144. loadstring(GetVariable("races") or "") ()
  145.  
  146.  
  147.  
  148. function printBrowseList()
  149.  local posy = titleHeight
  150.  local font_height = WindowFontInfo(win, font, 1)
  151.  if #races > 0 then
  152.    for i = raceDisplayedStart, raceDisplayedEnd do
  153.      WindowText (win, font, races[i].name, 5, posy, 0, 0, ColourNameToRGB(((i==raceSelected and "red") or ((races[i].str~=nil and "white") or "darkgray"))))
  154.      posy = posy + font_height + spacer
  155.    end
  156.  end
  157. end
  158.  
  159. function printRace(name, line, args)
  160.  local num = tonumber(args[1])
  161.  if num then
  162.    if races[num] then
  163.      tprint(races[num])
  164.    end
  165.  end
  166. end
  167.  
  168. function raceClick()
  169.  hottop = WindowHotspotInfo(win, "leftbackground", 2)
  170.  clickpos = WindowInfo(win, 15)
  171.  raceIndex = math.floor((clickpos-hottop)/raceLineHeight)+raceDisplayedStart
  172.  --Note("tFit: "..textFit.." tStart: "..textStart.." eEnd: "..textEnd.." #text: "..#text)
  173.  updateSelectedRace()
  174. end
  175.  
  176. function updateRaceText()
  177.  if raceSelected > -1 then -- we chose something
  178.    local race = races[raceSelected]
  179.    if race.price == nil or race.deposit==nil or race.language==nil or race.ac==nil or race.hp==nil or race.apponly==nil or race.str==nil or race.dex==nil or race.con==nil or race.int==nil or race.wis==nil or race.cha==nil or race.frc==nil or race.lck==nil or race.erarestrict==nil then
  180.      -- tried to access while still scanning or invalid scan data
  181.      addText( {"red","Either your race data is invalid or scan is still underway..."}, font, "center")
  182.      textEnd = math.min(#text, textStart+textFit-2)
  183.      return
  184.    end
  185.    if race ~= nil then
  186.      text = {} -- clear the text
  187.      local left = config.split+2
  188.      local top = titleHeight
  189.      local right = config.width-SCROLL_BAR_WIDTH
  190.      local bot = config.height
  191.      local filler = string.rep("-", 20)
  192.      local title_width = WindowTextWidth(win, font, race.name)
  193.      addText( {"white",filler.."Race"..filler}, font, "center")
  194.      addText( {"cyan",race.name}, font, "center")
  195.      
  196.      addText( {"white", filler.."Stats"..filler}, font, "center")
  197.      addText( {"white","Price: ",((race.price==0 and "lime") or "red"),race.price,"white"," Deposit: ",((race.deposit==0 and "lime") or "red"),race.deposit,"white"," Language: ","red",race.language}, font, "center")
  198.      addText( {"white","AC: ","red",race.ac,"white"," Base HP: ","red",race.hp,"white"," App Only: ",((race.apponly=="Yes" and "red") or "lime"),race.apponly}, font, "center")
  199.      addText( {"white","Str: ","red",race.str,"white"," Dex: ","red",race.dex,"white"," Con: ","red",race.con}, font, "center")
  200.      addText( {"white","Int: ","red",race.int,"white"," Wis: ","red",race.wis,"white"," Cha: ","red",race.cha}, font, "center")
  201.      addText( {"white","Frc: ","red",race.frc,"white"," Lck: ","red",race.lck,"white"," Era Restrict: ",((race.erarestrict==0 and "lime") or "red"),race.erarestrict}, font, "center")
  202.      
  203.      addText( {"white",filler.."Levels"..filler}, font, "center")
  204.      addText( {"white","               COM PIL ENG HUN SMU DIP LEA ESP SLI MED SCI"}, font, "center")
  205.      for a, b in pairsByKeys(race.levels) do
  206.        local t = {}
  207.        --t[#t+1]=((b.class==race.mainclass and "cyan") or "white")
  208.        --t[#t+1]=string.format("%14s", b.class)..": "
  209.        t[#t+1]=((a==race.mainclass and "cyan") or "white")
  210.        t[#t+1]=string.format("%14s",a)..": "
  211.        for i, j in ipairs(b.levels) do
  212.          t[#t+1]=((j=="5" and "red") or ((j=="4" and "yellow") or ((j=="3" and "cyan") or ((j=="2" and "lime") or "blue"))))
  213.          t[#t+1]=" "..j.."  "
  214.        end
  215.        addText( t, font, "center")
  216.      end
  217.      if #race.attribs > 0 then
  218.        addText( {"white",filler.."Extra Arributes"..filler}, font, "center")
  219.        local temp = ""
  220.        for i, j in ipairs(race.attribs) do
  221.          addText( {"lime",j.name,"white"," - ","lime",j.desc}, font, "center")
  222.        end
  223.      end
  224.  
  225.    textEnd = math.min(#text, textStart+textFit-2)
  226.    end
  227.  end
  228.  
  229. end
  230.  
  231. function addText(addtext, font, align, pos)
  232.  local line = { t = copytable.deep(addtext), f = font, a = align, p = pos }
  233.  text[#text + 1] = line
  234. end
  235.  
  236. function drawText()
  237.  --textEnd = math.min(textFit, #text)
  238.  local posy = titleHeight
  239.  local bound = { left = config.split+2, top = titleHeight, right = config.width-SCROLL_BAR_WIDTH, bot = config.height-2 } -- valid bounding box for drawing
  240.  
  241.  if #text >= 1 then
  242.    for i = textStart, textEnd do
  243.      v = text[i]
  244.      if v~=nil then
  245.        local pos = {}
  246.        local alltext = ""
  247.        for a, b in ipairs(v.t) do
  248.          if math.fmod(a-1, 2)==1 then -- text
  249.            alltext = alltext..b
  250.          end
  251.        end
  252.  
  253.      local textWidth = WindowTextWidth(win, v.f, alltext)
  254.      local textHeight = WindowFontInfo(win, v.f, 1)
  255.      if v.a == "left" then
  256.        pos = { left = bound.left, top = posy, right = bound.left+textWidth, bot = posy+textHeight }
  257.      elseif v.a == "center" then
  258.        pos = { left = (bound.left+((bound.right-bound.left)/2))-(textWidth/2), top = posy, right = (bound.left+((bound.right-bound.left)/2))+(textWidth/2), bot = posy+textHeight }
  259.      elseif v.a == "right" then
  260.        pos = { left = bound.right-textWidth, top = posy, right = bound.right, bot = posy+textHeight }
  261.      else
  262.        pos = v.p
  263.      end
  264.      local colour = ""
  265.      for a, b in ipairs(v.t) do
  266.        if math.fmod(a-1, 2)==0 then -- got the colour
  267.          colour = b
  268.        elseif math.fmod(a-1, 2)==1 then -- got the text
  269.          tWidth = WindowTextWidth(win, v.f, b)
  270.          pos.left = pos.left + WindowText(win, v.f, b, pos.left, pos.top, pos.left+tWidth, pos.bot, ColourNameToRGB(colour))
  271.        end
  272.      end
  273.  
  274.      posy = posy + textLineHeight
  275.    end
  276.  end
  277.  end
  278.  
  279. end
  280.  
  281. function findBestClass(levels)
  282.  local best = 0
  283.  
  284.  
  285. end
  286.  
  287. function addLevels(list)
  288.  local total = 0
  289.  for i, v in pairs(list) do
  290.    total = total + v
  291.  end
  292.  return total
  293. end
  294.  
  295. function raceListScanAdd(name, line, args)
  296.  local race = {}
  297.  for i, v in pairs(args) do
  298.    if math.fmod(i-1, 3)==0 then -- index
  299.      race.index = tonumber(v)
  300.      --Note("found race index: "..v)
  301.    elseif math.fmod(i-1, 3)==1 then -- era restrict
  302.      race.erarestrict = tonumber(v)
  303.      --Note("found era restrict: "..v)
  304.    elseif math.fmod(i-1, 3)==2 then -- race name
  305.      race.name = Trim(v)
  306.      --Note("found race name: "..v)
  307.      races[#races + 1] = race
  308.      race = {}
  309.    end
  310.  end
  311.  
  312. end
  313.  
  314. function startRacelistScan(name, line, args)
  315.  races = {}
  316.  SendNoEcho("showrace")
  317.  EnableTrigger("RacelistScanStart", true)
  318.  EnableTrigger("gagAll", true)
  319.  ColourNote("yellow", "", "Racelist Scan started...")
  320.  
  321. end
  322.  
  323. function enableRaceListScan(name, line, args)
  324.  EnableTriggerGroup("RacelistScan", true)
  325.  EnableTrigger("RacelistScanStart", false)
  326.  EnableTrigger("RacelistScanStop", true)
  327.  
  328. end
  329.  
  330. function stopRacelistScan(name, line, args)
  331.  EnableTriggerGroup("RacelistScan", false)
  332.  EnableTrigger("RacelistScanStart", false)
  333.  EnableTrigger("RacelistScanStop", false)
  334.  ColourNote("yellow", "", "Racelist Scan complete. Found "..#races.." races.")
  335.  races.scantime = os.time()
  336.  SetUpHotspotsAndDraw(false)
  337.  --tprint(races)
  338.  startRaceScan()
  339. end
  340.  
  341. function startRaceScan(name, line, args)
  342.  currentRaceIndex = 0
  343.  ColourNote("yellow", "", "Race Scan started...\n\n")
  344.  scanNextRace()
  345. end
  346.  
  347. function scanNextRace(name, line, args)
  348.  currentRaceIndex = currentRaceIndex + 1
  349.  if currentRaceIndex > #races then
  350.    ColourNote("yellow","","Race Scan complete.")
  351.    EnableTrigger("gagAll", false)
  352.    --tprint(races)
  353.  else
  354.    currentRace = races[currentRaceIndex]
  355.    DeleteLines(2)
  356.    ColourNote("silver","","Scan "..string.format("%2.2f",((currentRaceIndex/#races)*100)).."% completed.")
  357.    SendNoEcho("showrace "..currentRace.index)
  358.    EnableTriggerGroup("raceScanFirst", true)
  359.  end
  360.  scheduleRedraw()
  361. end
  362.  
  363. function sortByAlpha()
  364.  table.sort(races, function (k1, k2) return k1.name < k2.name end )
  365.  clearFilters()
  366.  updateSelectedRace()
  367. end
  368.  
  369. function sortByFilter(class, filter, stats)
  370.  table.sort(races, function (k1, k2) return getSubclassLevelsByClass(k1, class, filter, stats) > getSubclassLevelsByClass(k2, class, filter, stats) end )
  371.  updateSelectedRace()
  372. end
  373.  
  374. function clearFilters()
  375.  filter_main_class = ""
  376.  filter_classes = {}
  377.  filter_stats = {}
  378. end
  379.  
  380.  
  381. function updateSelectedRace()
  382.  if races[raceIndex] ~= nil then
  383.    raceSelected = raceIndex
  384.    updateRaceText()
  385.  end
  386.  forceRedraw()
  387. end
  388.  
  389. class_matrix = {  ["combat"] = 1,
  390.                        ["piloting"] = 2,
  391.                        ["engineering"] = 3,
  392.                        ["bounty hunting"] = 4,
  393.                        ["smuggling"] = 5,
  394.                        ["diplomacy"] = 6,
  395.                        ["leadership"] = 7,
  396.                        ["espionage"] = 8,
  397.                        ["slicer"] = 9,
  398.                        ["medical"] = 10,
  399.                        ["science"] = 11 }
  400.                        
  401. matrix_class = { "combat", "piloting", "engineering", "bounty hunting", "smuggling", "diplomacy", "leadership", "espionage", "slicer", "medical", "science" }
  402. matrix_stats = { "price", "deposit", "str", "dex", "con", "int", "wis", "cha", "frc", "lck", "ac", "hp", "apponly", "erarestrict" }
  403.  
  404. function getSubclassLevelsByClass(r, c, s, st)
  405.  local num = 0
  406.  if type(s)=="table" then
  407.    for i, v in ipairs(s) do
  408.      if c=="" then -- we didn't specify a class, take the average
  409.        for a=1, 11 do
  410.          num = num + r.levels[matrix_class[a]].levels[class_matrix[v]]
  411.        end
  412.        num = num / 11
  413.      else
  414.        num = num + r.levels[c].levels[class_matrix[v]]
  415.      end
  416.    end
  417.  end
  418.  if st~=nil then
  419.    if type(st)=="table" then
  420.      for i, v in ipairs(st) do
  421.        num = num + getRaceStat(r, v)
  422.      end
  423.    end
  424.  end
  425.  return num
  426. end
  427.  
  428. function getRaceStat(r, s)
  429.  if r[s] ~= nil then
  430.    if s=="price" or s=="deposit" then -- normalize price and deposit to be in line with stats
  431.      return -r[s]/1000
  432.    elseif s=="apponly" then -- convert apponly into a number
  433.      return ((r[s]=="Yes" and 10) or 0)
  434.    elseif s=="ac" then -- convert ac to positive and normalize
  435.      return -r[s]/25
  436.    elseif s=="hp" then -- normalize hp
  437.      return r[s]/250
  438.    else
  439.      return r[s]
  440.    end
  441.  end
  442. end
  443.  
  444. function addRaceScanFirst(name, line, args)
  445. -- "\(R\)ace\: (.*)\nStr Plus\: ([\s\d,-]+) Dex Plus\: ([\s\d,-]+) Wis Plus\: ([\s\d,-]+) Int Plus\: ([\s\d,-]+) \nCon Plus\: ([\s\d,-]+) Cha Plus\: ([\s\d,-]+) Lck Plus\: ([\s\d,-]+) \nHit Pts\: ([\s\d,-]+)AC Mod\: ([\s\d,-]+) Frc Plus\: ([\s\d,-]+) \nPrice\: ([\s\d,-]+)Deposit\: ([\s\d,-]+)App Only\: (.*)\n\(D\)efault Language\: (.*)\n\(P\)ossible Skincolors\:\Z"
  446.  if currentRace.name ~= args[1] then
  447.    ColourNote("red","","Mismatched race names detected ("..currentRace.name.."~="..args[1]..") aborting...")
  448.    stopRaceScan()
  449.    return
  450.  end
  451.  currentRace.str = tonumber(args[2])
  452.  currentRace.dex = tonumber(args[3])
  453.  currentRace.wis = tonumber(args[4])
  454.  currentRace.int = tonumber(args[5])
  455.  currentRace.con = tonumber(args[6])
  456.  currentRace.cha = tonumber(args[7])
  457.  currentRace.lck = tonumber(args[8])
  458.  currentRace.hp =  tonumber(args[9])
  459.  currentRace.ac =  tonumber(args[10])
  460.  currentRace.frc = tonumber(args[11])
  461.  currentRace.price = tonumber(args[12])
  462.  currentRace.deposit = tonumber(args[13])
  463.  currentRace.apponly = Trim(args[14])
  464.  --currentRace.language = Trim(args[15])
  465.  --races[currentRaceIndex] = currentRace
  466.  EnableTriggerGroup("raceScanFirst", false)
  467.  DeleteLines(1)
  468.  startRaceScanSecond()
  469. end
  470.  
  471. function addRaceMainClass(name, line, args)
  472.  currentRace.mainclass = args[1]
  473. end
  474.  
  475. function startRaceScanSecond(name, line, args)
  476.  EnableTriggerGroup("raceScanSecond", true)
  477. end
  478. function addRaceScanSecond(name, line, args)
  479.  currentRace.language = Trim(args[1])
  480.  EnableTriggerGroup("raceScanSecond", false)
  481.  startSkinColors()
  482. end
  483.  
  484. function startSkinColors(name, line, args)
  485.  skinColors = {}
  486.  EnableTriggerGroup("SkinColors", true)
  487. end
  488.  
  489. function addSkinColors(name, line, args)
  490.  local color = {}
  491.  for i, v in pairs(args) do
  492.    if math.fmod(i-1, 2)==0 then -- index
  493.      color.index = tonumber(v)
  494.      --Note("found race index: "..v)
  495.    elseif math.fmod(i-1, 2)==1 then -- name
  496.      color.name = Trim(v)
  497.      --Note("found era restrict: "..v)
  498.      skinColors[#skinColors + 1] = color
  499.      color = {}
  500.    end
  501.  end
  502. end
  503.  
  504. function stopSkinColors(name, line, args)
  505.  EnableTriggerGroup("SkinColors", false)
  506.  currentRace.skincolors = copytable.deep(skinColors)
  507.  startExtraAttribs()
  508. end
  509.  
  510. function startExtraAttribs(name, line, args)
  511.  extraAttribs = {}
  512.  EnableTriggerGroup("ExtraAttribs", true)
  513. end
  514.  
  515. function addExtraAttrib(name, line, args)
  516.  local attrib = { name = Trim(args[1]), desc = Trim(args[2]) }
  517.  extraAttribs[#extraAttribs + 1] = attrib
  518. end
  519.  
  520.  
  521. function stopExtraAttribs(name, line, args)
  522.  EnableTriggerGroup("ExtraAttribs", false)
  523.  currentRace.attribs = copytable.deep(extraAttribs)
  524.  startRaceLevels()
  525. end
  526.  
  527. function startRaceLevels(name, line, args)
  528.  raceLevels = {}
  529.  EnableTriggerGroup("RaceLevels", true)
  530. end
  531.  
  532. function addRaceLevels(name, line, args)
  533.  local levels = {}
  534.  --levels.class = Trim(args[1])
  535.  args[2] = string.gsub(Trim(args[2]), "   ", " ")
  536.  levels.levels = utils.split(Trim(args[2]), " ")
  537.  --raceLevels[#raceLevels + 1] = levels
  538.  raceLevels[Trim(args[1])] = levels
  539. end
  540.  
  541. function stopRaceLevels(name, line, args)
  542.  EnableTriggerGroup("RaceLevels", false)
  543.  currentRace.levels = copytable.deep(raceLevels)
  544.  races[currentRaceIndex] = currentRace
  545.  scanNextRace()
  546. end
  547.  
  548. function stopRaceScan(name, line, args)
  549.  EnableTriggerGroup("raceScanFirst", false)
  550.  EnableTriggerGroup("SkinColors", false)
  551.  EnableTriggerGroup("ExtraAttribs", false)
  552.  EnableTriggerGroup("RaceLevels", false)
  553.  EnableTrigger("gagAll", false)
  554. end
  555.  
  556. function getRaceByIndex(index)
  557.  for i, v in pairs(races) do
  558.    if i==index then
  559.      return v
  560.    end
  561.  end
  562.  ColourNote("red","","Error, no race with that index ("..index..")")
  563.  return
  564. end
  565.  
  566. function beginScan(name, line, args)
  567. end
  568. function clearTable(name, line, args)
  569.  races = {}
  570.  text = {}
  571.  config = default_config
  572.  ColourNote("yellow","","Race list tables cleared.")
  573.  OnPluginSaveState()
  574.  SetUpHotspotsAndDraw(true)
  575. end
  576.  
  577. function showWindow(name, line, args)
  578.  visible = "true"
  579.  scheduleRedraw()
  580. end
  581. function hideWindow(name, line, args)
  582.  visible = "false"
  583.  WindowShow(win, false)
  584. end
  585.  
  586. function setupWindow(name, line, args)
  587.  
  588.  
  589. end
  590.  
  591.  
  592. function drawWindow(name, line, args)
  593.     WindowRectOp (win, miniwin.rect_fill, 0, 0, config.width, config.height, ColourNameToRGB(config.backcolor))  -- draw blank rectangle to "erase" window contents
  594.  -- drag handler
  595.   movewindow.add_drag_handler (win, 0, 0, config.width-30, titleHeight)    
  596.  
  597.      -- draw border
  598.  WindowRectOp (win, miniwin.rect_draw_edge, 0, 0, 0, 0, miniwin.rect_edge_etched, miniwin.rect_edge_at_all)
  599.  WindowRectOp (win, miniwin.rect_frame, 1, titleHeight, config.split, config.height-1, ColourNameToRGB("white"))
  600.     WindowRectOp (win, miniwin.rect_frame, config.split+1, titleHeight, config.width-1, config.height-1, ColourNameToRGB("white"))
  601.  
  602.  printBrowseList()
  603.    
  604.  drawText()
  605.  
  606.  -- draw scrollbars
  607.  drawScrollbars()
  608.    
  609.    
  610.  -- draw X in the corner to close the window
  611.  --WindowRectOp(win, 5, config.width-15, 1, config.width, titleHeight, 5, 15+ 0x0800)
  612.  WindowLine (win, config.width-15, 5, config.width-5, 15, ColourNameToRGB ("white"), miniwin.pen_solid, 1)
  613.  WindowLine (win, config.width-15, 15, config.width-5, 5, ColourNameToRGB ("white"), miniwin.pen_solid, 1)
  614.  WindowAddHotspot(win, "windowX",
  615.        config.width-15, 5, config.width-5, 15,
  616.             "",                   --mousehover
  617.             "",                   --mouseoffhover
  618.             "destroyWindow",      --mousedown
  619.             "CancelMouseDown",                   --mouseoffdown
  620.             "LeftClickOnly",                   --mouseup
  621.             "Close race browser window",
  622.             1, 0)
  623.  -- heading line
  624.     WindowText (win, font, "LotJ Race Browser v"..VERSION, 3, 3, 0, 0, ColourNameToRGB  "white")
  625.  drawRefreshButton()
  626.  drawResizer(win, config.width, config.height)
  627.  WindowShow (win,  true)
  628.  --BroadcastPlugin(999, "repaint")
  629.  
  630.  
  631. end
  632.  
  633. function drawRefreshButton()
  634.  local display = ""
  635.  if races.scantime then
  636.    local daysold = tonumber(string.format("%1.0f", os.difftime(os.time(), tonumber(races.scantime))/86400))
  637.    display = "Race data is "..((daysold>0 and daysold.." day"..((daysold>1 and "s")or "").." old") or "current")
  638.  else
  639.    display = "No race data"
  640.  end
  641.  WindowText(win, font, display, config.width-WindowTextWidth(win, font, display)-40, 3, 0, 0, ColourNameToRGB("white"))
  642.  
  643.  WindowAddHotspot(win, "refreshbutton", config.width-30, 1, config.width-15, titleHeight, "", "", "startRacelistScan", "", "", "Update race data", 1, 0)
  644.  points = string.format("%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i", config.width-23, titleHeight-12, config.width-19, titleHeight-8, config.width-21,titleHeight-8,config.width-21, titleHeight-3,config.width-25, titleHeight-3,config.width-25,titleHeight-8,config.width-27, titleHeight-8)
  645.  WindowPolygon(win, points, ColourNameToRGB("white"), 0, 1, ColourNameToRGB("white"), 0, true, false)
  646.  
  647.  
  648. end
  649.  
  650. function drawScrollbars(name, line, args)
  651.  
  652.   -- left Scrollbar base
  653.   WindowRectOp(win, 2, config.split-2-SCROLL_BAR_WIDTH, titleHeight, config.split-2, config.height-2, SCROLL_BACKGROUND_COLOUR) -- scroll bar background
  654.   WindowRectOp(win, 1, config.split-2-SCROLL_BAR_WIDTH+1, SCROLL_BAR_WIDTH+titleHeight+1, config.split-2-1, config.height-SCROLL_BAR_WIDTH-1, SCROLL_DETAIL_COLOUR) -- scroll bar background inset rectangle
  655.  
  656.   -- right Scrollbar base
  657.   WindowRectOp(win, 2, config.width-SCROLL_BAR_WIDTH, titleHeight, config.width, -SCROLL_BAR_WIDTH, SCROLL_BACKGROUND_COLOUR) -- scroll bar background
  658.   WindowRectOp(win, 1, config.width-SCROLL_BAR_WIDTH+1, SCROLL_BAR_WIDTH+titleHeight+1, config.width-1, config.height-(2*SCROLL_BAR_WIDTH)-1, SCROLL_DETAIL_COLOUR) -- scroll bar background inset rectangle
  659.  
  660.  
  661.   -- draw right scrollbar up and down arrows
  662.  
  663.   if (keepscrolling == "rightup") then
  664.      -- draw top scroll button pressed
  665.      WindowRectOp(win, 5, (config.width-SCROLL_BAR_WIDTH), titleHeight, 0, titleHeight+SCROLL_BAR_WIDTH, 10,  15 + 0x800) -- up arrow pushed
  666.      points = string.format("%i,%i,%i,%i,%i,%i", (config.width-SCROLL_BAR_WIDTH)+3, titleHeight+9,(config.width-SCROLL_BAR_WIDTH)+7, titleHeight+5,(config.width-SCROLL_BAR_WIDTH)+11, titleHeight+9)
  667.      WindowPolygon(win, points,
  668.         0x000000, 0, 1, -- pen (solid, width 1)
  669.         0x000000, 0, -- brush (solid)
  670.         true, -- close
  671.         false) -- alt fill
  672.   else
  673.      -- draw top scroll button unpressed
  674.      WindowRectOp(win, 5, (config.width-SCROLL_BAR_WIDTH), titleHeight, config.width, titleHeight+SCROLL_BAR_WIDTH, 5, 15 + 0x800)
  675.      points = string.format("%i,%i,%i,%i,%i,%i", (config.width-SCROLL_BAR_WIDTH)+3, titleHeight+9,(config.width-SCROLL_BAR_WIDTH)+7, titleHeight+5,(config.width-SCROLL_BAR_WIDTH)+11, titleHeight+9)
  676.      WindowPolygon(win, points,
  677.         0x000000, 0, 1,   -- pen (solid, width 1)
  678.         0x000000, 0, --brush (solid)
  679.         true, --close
  680.         false)  --alt fill
  681.   end
  682.    
  683.   if (keepscrolling == "rightdown") then
  684.      -- draw bottom scroll button pressed
  685.      WindowRectOp(win, 5, (config.width-SCROLL_BAR_WIDTH), config.height-(SCROLL_BAR_WIDTH*2), 0, config.height-SCROLL_BAR_WIDTH-1, 10,  15 + 0x800)
  686.      points = string.format("%i,%i,%i,%i,%i,%i", (config.width-SCROLL_BAR_WIDTH)+3, (config.height-SCROLL_BAR_WIDTH)-11,(config.width-SCROLL_BAR_WIDTH)+7, (config.height-SCROLL_BAR_WIDTH)-7, (config.width-SCROLL_BAR_WIDTH)+11,(config.height-SCROLL_BAR_WIDTH)-11)
  687.      WindowPolygon(win, points,
  688.         0x000000, 0, 1, -- pen (solid, width 1)
  689.         0x000000, 0, -- brush (solid)
  690.         true, -- close
  691.         false) -- alt fill
  692.   else
  693.      -- draw bottom scroll button unpressed
  694.      WindowRectOp(win, 5, (config.width-SCROLL_BAR_WIDTH), config.height-(SCROLL_BAR_WIDTH*2), config.width, config.height-SCROLL_BAR_WIDTH, 5,  15 + 0x800)
  695.      points = string.format("%i,%i,%i,%i,%i,%i", (config.width-SCROLL_BAR_WIDTH)+3, (config.height-SCROLL_BAR_WIDTH)-11,(config.width-SCROLL_BAR_WIDTH)+7, (config.height-SCROLL_BAR_WIDTH)-7, (config.width-SCROLL_BAR_WIDTH)+11,(config.height-SCROLL_BAR_WIDTH)-11)
  696.      WindowPolygon(win, points,
  697.         0x000000, 0, 1,   -- pen (solid, width 1)
  698.         0x000000, 0, --brush (solid)
  699.         true, --close
  700.         false) --alt fill
  701.   end
  702.  
  703.      -- draw left scrollbar up and down arrows
  704.  
  705.   if (keepscrolling == "leftup") then
  706.      -- draw top scroll button pressed
  707.      WindowRectOp(win, 5, (config.split-SCROLL_BAR_WIDTH-2), titleHeight, config.split-2, titleHeight+SCROLL_BAR_WIDTH, 10,  15 + 0x800) -- up arrow pushed
  708.      points = string.format("%i,%i,%i,%i,%i,%i", (config.split-SCROLL_BAR_WIDTH-2)+3, titleHeight+9,(config.split-SCROLL_BAR_WIDTH-2)+7, titleHeight+5,(config.split-SCROLL_BAR_WIDTH-2)+11, titleHeight+9)
  709.      WindowPolygon(win, points,
  710.         0x000000, 0, 1, -- pen (solid, width 1)
  711.         0x000000, 0, -- brush (solid)
  712.         true, -- close
  713.         false) -- alt fill
  714.   else
  715.      -- draw top scroll button unpressed
  716.      WindowRectOp(win, 5, (config.split-SCROLL_BAR_WIDTH-2), titleHeight, config.split-2, titleHeight+SCROLL_BAR_WIDTH, 5, 15 + 0x800)
  717.      points = string.format("%i,%i,%i,%i,%i,%i", (config.split-SCROLL_BAR_WIDTH-2)+3, titleHeight+9,(config.split-SCROLL_BAR_WIDTH-2)+7, titleHeight+5,(config.split-SCROLL_BAR_WIDTH-2)+11, titleHeight+9)
  718.      WindowPolygon(win, points,
  719.         0x000000, 0, 1,   -- pen (solid, width 1)
  720.         0x000000, 0, --brush (solid)
  721.         true, --close
  722.         false)  --alt fill
  723.   end
  724.    
  725.   if (keepscrolling == "leftdown") then
  726.      -- draw bottom scroll button pressed
  727.      WindowRectOp(win, 5, (config.split-SCROLL_BAR_WIDTH-2), config.height-SCROLL_BAR_WIDTH, config.split-2, config.height-1, 10,  15 + 0x800)
  728.      points = string.format("%i,%i,%i,%i,%i,%i", (config.split-SCROLL_BAR_WIDTH-2)+3, config.height-11,(config.split-SCROLL_BAR_WIDTH-2)+7, config.height-7, (config.split-SCROLL_BAR_WIDTH-2)+11,config.height-11)
  729.      WindowPolygon(win, points,
  730.         0x000000, 0, 1, -- pen (solid, width 1)
  731.         0x000000, 0, -- brush (solid)
  732.         true, -- close
  733.         false) -- alt fill
  734.   else
  735.      -- draw bottom scroll button unpressed
  736.      WindowRectOp(win, 5, (config.split-SCROLL_BAR_WIDTH-2), config.height-SCROLL_BAR_WIDTH, config.split-2, config.height, 5,  15 + 0x800)
  737.      points = string.format("%i,%i,%i,%i,%i,%i", (config.split-SCROLL_BAR_WIDTH-2)+3, config.height-11,(config.split-SCROLL_BAR_WIDTH-2)+7, config.height-7, (config.split-SCROLL_BAR_WIDTH-2)+11,config.height-11)
  738.      WindowPolygon(win, points,
  739.         0x000000, 0, 1,   -- pen (solid, width 1)
  740.         0x000000, 0, --brush (solid)
  741.         true, --close
  742.         false) --alt fill
  743.   end
  744.  
  745.  
  746.    -- determine left scrollbar position indicator
  747.  
  748.    totalSteps = #races
  749.    if (totalSteps <= racesFit-1) then
  750.       totalSteps = 1
  751.    end
  752.    SCROLL_BAR_HEIGHT = (config.height-(2*SCROLL_BAR_WIDTH)-titleHeight)
  753.    if (not dragscrolling) then
  754.      stepNum = raceDisplayedStart-1
  755.      barPos = SCROLL_BAR_WIDTH + titleHeight + ((SCROLL_BAR_HEIGHT/totalSteps) * stepNum)
  756.      barSize = (SCROLL_BAR_HEIGHT/math.max(racesFit-1,totalSteps)) * (racesFit-1)
  757.      if barSize < 10 then
  758.        barSize = 10
  759.      end
  760.      if barPos+barSize > SCROLL_BAR_WIDTH+titleHeight+SCROLL_BAR_HEIGHT then
  761.        barPos = SCROLL_BAR_WIDTH+titleHeight+SCROLL_BAR_HEIGHT - barSize
  762.      end
  763.      WindowAddHotspot(win, "leftscroller", (config.split-SCROLL_BAR_WIDTH-2), barPos, config.split-2, barPos+barSize, "MouseOver", "CancelMouseOver", "MouseDown", "CancelMouseDown", "MouseUp", "", 1, 0)
  764.      WindowDragHandler(win, "leftscroller", "ScrollerMoveCallback", "ScrollerReleaseCallback", 0)
  765.    
  766.    end
  767.    WindowRectOp(win, 5, (config.split-SCROLL_BAR_WIDTH-2), barPos, config.split-2, barPos+barSize, 5, 15 + 0x800) -- scrollbar position indicator
  768.    
  769.    
  770.   -- determine right scrollbar position indicator
  771.   totalSteps2 = #text
  772.   if (totalSteps2 <= textFit-1) then
  773.      totalSteps2 = 1
  774.   end
  775.   SCROLL_BAR_HEIGHT2 = (config.height-(3*SCROLL_BAR_WIDTH)-titleHeight)
  776.   if (not dragscrolling) then
  777.      stepNum2 = textStart-1
  778.      barPos2 = SCROLL_BAR_WIDTH +titleHeight+ ((SCROLL_BAR_HEIGHT2/totalSteps2) * stepNum2)
  779.      barSize2 = (SCROLL_BAR_HEIGHT2/math.max(textFit-1,totalSteps2)) * (textFit-1)
  780.      if barSize2 < 10 then
  781.         barSize2 = 10
  782.      end
  783.      if barPos2+barSize2 > SCROLL_BAR_WIDTH+titleHeight+SCROLL_BAR_HEIGHT2 then
  784.         barPos2 = SCROLL_BAR_WIDTH+titleHeight+SCROLL_BAR_HEIGHT2 - barSize2
  785.      end
  786.      WindowAddHotspot(win, "rightscroller", (config.width-SCROLL_BAR_WIDTH), barPos2, config.width, barPos2+barSize2, "MouseOver", "CancelMouseOver", "MouseDown", "CancelMouseDown", "MouseUp", "", 1, 0)
  787.      WindowDragHandler(win, "rightscroller", "ScrollerMoveCallback", "ScrollerReleaseCallback", 0)
  788.   end
  789.   WindowRectOp(win, 5, (config.width-SCROLL_BAR_WIDTH), barPos2, config.width, barPos2+barSize2, 5, 15 + 0x800) -- scrollbar position indicator
  790.    
  791. end
  792.  
  793. function destroyWindow(name, list, args)
  794.     WindowShow (win, false)
  795.     visible = "false"
  796. end
  797.  
  798. function scheduleRedraw()
  799.     if redraw_scheduled == false then
  800.         redraw_scheduled = true
  801.         DoAfterSpecial(0.1, 'drawWindows()', sendto.script)
  802.     end
  803. end
  804.  
  805. function forceRedraw()
  806.  if redraw_scheduled == false then
  807.    redraw_scheduled = true
  808.    drawWindows()
  809.  end
  810. end
  811.  
  812. function wheel_move (flags, hotspot_id)
  813.  if hotspot_id == "leftbackground" then
  814.    if bit.band(flags, 0x100) ~= 0 then
  815.      if raceDisplayedStart < #races-racesFit+2 then
  816.        -- down
  817.        raceDisplayedStart = math.max(1, math.min(#races-racesFit+2, raceDisplayedStart+3))
  818.        raceDisplayedEnd = math.min(#races, raceDisplayedStart+racesFit-2)    
  819.        forceRedraw()
  820.      end
  821.    elseif raceDisplayedStart > 1 then
  822.      -- up
  823.      raceDisplayedStart = math.max(1, raceDisplayedStart-3)
  824.      raceDisplayedEnd = math.min(#races, raceDisplayedStart+racesFit-2)
  825.      forceRedraw()
  826.    end
  827.  elseif hotspot_id == "rightbackground" then
  828.    if bit.band(flags, 0x100) ~= 0 then
  829.      if textStart < #text-textFit+2 then
  830.        -- down
  831.        textStart = math.max(1, math.min(#text-textFit+2, textStart+3))
  832.        textEnd = math.min(#text, textStart+textFit-2)    
  833.        forceRedraw()
  834.      end
  835.    elseif textStart > 1 then
  836.      -- up
  837.      textStart = math.max(1, textStart-3)
  838.      textEnd = math.min(#text, textStart+textFit-2)
  839.      forceRedraw()
  840.    end
  841.  
  842.  end
  843. end -- wheel_move
  844.  
  845.  
  846. function ScrollerMoveCallback(flags, hotspot_id)
  847.  mouseposy = WindowInfo(win, 18)
  848.  windowtop = WindowInfo(win, 2)
  849.  if hotspot_id == "leftscroller" then
  850.    barPos = math.max(mouseposy-windowtop+clickdelta, SCROLL_BAR_WIDTH+titleHeight)
  851.    if barPos > config.height-(SCROLL_BAR_WIDTH)-barSize then
  852.      barPos = config.height-(SCROLL_BAR_WIDTH)-barSize
  853.      raceDisplayedStart = math.max(1,#races-racesFit+2)
  854.      raceDisplayedEnd = #races
  855.    else
  856.      raceDisplayedStart = math.max(1,math.floor((barPos-SCROLL_BAR_WIDTH-titleHeight)/(SCROLL_BAR_HEIGHT/totalSteps)+1))
  857.      raceDisplayedEnd = math.min(raceDisplayedStart + racesFit-2, #races)
  858.    end
  859.  elseif hotspot_id == "rightscroller" then
  860.    barPos2 = math.max(mouseposy-windowtop+clickdelta, SCROLL_BAR_WIDTH+titleHeight)
  861.    if barPos2 > config.height-(SCROLL_BAR_WIDTH*2)-barSize2 then
  862.      barPos2 = config.height-(SCROLL_BAR_WIDTH*2)-barSize2
  863.      textStart = math.max(1,#text-textFit+2)
  864.      textEnd = #text
  865.    else
  866.      textStart = math.max(1,math.floor((barPos2-SCROLL_BAR_WIDTH-titleHeight)/(SCROLL_BAR_HEIGHT/totalSteps2)+1))
  867.      textEnd = math.min(#text, textStart+textFit-2)
  868.    end
  869.  end
  870.  scheduleRedraw()
  871. end
  872.  
  873. function ScrollerReleaseCallback(flags, hotspot_id)
  874.   dragscrolling = false
  875.   scheduleRedraw()
  876. end
  877.  
  878. ----------------------------------------------------------------------
  879. -- Called as resizer is dragged.
  880. ----------------------------------------------------------------------
  881. function ResizeMoveCallback(flags, hotspot_id)
  882.   posx, posy = WindowInfo (win, 17), WindowInfo (win, 18)
  883.   config.width = config.width + posx - startposx
  884.   startposx = posx
  885.   if (config.width < MIN_WIDTH) then
  886.      config.width = MIN_WIDTH
  887.      startposx = windowinfo.window_left+config.width
  888.   elseif (windowinfo.window_left+config.width > GetInfo(281)) then
  889.      config.width = GetInfo(281)-windowinfo.window_left
  890.      startposx = GetInfo(281)
  891.   end
  892.  
  893.   config.height = config.height + posy - startposy
  894.   startposy = posy
  895.   if (config.height < MIN_HEIGHT) then
  896.     config.height = MIN_HEIGHT
  897.     startposy = windowinfo.window_top+config.height
  898.   elseif (windowinfo.window_top+config.height > GetInfo(280)) then
  899.     config.height = GetInfo(280)-windowinfo.window_top
  900.     startposy = GetInfo(280)
  901.   end
  902.  
  903.  
  904.     if (utils.timer() - lastRefresh > 0.0333) then
  905.         SetUpHotspotsAndDraw(false)
  906.         lastRefresh = utils.timer()
  907.     end
  908. end
  909. ---------------------------------------------------------------------------------
  910. -- Called after the resize widget is released.
  911. ---------------------------------------------------------------------------------
  912. function ResizeReleaseCallback ()
  913.  config.height = titleHeight+(raceLineHeight*(racesFit-1))+3 -- snap height down to not have dead space after last line
  914.  SetUpHotspotsAndDraw(false) -- true here causes old lines to re-wrap at the new size
  915. end
  916. ---------------------------------------------------------------------------------
  917. -- Called as window split is being dragged.
  918. ---------------------------------------------------------------------------------
  919. function SplitMoveCallback(flags, hotspot_id)
  920.  posx = WindowInfo(win, 17)
  921.  config.split = config.split + posx - startposx
  922.  startposx = posx
  923.  if (config.split < MIN_SPLIT) then
  924.    config.split = MIN_SPLIT
  925.    startposx = windowinfo.window_left+config.split
  926.  elseif (windowinfo.window_left+config.split > GetInfo(281)) then -- prevent moving split off right edge of screen
  927.    config.split = GetInfo(281)-windowinfo.window_left
  928.    startposx = GetInfo(281)
  929.  end
  930.  
  931.  if (utils.timer() - lastRefresh > 0.0333) then
  932.         SetUpHotspotsAndDraw(false)
  933.         lastRefresh = utils.timer()
  934.     end
  935. end
  936. ---------------------------------------------------------------------------------
  937. -- Called after window split is released.
  938. ---------------------------------------------------------------------------------
  939. function SplitReleaseCallback()
  940.  SetUpHotspotsAndDraw(false)
  941. end
  942. ---------------------------------------------------------------------------------
  943. -- Called when mouse button is pressed on hotspot.
  944. ---------------------------------------------------------------------------------
  945. function MouseDown(flags, hotspot_id)
  946.  if (hotspot_id == "resize" or hotspot_id == "splitmove") then
  947.    startposx, startposy = WindowInfo (win, 17), WindowInfo (win, 18)
  948.  elseif (hotspot_id == "leftscroller") then
  949.    clickdelta = WindowHotspotInfo(win, "leftscroller", 2)-WindowInfo (win, 15)
  950.    dragscrolling = true
  951.  elseif (hotspot_id == "rightscroller") then
  952.    clickdelta = WindowHotspotInfo(win, "rightscroller", 2)-WindowInfo (win, 15)
  953.    dragscrolling = true
  954.  elseif (hotspot_id == "leftup" or hotspot_id == "leftdown") then
  955.    keepscrolling = hotspot_id
  956.    scrollbar()
  957.  elseif (hotspot_id == "rightup" or hotspot_id == "rightdown") then
  958.    keepscrolling = hotspot_id
  959.    scrollbar2()
  960.  elseif (hotspot_id == "leftbackground") then
  961.    raceClick()
  962.  end
  963. end
  964. ---------------------------------------------------------------------------------
  965. -- Called when mouse moved away from hotspot. Doesn't really apply for draggables.
  966. ---------------------------------------------------------------------------------
  967. function CancelMouseDown(flags, hotspot_id)
  968.  keepscrolling = ""
  969.  scheduleRedraw()
  970. end
  971. ---------------------------------------------------------------------------------
  972. -- Called when mouse button released on hotspot.
  973. ---------------------------------------------------------------------------------
  974. function MouseUp(flags, hotspot_id, win)
  975.   if bit.band (flags, miniwin.hotspot_got_rh_mouse) ~= 0 then
  976.      right_click_menu()
  977.   end
  978.   keepscrolling = ""
  979.   return true
  980. end
  981. function LeftClickOnly(flags, hotspot_id, win)
  982.     if bit.band (flags, miniwin.hotspot_got_rh_mouse) ~= 0 then
  983.    return true
  984.     end
  985.     return false
  986. end
  987.  
  988. function right_click_menu(hotspot_id)
  989.  
  990.     menu ="!"
  991.  menu = menu .."^Race Sorting|>Apply main class filter|"
  992.  
  993.  for i, v in ipairs(matrix_class) do
  994.    menu = menu..((filter_main_class==v and "+") or "")..v.."|"
  995.  end
  996.  menu = menu.."<|>Apply level filters|"
  997.  for i, v in ipairs(matrix_class) do
  998.    local found = false
  999.    for k, j in pairs(filter_classes) do
  1000.      if j==v then -- class belongs to sorting filter
  1001.        found = true
  1002.      end
  1003.    end
  1004.    menu = menu..((found and "+") or "")..v.."|"
  1005.  end
  1006.  menu = menu.."<|>Apply stat filters|"
  1007.  for i, v in ipairs(matrix_stats) do
  1008.    local found = false
  1009.      for k, j in pairs(filter_stats) do
  1010.        if j==v then -- stat belongs to sorting filter
  1011.          found = true
  1012.        end
  1013.      end
  1014.    menu = menu..((found and "+") or "")..v.."|"
  1015.  end
  1016.  menu = menu .. "<|Sort alphabetically|Clear filters"
  1017.  
  1018.  result = tonumber(WindowMenu (win,
  1019.         WindowInfo (win, 14),  -- x position
  1020.         WindowInfo (win, 15),   -- y position
  1021.         menu))
  1022.    
  1023.    
  1024.  if result~=nil then
  1025.    if result > 0 and result <= #matrix_class then -- chose a main class
  1026.      if filter_main_class==matrix_class[result] then -- remove main class choice
  1027.        filter_main_class = ""
  1028.      else
  1029.        filter_main_class = matrix_class[result]
  1030.      end
  1031.    elseif result > #matrix_class and result <= #matrix_class*2 then -- chose a level filter
  1032.      local choice = matrix_class[result-#matrix_class]
  1033.      local found = 0
  1034.      for k, v in pairs(filter_classes) do
  1035.        if v==choice then -- choice already in filter, remove it
  1036.          found = k
  1037.        end
  1038.      end
  1039.      if found>0 then
  1040.        table.remove(filter_classes, found)
  1041.      else
  1042.        filter_classes[#filter_classes + 1] = choice
  1043.      end
  1044.    elseif result > #matrix_class*2 and result <= #matrix_class*2+#matrix_stats then -- chose a stat filter
  1045.      local choice = matrix_stats[result-#matrix_class*2]
  1046.      local found = 0
  1047.      for k, v in pairs(filter_stats) do
  1048.        if v==choice then -- choice already in filter, remove it
  1049.          found = k
  1050.        end
  1051.      end
  1052.      if found>0 then
  1053.        table.remove(filter_stats, found)
  1054.      else
  1055.        filter_stats[#filter_stats + 1] = choice
  1056.      end
  1057.    elseif result == #matrix_class*2+#matrix_stats+1 then -- chose alpha sort
  1058.      sortByAlpha()
  1059.      return
  1060.    elseif result == #matrix_class*2+#matrix_stats+2 then -- chose clear filters
  1061.      clearFilters()
  1062.      return
  1063.    end
  1064.    sortByFilter(filter_main_class, filter_classes, filter_stats)
  1065.  end
  1066.  
  1067. end
  1068.  
  1069. keepscrolling = ""
  1070. require "wait"
  1071.  
  1072. function scrollbar()
  1073.   wait.make(
  1074.   function()
  1075.      while keepscrolling == "leftup" or keepscrolling == "leftdown" do
  1076.         if keepscrolling == "leftup" then
  1077.            if (raceDisplayedStart > 1) then
  1078.               raceDisplayedStart = raceDisplayedStart - 1
  1079.               raceDisplayedEnd = raceDisplayedEnd - 1
  1080.            else
  1081.                 keepscrolling = ""
  1082.            end
  1083.         elseif keepscrolling == "leftdown" then
  1084.            if (raceDisplayedEnd < #races) then
  1085.               raceDisplayedStart = raceDisplayedStart + 1
  1086.               raceDisplayedEnd = raceDisplayedEnd + 1
  1087.            else
  1088.               keepscrolling = ""
  1089.            end
  1090.         end
  1091.         wait.time(0.1)
  1092.         forceRedraw()
  1093.      end
  1094.   end
  1095.   )
  1096. end
  1097.  
  1098. function scrollbar2()
  1099.   wait.make(
  1100.   function()
  1101.      while keepscrolling == "rightup" or keepscrolling == "rightdown" do
  1102.         if keepscrolling == "rightup" then
  1103.            if (textStart > 1) then
  1104.               textStart = textStart - 1
  1105.               textEnd = textEnd - 1
  1106.            else
  1107.                 keepscrolling = ""
  1108.            end
  1109.         elseif keepscrolling == "rightdown" then
  1110.            if (textEnd < #text) then
  1111.               textStart = textStart + 1
  1112.               textEnd = textEnd + 1
  1113.            else
  1114.               keepscrolling = ""
  1115.            end
  1116.         end
  1117.         wait.time(0.1)
  1118.         forceRedraw()
  1119.      end
  1120.   end
  1121.   )
  1122. end
  1123.  
  1124. function OnPluginInstall ()    
  1125.  -- get default config
  1126.  if not config then
  1127.    config = default_config
  1128.  end
  1129.  
  1130.  --- Setup the windows
  1131.  SetUpHotspotsAndDraw(true)  
  1132.    
  1133. end -- OnPluginInstall
  1134. --================================================================================
  1135. -- Called by OnPluginInstall, but also by redraw routine to refresh the screen
  1136. -- and (if the first time) add the resizer tag, otherwise move the resizer relative
  1137. -- to the main window.
  1138. --=================================================================================
  1139. function SetUpHotspotsAndDraw(firstTime)
  1140.     if (firstTime) then
  1141.    
  1142.         WindowCreate (win, 0, 0, config.width, config.height, miniwin.pos_center_all, 0, ColourNameToRGB("black")) -- create window
  1143.         windowinfo = movewindow.install (win, 6) -- default to 6 (on top right)
  1144.         check(WindowFont (win, font, font_name, font_size, false, false, false, false))
  1145.    -- spacing stuff
  1146.    titleHeight = WindowFontInfo(win, font, 1)+4
  1147.    raceLineHeight = WindowFontInfo(win, font, 1)+spacer
  1148.    textLineHeight = WindowFontInfo(win, font, 1)+1
  1149.    
  1150.    --effectiveWidth = math.min(config.width, GetInfo(281)-windowinfo.window_left)
  1151.         WindowAddHotspot (win, "resize", config.width-RESIZE_TAG_SIZE, config.height-RESIZE_TAG_SIZE, config.width, config.height, "MouseOver", "CancelMouseOver", "MouseDown", "CancelMouseDown", "MouseUp", "", 6, 0)
  1152.         WindowDragHandler(win, "resize", "ResizeMoveCallback", "ResizeReleaseCallback", 0)
  1153.    WindowAddHotspot (win, "splitmove", config.split-1, titleHeight, config.split+1, config.height-1, "MouseOver", "CancelMouseOver", "MouseDown", "CancelMouseDown", "MouseUp", "", 8, 0)
  1154.    WindowDragHandler(win, "splitmove", "SplitMoveCallback", "SplitReleaseCallback", 0)
  1155.    -- make background hotspots for scrolling
  1156.    WindowAddHotspot (win, "leftbackground", 2, titleHeight, config.split-SCROLL_BAR_WIDTH-2, config.height-2, "MouseOver", "CancelMouseOver", "MouseDown", "CancelMouseDown", "MouseUp", "",0, 0)
  1157.    WindowScrollwheelHandler(win, "leftbackground", "wheel_move")
  1158.    -- left scroll bar up/down buttons
  1159.    WindowAddHotspot(win, "leftup", config.split-1-SCROLL_BAR_WIDTH, titleHeight, config.split-1, titleHeight+SCROLL_BAR_WIDTH, "MouseOver", "CancelMouseOver", "MouseDown", "CancelMouseDown", "MouseUp", "", 1, 0)
  1160.    WindowAddHotspot(win, "leftdown", config.split-1-SCROLL_BAR_WIDTH, config.height-SCROLL_BAR_WIDTH, config.split-1, config.height, "MouseOver", "CancelMouseOver", "MouseDown", "CancelMouseDown", "MouseUp", "", 1, 0)
  1161.  
  1162.    WindowAddHotspot (win, "rightbackground", config.split+2, titleHeight, config.width-SCROLL_BAR_WIDTH-2, config.height-2, "MouseOver", "CancelMouseOver", "MouseDown", "CancelMouseDown", "MouseUp", "",0, 0)    
  1163.    WindowScrollwheelHandler(win, "rightbackground", "wheel_move")
  1164.    -- right scroll bar up/down buttons
  1165.    WindowAddHotspot(win, "rightup", config.width-SCROLL_BAR_WIDTH, titleHeight, config.width-2, titleHeight+SCROLL_BAR_WIDTH, "MouseOver", "CancelMouseOver", "MouseDown", "CancelMouseDown", "MouseUp", "", 1, 0)
  1166.    WindowAddHotspot(win, "rightdown", config.width-SCROLL_BAR_WIDTH, config.height-(2*SCROLL_BAR_WIDTH), config.width-2, config.height-SCROLL_BAR_WIDTH, "MouseOver", "CancelMouseOver", "MouseDown", "CancelMouseDown", "MouseUp", "", 1, 0)
  1167.  
  1168.     else -- not our first time drawing
  1169.         -- everything has already been made
  1170.         -- just move them back into place
  1171.         --effectiveWidth = math.min(config.width, GetInfo(281)-windowinfo.window_left)
  1172.         WindowResize(win, config.width, config.height, 0x000000)
  1173.         WindowMoveHotspot(win, "resize", config.width-RESIZE_TAG_SIZE, config.height-RESIZE_TAG_SIZE, config.width, config.height)
  1174.    WindowMoveHotspot(win, "splitmove", config.split-1, WindowFontInfo(win, font, 1)+4, config.split+1, config.height-1)
  1175.    
  1176.    WindowMoveHotspot(win, "leftbackground", 2, WindowFontInfo(win, font, 1)+4, config.split-SCROLL_BAR_WIDTH-2, config.height-2)
  1177.    WindowMoveHotspot(win, "rightbackground", config.split+2, titleHeight, config.width-SCROLL_BAR_WIDTH-2, config.height-2)
  1178.    WindowMoveHotspot(win, "leftup",config.split-1-SCROLL_BAR_WIDTH, titleHeight, config.split-1, titleHeight+SCROLL_BAR_WIDTH)
  1179.    WindowMoveHotspot(win, "leftdown",config.split-1-SCROLL_BAR_WIDTH, config.height-SCROLL_BAR_WIDTH, config.split-1, config.height)
  1180.    WindowMoveHotspot(win, "rightup",config.width-SCROLL_BAR_WIDTH, titleHeight, config.width-2, titleHeight+SCROLL_BAR_WIDTH)
  1181.    WindowMoveHotspot(win, "rightdown",config.width-SCROLL_BAR_WIDTH, config.height-(2*SCROLL_BAR_WIDTH), config.width-2, config.height-SCROLL_BAR_WIDTH)
  1182.     end
  1183.  
  1184.  -- left window
  1185.  racesFit = math.ceil((config.height-titleHeight)/raceLineHeight)
  1186.  
  1187.  raceDisplayedStart = 1
  1188.  raceDisplayedEnd = math.min(racesFit, #races)
  1189.  -- right window
  1190.  textFit = math.ceil((config.height-titleHeight)/textLineHeight)
  1191.  
  1192.  textStart = 1
  1193.  textEnd = math.min(#text, textFit)
  1194.    
  1195.  redraw_scheduled = true
  1196.  drawWindows()
  1197. end
  1198.  
  1199.  
  1200. function drawWindows()
  1201.     if redraw_scheduled == false then
  1202.         return
  1203.     else
  1204.         redraw_scheduled = false
  1205.     end
  1206.  if visible == "true" then
  1207.    drawWindow()
  1208.  end
  1209. end
  1210. function drawResizer(window, winwidth, winheight)
  1211.   -- draw the resize widget bottom right corner.
  1212.   WindowRectOp(win, 2, winwidth-SCROLL_BAR_WIDTH, winheight-SCROLL_BAR_WIDTH, 0, 0, SCROLL_BACKGROUND_COLOUR) -- resizer background
  1213.   WindowLine(window, winwidth-3, winheight-2, winwidth-2, winheight-3, 0xffffff, 0, 2)
  1214.   WindowLine(window, winwidth-4, winheight-2, winwidth-2, winheight-4, 0x696969, 0, 1)
  1215.   WindowLine(window, winwidth-6, winheight-2, winwidth-2, winheight-6, 0xffffff, 0, 2)
  1216.   WindowLine(window, winwidth-7, winheight-2, winwidth-2, winheight-7, 0x696969, 0, 1)
  1217.   WindowLine(window, winwidth-9, winheight-2, winwidth-2, winheight-9, 0xffffff, 0, 2)
  1218.   WindowLine(window, winwidth-10, winheight-2, winwidth-2, winheight-10, 0x696969, 0, 1)
  1219.   WindowLine(window, winwidth-12, winheight-2, winwidth-2, winheight-12, 0xffffff, 0, 2)
  1220.   WindowLine(window, winwidth-13, winheight-2, winwidth-2, winheight-13, 0x696969, 0, 1)
  1221. end
  1222.  
  1223. function OnPluginSaveState ()
  1224.  movewindow.save_state (win)
  1225.  SetVariable("config", serialize.save("config"))
  1226.  SetVariable("races", serialize.save("races"))
  1227.  SetVariable("visible", visible)
  1228. end -- function OnPluginSaveState
  1229.  
  1230. function OnPluginDisable()
  1231.  WindowShow(win, false)
  1232. end
  1233.  
  1234.  ]]>
  1235.   </script>
  1236.   </muclient>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement