[Home] [Downloads] [Search] [Help/forum]


Register forum user name Search FAQ

Gammon Forum

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Lua
. . -> [Subject]  Can't reuse state file variable value…

Can't reuse state file variable value…

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


Posted by gameshogun   Philippines  (9 posts)  [Biography] bio
Date Mon 26 Oct 2015 12:34 AM (UTC)

Amended on Mon 26 Oct 2015 12:35 AM (UTC) by gameshogun

Message
Can't make anything to work… :(

Since EXP per level is static, I want to be able to set it on a per world basis (since my MCL files are per-character).

But whenever I try to re-use the value, it's a nil.

Here's the variable state file:

<variable name="char_exp">char_exp = {
xpl = "16000",
}</variable>


And here's part of the script:

require "serialize"  -- needed to serialize table to string
char_exp = {}  -- ensure table exists, if not loaded from variable

function OnPluginInstall ()
  assert (loadstring (GetVariable ("char_exp") or "")) ()
end -- function OnPluginInstall

function OnPluginSaveState ()
  SetVariable ("char_exp",
               "char_exp = " .. serialize.save_simple (char_exp))
end -- function OnPluginSaveState

if char_exp == nil then               -- pop-up dialog for the first time
  xpl = utils.inputbox (
    "Max XP per level?",                      -- text question
    "XP per Level",                           -- window title
    nil,                                      -- field pre-text
    nil,                                      -- font
    nil,                                      -- font-size
    { -- dialog box dimensions
      box_width = 180,
      box_height = 130,
      prompt_height = 12,
      reply_width = 80,
      reply_height = 20,
      max_length = 12,
    }
  )
  char_exp.xpl = xpl                  -- push dialog value to char_exp.xpl for saving
  char_xpl = xpl                      -- push dialog value to char_xpl for XP bar use
else                                  -- already set
  char_xpl = char_exp.xpl             -- reuse existing value in state file
  Note ("char_xpl: " .. char_exp.xpl) -- test if it's working
end


I also tried a different way, manually setting a variable via Shift+CTRL+7 but the plugin doesn't see it, tried GetVariable, GetPluginVariable, to no avail.

*shrugs* Not sure what I'm missing or might have misunderstood.

Anyway, it's for my EXP bar.

Thanks ^_^

Confirm my identity: https://yukino.keybase.pub
Read my profile: https://jcsesecuneta.com/profile/
[Go to top] top

Posted by Fiendish   USA  (2,514 posts)  [Biography] bio   Global Moderator
Date Reply #1 on Mon 26 Oct 2015 04:49 PM (UTC)

Amended on Mon 26 Oct 2015 04:52 PM (UTC) by Fiendish

Message
If you're having a problem with plugins not saving state, make sure you have
save_state="y"
in the <plugin ....> block at the top of the file. Otherwise...


Plugins don't store variables in the world file, they store in their own state files in worlds/plugins/state.

In order to read the world's variable, you need to use GetPluginVariable (hahaha) with a blank plugin name, like this:

GetPluginVariable ("", "char_exp")


You will never be able to SetVariable to the global location from a plugin, though, unless you convince Nick to make that possible. I've tried. :)

Nick does suggest a (too fragile to work for me, but maybe usable for you) workaround in http://www.mushclient.com/forum/?id=12815&reply=7#reply7 of making a world alias that you then Execute.

https://github.com/fiendish/aardwolfclientpackage
[Go to top] top

Posted by Nick Gammon   Australia  (22,975 posts)  [Biography] bio   Forum Administrator
Date Reply #2 on Mon 26 Oct 2015 08:42 PM (UTC)
Message
Can you post the entire plugin? What you have there looks reasonable. I'd like to test it.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by gameshogun   Philippines  (9 posts)  [Biography] bio
Date Reply #3 on Mon 26 Oct 2015 11:06 PM (UTC)

Amended on Mon 26 Oct 2015 11:40 PM (UTC) by Nick Gammon

Message
Thank you for the replies.

Here it is, it's all based on the prompt-based exp bar sample you wrote. Trying to put the "exp per level" as a saved variable so there's less displayed on the prompt.

Also, I adjusted the computation below to xp tnl.


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE muclient [
  <!ENTITY trigger_match  "^\[\-?(\d+)\/(\d+) \-?(\d+)\/(\d+) \-?(\d+)\/(\d+) (?P<axp>\d+) (.*?)$" >
]>

<!--History>
  * Based on Nick Gammon "Experience Bar" plugin
    * http://www.gammon.com.au/forum/?id=9224
  * With additional assistance
    * http://www.gammon.com.au/forum/?id=13018
</History-->

