Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Plugins ➜ Miniwindow plugin - quest tracker for Aardwolf

Miniwindow plugin - quest tracker for Aardwolf

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Sun 27 Jul 2008 12:23 AM (UTC)

Amended on Mon 28 Jul 2008 01:04 AM (UTC) by Nick Gammon

Message
The plugin below illustrates using the new miniwindows concept in a plugin.

Miniwindows were released in version 4.34, see here for a copy:

http://www.gammon.com.au/forum/?id=8811

The first thing it does (in OnPluginInstall) is to create the miniwindow, in order to find the font characteristics of the specified font.

Later, when triggered by the line "You ask * for a quest." it starts capturing quest instructions into the table quest_info. Finally, when a line appears that is not part of the quest instructions, it knows it can wrap up, recreates the miniwindow of the appropriate width and height, and shows the quest.

It uses the quest time line, which is something like "Questor tells you 'You have 42 minutes to complete your quest.'" - to calculate when the quest expires, and stores that in when_required. This is used to update the time to go each 30 seconds.

This plugin illustrates the general idea for writing a miniwindow plugin.

To use, copy between the lines, and save as Aardwolf_Quest_Noter.xml in your Plugins directory, and then use File -> Plugins to install it.


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Tuesday, July 15, 2008, 9:13 AM -->
<!-- MuClient version 4.33 -->

<!-- Plugin "Aardwolf_Quest_Noter" generated by Plugin Wizard -->

<muclient>
<plugin
   name="Aardwolf_Quest_Noter_v2"
   author="Nick Gammon"
   id="76c899eda20ad99787c6b438"
   language="Lua"
   purpose="Remembers standard quest instructions"
   date_written="2008-07-24"
   requires="4.34"
   version="2.0"
   save_state="y"
   >
<description trim="y">
<![CDATA[
Remembers what a quest-giver told you to do.
]]>
</description>

</plugin>


<!--  Triggers  -->

<triggers>

  <trigger
   match="@questor tells you '*'"
   name="questor_line"
   script="questor_line"
   sequence="100"
   expand_variables="y"
  >
  </trigger>
  
  <trigger
   enabled="y"
   match="You ask * for a quest."
   script="start_questor_stuff"
   sequence="100"
  >
  </trigger>
  
  <trigger
   match="@questor tells you 'You have * to complete your quest.'"
   name="questor_end"
   script="questor_end"
   sequence="10"
   expand_variables="y"
  >
  </trigger>
  
 <trigger
   enabled="y"
   match="QUEST: You have almost completed your QUEST!"
   sequence="100"
   script="quest_done"
  >
  </trigger>

 <trigger
   enabled="y"
   match="You inform * that you have completed your quest."
   sequence="100"
   script="quest_handed_in"
  >
  </trigger>
  
 <trigger
   enabled="y"
   match="There are * minutes remaining until you can go on another quest."
   sequence="100"
   script="quest_time_to_go"
  >
  </trigger>

 <trigger
   enabled="y"
   match="QUEST: You may now quest again."
   sequence="100"
   script="quest_available"
  >
  </trigger>

  <trigger
   enabled="y"
   match="You do not have to wait to go on another quest."
   sequence="100"
   script="quest_available"
  >
  </trigger>
     
</triggers>

<!--  Timers  -->


<timers>
  <timer 
      script="show_quest_text" 
      enabled="y" 
      second="30.00" 
      >
  </timer>
</timers>

<!--  Script  -->