<muclient>
  <plugin
    name="Ansalon_MW_Expbar_Prompt"
    author="Ansalon"
    language="Lua"
    purpose="Shows XP to level as bar"
    save_state="y"
    date_written="2015-09-30"
    date_modified="2015-10-27"
    requires="4.99"
    version="1.10"
    id="62a3dfc07c5b023272af5e6e"
    >
    <description trim="y"><![CDATA[
      Install this plugin to show how close you are to levelling.

      Note: This is prompt based.

      I. Match
        1. See "trigger_match" at the top of this file
        2. Change it to match your prompt design
    ]]></description>
  </plugin>

  <triggers>
    <trigger
      enabled="y"
      match="&trigger_match;"
      regexp="y"
      script="do_prompt"
      sequence="100"
    ></trigger>
  </triggers>

  <script><![CDATA[
    win = GetPluginID ()  -- get a unique name

    -- configuration
    GAUGE_HEIGHT = 11
    NUMBER_OF_TICKS = 20

    BACKGROUND_COLOUR = ColourNameToRGB "gray"
    BOX_COLOUR = ColourNameToRGB "dodgerblue"

    require "serialize"  -- needed to serialize table to string
    char_exp = {}  -- ensure table exists, if not loaded from variable

    -- on plugin install, convert variable into Lua table
    function OnPluginInstall ()
      assert (loadstring (GetVariable ("char_exp") or "")) ()
    end -- function OnPluginInstall

    -- on saving state, convert Lua table back into string variable
    -- save_simple is for simple tables that do not have cycles (self-reference)
    -- or refer to other tables
    function OnPluginSaveState ()
      SetVariable ("char_exp",
                   "char_exp = " .. serialize.save_simple (char_exp))
    end -- function OnPluginSaveState

    if char_exp == nil then
      xpl = utils.inputbox (              -- pop-up dialog for the first time
        "Max XP per level?",                      -- text question
        "XP per Level",                           -- window title
        nil,                                      -- field pre-text
        nil,                                      -- font
        nil,                                      -- font-size
        { -- dialog box dimensions
          box_width = 180,
          box_height = 130,
          prompt_height = 12,
          reply_width = 80,
          reply_height = 20,
          max_length = 12,
        }
      )
      char_exp.xpl = xpl                  -- push dialog value to char_exp.xpl for saving
      char_xpl = xpl                      -- push dialog value to char_xpl for XP bar use
    else                                  -- already set
      char_xpl = char_exp.xpl             -- reuse existing value in state file
      Note ("char_xpl: " .. tonumber (char_exp.xpl))    -- test if it's working
    end -- if char_exp


{cont next post}

Confirm my identity: https://yukino.keybase.pub
Read my profile: https://jcsesecuneta.com/profile/
[Go to top] top

Posted by gameshogun   Philippines  (9 posts)  [Biography] bio
Date Reply #4 on Mon 26 Oct 2015 11:07 PM (UTC)

Amended on Mon 26 Oct 2015 11:41 PM (UTC) by Nick Gammon

Message
{cont.}

    -- draw the bar here, on getting the prompt, or window resize
    function draw_bar ()

      -- check numbers for validity
      if not current_xp or
         not max_xp or
         current_xp < 0 or
         max_xp <= 0 then
         return
      end -- if

      -- cannot have more than max xp
      if current_xp > max_xp then
         current_xp = max_xp
      end -- if

      -- width is window width minus 2
      local gauge_width = GetInfo (281) - 2

      -- make room for the bar
      local bottom_margin = GetInfo (275)

      -- adjust text rectangle, keeping existing settings where possible
      if bottom_margin == 0 or
        (bottom_margin < 0 and math.abs (bottom_margin) < (GAUGE_HEIGHT + 2)) then
        TextRectangle(GetInfo (272), GetInfo (273),   -- left, top
                      GetInfo (274), -- right
                      - (GAUGE_HEIGHT + 2),  -- bottom (gauge height plus 2 more)
                      GetInfo (276), GetInfo (282) or 0, GetInfo (277),  --  BorderOffset, BorderColour, BorderWidth
                      GetInfo (278), GetInfo (279)) -- OutsideFillColour, OutsideFillStyle
      end -- if

      -- make the miniwindow
      WindowCreate (win,
                    0, 0,   -- left, top (auto-positions)
                    gauge_width,     -- width
                    GAUGE_HEIGHT,  -- height
                    10,       -- auto-position: bottom left
                    0,  -- flags
                    BACKGROUND_COLOUR)

      WindowRectOp (win, 2, 0, 0, 0, 0, BACKGROUND_COLOUR)  -- fill entire box

      -- how far through the level we are
      local done = current_xp / max_xp
      local bar_width = gauge_width * done

      -- box size must be > 0 or WindowGradient fills the whole thing
      if math.floor (bar_width) > 0 then

        -- top half
        WindowGradient (win, 0, 0,
                        bar_width, GAUGE_HEIGHT / 2,
                        0x000000,  -- black
                        BOX_COLOUR,
                        2)   -- vertical gradient

        -- bottom half
        WindowGradient (win, 0, GAUGE_HEIGHT / 2,
                        bar_width, 0,
                        BOX_COLOUR,
                        0x000000,  -- black
                        2)   -- vertical gradient
      end -- any experience to speak of

      -- show ticks
      local ticks_at = gauge_width / NUMBER_OF_TICKS

      -- ticks
      for i = 1, NUMBER_OF_TICKS do
        WindowLine (win, i * ticks_at, 0, i * ticks_at, GAUGE_HEIGHT, ColourNameToRGB ("silver"), 0, 1)
      end -- for

      -- draw a box around it
      check (WindowRectOp (win, 1, 0, 0, 0, 0, ColourNameToRGB ("lightgrey")))  -- frame entire box

      -- ensure window visible
      WindowShow (win, true)
    end -- draw_bar

    function do_prompt (name, line, wildcards, styles)
      -- CHANGE HERE if your prompt is different (eg. different wildcard numbers)
      -- (string.gsub removes commas from the experience figures, if necessary)
      max_xp = tonumber (char_xpl)
      current_xp = max_xp - tonumber (wildcards.axp)

      draw_bar ()
    end -- do_prompt

    function OnPluginWorldOutputResized ()
      draw_bar ()
    end -- function

    -- hide window on removal
    function OnPluginClose ()
      WindowShow (win,  false)  -- hide it
    end -- OnPluginClose

    -- hide window on disable
    function OnPluginDisable ()
      WindowShow (win,  false)  -- hide it
    end -- OnPluginDisable
  ]]></script>