<script>
<![CDATA[

background_colour = 0xE7FFFF
text_colour = 0x000000
heading_colour = 0x800080
time_colour = 0x82004B


quest_info = {}

require "serialize"
require "commas"
require "var"

function quest_handed_in (name, line, wildcards)
  Send "score"
  next_quest_time = os.time () + (30 * 60)  -- 30 mins to go
  quest_info = {}
  show_quest_text ()
end -- quest_handed_in

function quest_time_to_go (name, line, wildcards)
  local mins = tonumber (wildcards [1])
  if mins then
    next_quest_time = os.time () + mins * 60
  else
    next_quest_time = nil
  end -- if
  quest_info = {}
  show_quest_text ()
end -- quest_time_to_go

function quest_available (name, line, wildcards)
  next_quest_time = os.time ()
  quest_info = {}
  show_quest_text ()
end -- quest_available

function quest_done (name, line, wildcards)
  quest_info = { "Quest complete - go hand it in." }
  max_width = WindowTextWidth (win, font_id, quest_info [1])
  show_quest_text ()
end -- quest_done

function start_questor_stuff (name, line, wildcards)
  check (EnableTrigger ("questor_line", true))
  check (EnableTrigger ("questor_end", true))
  quest_info = {}
  max_width = 0
  var.questor = wildcards [1]
end -- start_questor_stuff

function questor_line (name, line, wildcards)
  local text = wildcards [1]

  if string.match (text, "^Thank you, brave ") then
    return
  end -- if
  
  if string.match (text, "^Good luck ") then
    return
  end -- if

  table.insert (quest_info, text  )
  max_width = math.max (max_width, WindowTextWidth (win, font_id, text)) 
  
end -- questor_line

function Display_Line (line, text, id, colour)

local left = 5
local top =  (line - 1) * font_height

  WindowText (win, id, text, left, top, 0, 0, colour)

end -- Display_Line

function show_when_quest_available ()

  local time_to_go = next_quest_time - os.time ()
  
  if time_to_go <= 0 then
    text = "You can quest again!"
  else
    text = string.format ("Time until next quest: %s", convert_time (time_to_go))
  end -- if
  
  max_width = WindowTextWidth (win, font_id, text)
  
 -- recreate the window the correct size
  WindowCreate (win, 
               0, 0,   -- left, top (auto-positions)
               max_width + 10,     -- width
               font_height + 5,  -- height
               7,       -- auto-position: top middle
               0,  -- flags
               0xE7FFFF) 
  
  Display_Line (1, text, font_id, time_colour)
    
  WindowShow (win, true)

end -- show_when_quest_available

function show_quest_text ()

  if #quest_info == 0 and 
    next_quest_time then
    show_when_quest_available ()
    return
  end -- one available now/soon
                 
  -- do nothing if no quest
  if #quest_info == 0 or when_required == nil then
    return
  end -- if

  -- recreate the window the correct size
  WindowCreate (win, 
               0, 0,   -- left, top (auto-positions)
               max_width + 10,     -- width
               (#quest_info + 2) * font_height + 5,  -- height
               7,       -- auto-position: top middle
               0,  -- flags
               0xE7FFFF) 

  -- heading
  local text = "Current quest."
  Display_Line (1, text, font_id, heading_colour)

  -- list of mobs
  for i, v in ipairs (quest_info) do
    Display_Line (i + 1, v, font_id, text_colour)
  end -- for
  
  -- how long to go
  local time_to_go = when_required - os.time ()
  
  if time_to_go < 0 then
    return
  end -- if
  
  text = string.format ("Time to go: %s", convert_time (time_to_go))
  Display_Line (#quest_info + 2, text, font_id, time_colour)
    
  WindowShow (win, true)
    
end -- show_quest_text

function questor_end (name, line, wildcards)

  local text = wildcards [1]
  
   -- work out when quest ends
  
  when_required = os.time ()
  
  local days = string.match (text, "(%d+) days?")
  if days then
    when_required = when_required + tonumber (days) * 60 * 60 * 24
  end -- some days left
  
  local hours = string.match (text, "(%d+) hours?")  
  if hours then
    when_required = when_required + tonumber (hours) * 60 * 60
  end -- some days left

  local minutes = string.match (text, "(%d+) minutes?")  
  if minutes then
    when_required = when_required + tonumber (minutes) * 60
  end -- some days left
 
  check (EnableTrigger ("questor_line", false))
  check (EnableTrigger ("questor_end", false))
  show_quest_text ()
end -- questor_end

function OnPluginSaveState ()
  SetVariable ("enabled", tostring (GetPluginInfo (GetPluginID (), 17)))
end -- function OnPluginSaveState

function OnPluginInstall ()

  win = GetPluginID ()
  font_id = "fn"
  
  font_name = "Comic Sans MS"    -- the actual font

  -- make win so I can grab the font info
  WindowCreate (win, 
                 0, 0, 1, 1,  -- 1 x 1 pixel
                 1,   -- position - irrelevant
                 0,   -- flags
                 0)   -- background colour
                 
  check (WindowFont (win, font_id, font_name, 8))  -- normal
  font_height = WindowFontInfo (win, font_id, 1)  -- height

 if GetVariable ("enabled") == "false" then
    ColourNote ("yellow", "", "Warning: Plugin " .. GetPluginName ().. " is currently disabled.")
    check (EnablePlugin(GetPluginID (), false))
    return
  end -- they didn't enable us last time
  
end -- OnPluginInstall

function OnPluginDisable ()
  WindowShow (win, false)
end -- OnPluginDisable


]]>
</script>

</muclient>



[EDIT] Improved version 2.0, now detects quest text better (if it has a blank line in it), and also shows time till you can quest again, see screenshots.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #1 on Sun 27 Jul 2008 12:31 AM (UTC)

Amended on Mon 28 Jul 2008 12:11 AM (UTC) by Nick Gammon

Message

Examples of it in operation:


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Bottomfeeder   (42 posts)  Bio
Date Reply #2 on Tue 29 Jul 2008 04:14 PM (UTC)
Message
Nick,

I was curious how problematic it would be to trim the Questor input down to Target, Room, Area, and Time to Finish? Loving this stuff, by the way.
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #3 on Tue 29 Jul 2008 09:07 PM (UTC)
Message
I might leave that as an exercise for some budding plugin-writer. :)

It's just text, you just need to identify the keywords like "* has murdered *" and you would quickly find the target.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by LupeMatteo   (6 posts)  Bio
Date Reply #4 on Fri 12 Dec 2008 10:48 PM (UTC)
Message
Bottomfeeder - If you figure out how to convert it down to:
Target:
Room:
Area:

I'd love to know. I'm looking into that as well.

Also, what about positioning of the window. I see 5 sets of numbers, but any clarification of what they mean?
I want to change the position of it in my window... same with the campaign noter.

I find that if my campaign has lots of targets and I take a quest, the Quest Noter won't show up due to lack of window space. I want to move the campaign up to the top right.

Thanks.
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #5 on Sat 13 Dec 2008 12:45 AM (UTC)
Message
Quote:

what about positioning of the window. I see 5 sets of numbers, but any clarification of what they mean?


See the documentation for WindowCreate:

http://www.gammon.com.au/scripts/doc.php?function=WindowCreate

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by LupeMatteo   (6 posts)  Bio
Date Reply #6 on Thu 18 Dec 2008 06:41 PM (UTC)
Message
Thanks, that helped perfect. Got the positioning perfect.

For the Quest Tracker though... I'm attempting to slim down the information that gets stored and displayed so it takes up less room.

Here is the code I've got and its giving me a script parsing error...


function questor_line (name, line, wildcards)
local text = wildcards [1]

if string.match (text, "^This threat must be eliminated!") or
string.match (text, "^you are to deliver the sentence!") then
return

if string.match (text, "^Good luck ") then
return
end -- if

table.insert (quest_info, text )
max_width = math.max (max_width, WindowTextWidth (win, font_id, text))

end -- questor_line


Certain quests change how the questor says what he wants done... ie. "This threat must be eliminated!" or "you are to deliver the sentence!"

Basically, I'm trying to make it check to see if either one is there, store the info between them and "Good luck " and then display it.

Am I missing something??
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #7 on Thu 18 Dec 2008 06:54 PM (UTC)
Message
Each "if" has to have a corresponding "end". Your first one doesn't.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by LupeMatteo   (6 posts)  Bio
Date Reply #8 on Thu 18 Dec 2008 07:22 PM (UTC)
Message
Ah, that would make sense.
However, why is it that only what gets matched doesn't get stored but everything the Questor says before that and in between does?

I thought it was a "match this case, store whats next and then when the next case is matched stop storing info"?
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #9 on Fri 19 Dec 2008 02:55 AM (UTC)
Message
Well, that function is called by the trigger which matches "@questor tells you '*'".

So, unless the function returns early, everything the questor says is stored.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Aps   (5 posts)  Bio
Date Reply #10 on Sat 08 Aug 2009 05:09 AM (UTC)

Amended on Sun 09 Aug 2009 09:59 AM (UTC) by Aps

Message
I like the plugin, just found a couple bugs in it I believe. One if you request a quest early during the 30minute countdown it messes up the timer and it goes back to a different amount of minutes or stops. Also the timer is off in a way because quests reset at the beginning of a tick so they aren't necissarily 30 minutes till the next quest, but it'll be within half a minute.
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


41,231 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.