</muclient>


Thank you again.

Confirm my identity: https://yukino.keybase.pub
Read my profile: https://jcsesecuneta.com/profile/
[Go to top] top

Posted by Nick Gammon   Australia  (22,975 posts)  [Biography] bio   Forum Administrator
Date Reply #5 on Mon 26 Oct 2015 11:52 PM (UTC)
Message

    if char_exp == nil then


That won't be nil, because it is set to an empty table further up:


    char_exp = {}  -- ensure table exists, if not loaded from variable


This test is better:


    if next (char_exp) == nil then  -- is table empty?





I think the big problem here is the order in which you are doing things.

You were displaying your dialog box before OnPluginInstall (since that code was not in any function). That meant you asked for the max XP, got an answer, and then overwrote it by reading in the saved variable. If you move the dialog into OnPluginInstall it seems to work fine for me.


   -- on plugin install, convert variable into Lua table
    function OnPluginInstall ()
      assert (loadstring (GetVariable ("char_exp") or "")) ()

       if next (char_exp) == nil then
          xpl = utils.inputbox (              -- pop-up dialog for the first time
            "Max XP per level?",                      -- text question
            "XP per Level",                           -- window title
            nil,                                      -- field pre-text
            nil,                                      -- font
            nil,                                      -- font-size
            { -- dialog box dimensions
              box_width = 180,
              box_height = 130,
              prompt_height = 12,
              reply_width = 80,
              reply_height = 20,
              max_length = 12,
            }
          )
          char_exp.xpl = xpl                  -- push dialog value to char_exp.xpl for saving
          char_xpl = xpl                      -- push dialog value to char_xpl for XP bar use
        else                                  -- already set
          char_xpl = char_exp.xpl             -- reuse existing value in state file
          Note ("char_xpl: " .. (tonumber (char_exp.xpl) or "NIL!"))    -- test if it's working
        end -- if char_exp

    end -- function OnPluginInstall

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (22,975 posts)  [Biography] bio   Forum Administrator
Date Reply #6 on Mon 26 Oct 2015 11:54 PM (UTC)
Message
Of course you probably want to make some option to change that variable, but I guess this is a work in progress. :)

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by gameshogun   Philippines  (9 posts)  [Biography] bio
Date Reply #7 on Tue 27 Oct 2015 10:01 AM (UTC)
Message
Ooh… thanks a bunch! I've been moving the code around but didn't realize it should be on OnPluginInstall. Now that you pointed it out, it's indeed the correct place.

Thanks for the correction too. I'll read about function next ^_^

And yep, a work in progress. Only recently thought of saving the max_xp value in the state file instead of via the prompt and or hard-coding, after I created another character. I don't know where it'll end up, learning as I go. :)

Confirm my identity: https://yukino.keybase.pub
Read my profile: https://jcsesecuneta.com/profile/
[Go to top] 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.


18,244 views.

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

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

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

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at HostDash]