User input

holatuwol

Developer
I'm still thinking through the confirm example. So far, I can't come with a solution that's any less weird than your universal abort script.
I can't come up with anything less clumsy.

boolean user_confirm( string ): Added.
 
[quote author=holatuwol link=topic=449.msg3953#msg3953 date=1174243323]
I can't come up with anything less clumsy.

boolean user_confirm( string ): Added.
[/quote]

Yay! This combined with my auto-start chat functionality means almost all likely script errors can be recovered from instead of doing it all manually and no worries about session time outs due to my having walked away for 10 minutes! Thanks!
 

Veloz

New member
[quote author=holatuwol link=topic=449.msg3953#msg3953 date=1174243323]
boolean user_confirm( string ): Added.
[/quote]

Thanks for adding this in... I look forward to the next release!
 

Veloz

New member
I know we've already gone down this road once, but this idea was sent to me by someone who has a great way of presenting their case... not sure if they want to remain anonymous, but lets just say that this person knows what they're talking about:

The task you want is buying and eating a chow mein.

Without select:
Code:
If(item_amount($item[Knob sausage chow mein]) < 1)
  {
  if(!confirm("buy 1 knob sausage chow mein?"))
    {
    if(!confirm("eat 1 bat wing chow mein?"))
      {
      if(!confirm("eat 1 rat appendix chow mein?"))
        {
         cli_execute("abort out of choices");
        }
        else
        {
        If(item_amount($item[rat appendix chow mein]) < 1)
          {
          if(!confirm("buy 1 rat appendix chow mein?"))
            {
            cli_execute("abort unable to eat");
            }
            else
            {
            buy(1, $item[rat appendix chow mein]);
            return eat(1, $item[rat appendix chow mein]);
            }
          }
        }
      }
      else
      {
      If(item_amount($item[bat wing chow mein]) < 1)
        {
        if(!confirm("buy 1 bat wing chow mein?"))
          {
          cli_execute("abort unable to eat");
          }
          else
          {
          buy(1, $item[bat wing chow mein]);
          return eat(1, $item[bat wing chow mein]);
          }
        }
      }
    }
    else
    {
    buy(1, $item[Knob sausage chow mein]);
    return eat(1, $item[Knob sausage chow mein]);
    }
  }

with select:
//select("prompt text","choices,comma,delimited")
//returns a 0 based integer corresponding to the chosen item.

Code:
int a = select("choose a chow mein", "knob sausage, bat wing, rat appendix");
item choicefood;
if(a==0)
  {choicefood = $item[knob sausage chow mein]}
  else
  {
  if(a==1)
    {choicefood = $item[bat wing chow mein]}
    else
    {choicefood = $item[rat appendix chow mein]}
  }
  
if(item_amount(choicefood) < 1)
  {
  if(confirm("buy a " + choicefood + "?"))
    {
    buy(1, choicefood)
    }
    else
    {
    cli_execute("abort cannot eat a " + choicefood);
    }
  }
eat(1, choicefood);
 

holatuwol

Developer
As stated before, you'd need to find a real example where it's necessary. I don't see why a script should ever ask the user which chow mein they should eat. It's chow mein, and consumption of chow mein has been more or less reduced to an exact science. Either it supplements main stat, or it supplements mysticality. There is no other choice. Asking the user is like walking up to someone saying, "Say, what color is the sky today?"
 

holatuwol

Developer
Because it was brought up elsewhere, here's what the script should look like without using select, assuming you avoided making things complicated on purpose. Now, I recognize the user will be prompted twice more than in the "select" example, but showing me something needlessly complicated isn't a good 'convince me' route.


PHP:
boolean ate_something = false;

void try_eat( item food )
{
    if ( ate_something )
        return;

    if ( !user_confirm( "eat 1 " + food + "?" ) )
        return;

    if ( food.item_amount() == 0 )
        if ( !user_confirm( "buy 1 " + food + "?" ) )
            abort( "cannot eat a " + food + "." );

    eat( 1, food );
    ate_something = true;
}

void main()
{
    try_eat( $item[knob sausage chow mein] );
    try_eat( $item[bat wing chow mein] );
    try_eat( $item[rat appendix chow mein] );

    if ( !ate_something )
        abort( "Could not eat anything." );
}
 

Catch-22

Active member
Unless I'm missing something, the primary motivation for not including user prompting for anything other than booleans is just as problematic now as it was two years ago.

I think user_confirm was only added because I could sympathize with the idea of using it to abort a script. If it's frustrating to feel limited by it, I'd feel more comfortable removing it entirely than I would by adding more things that'd lead to "Ok, so KoLmafia suddenly locked up..." bug reports.

Well, I wasn't around for that discussion. Whilst I can certainly understand some of your concern, I still think there is room for more user input functionality in KoLmafia.

Let's take Veracity's MMG script as an example:

First of all, instead of "Please input a value for int amount", you can have something more meaningful and user-friendly like "How much meat would you like to bet?"

We all knew that one already, so let's move on.

The second - more important - advantage is the ability to validate and act upon user-input on the fly.

Consider this scenario.

Instead of:

Code:
Please input value for int amount
>1
Please input value for float factor
>1
Please input value for int iterations
>1
Please input value for int chain_count
>1
Betting 1 meat from inventory
You must bet at least 1,000 meat.
Bet 1/1/1: for 1 Meat -> FAILED
Chain 1 failed on iteration #1 placing bet for 1
Done running 1 chains of 1 bets.
Net winnings = 0. Net change to closet = 0

You could have:

Code:
How much meat would you like to bet?
>1
You must bet at least 1,000 meat.
How much meat would you like to bet?
>1000
etc.

If you are so concerned about the end-user experience, how can you argue that this is not a better solution?
 

holatuwol

Developer
If you're doing prompting the user for information anyway, then yes, I completely agree. Providing a friendly message with user_input would be better than calling main().

Perhaps people believe that I encourage using the main method workaround or that I think it's "good enough" or something.

The fact is, I don't. I believe that prompting for information should never happen except at the very beginning of a script. I just indicate that for the people who are desperate for doing something I completely disagree with, a workaround exists, and I won't implement anything else that further supports something I strongly disagree with unless it's absolutely necessary.

Maybe the question that needs to be answered is, "Why do I feel that way?" Because re-reading this thread, it looks like nobody has a clue what I'm talking about it, since they just talk about how'd they'd use the feature without ever addressing my problem with it.

Okay, so here's the problem in more detail. (As a side note, it doesn't exist on OSX because of the way applications in OSX are organized, so it's more or less Windows/Linux specific.)

Suppose there is something in KoLmafia that prompts you for input (doesn't matter what it is). If you are alt-tabbed away from KoLmafia, alt-tabbing back to KoLmafia does not necessarily give you the prompting field. In fact, if you alt-tab, more likely than not, all fields will be unclickable and you won't see a prompt. In order to see the prompt, you have to alt-tab to the specific window that is bound to the prompting field.

Giving scripts free reign to prompt while you're alt-tabbed (which KoLmafia shouldn't do normally unless it's a yes-no prompt making sure you want to overdrink, which user_confirm also is intended to give scripters the ability to do) is probably asking for trouble.

Any solutions, or will we keep getting the same old, "BUT THIS IS HOW I'D USE IT" arguments that I kept getting two years ago?
 
Last edited:
I don't know anything about java at all, but if there is a way to force the input field box to always be on top of other KoLmafia windows maybe that would be relevant? Like I said I don't know enough to say if this option exists or if it is even worth the code it would take to implement it; it was just a thought.

Edit: It's always funny to see a ninja get ninja'd. lol
 

holatuwol

Developer
As far as I know, this isn't possible.

According to this, there's theoretically a way to force the popup into its own taskbar icon. However, this winds up being equivalent to someone IM'ing you while you're typing something, so it's not a very desirable solution.
 

dj_d

Member
Hola - not only do I agree with you, I would have preferred user_confirm not to exist either for the same reason. :)
 

Catch-22

Active member
If there's one thing I hate, it's a dialogue box that appears over the top of my full-screen Team Fortress 2 window ;)

I believe it's possible to check if KoLmafia is on-top, or the active window.

The solution that I can think of (off the top of my head) is to check if KoLmafia is the active window.

If KoLmafia is currently the active window, create the popup user input box, otherwise wait until it becomes the active window.

After thinking about it though, that method is probably the bad way of doing things. Java documentation recommends against checking if a window is active and suggests checking if a window has been activated instead. This lead me to think of another solution.

That other solution would be an event listener. I can explain myself better with some code, so here it is:

Code:
public void focusGained(FocusEvent e) {
  if getOwnedWindows.length >= 1 {
    getOwnedWindows(1).toFront();
  }
}

To talk you through that:

First off, the event is fired when the main KoLmafia window gains focus. If there are child windows, bring them to the front. This should give focus to a rogue dialogue.

Once you've finished with the dialogue box, focus will be given back to the main window and the event will fire again and check for more rogue windows.

Obviously more checks will need to be done to make sure that the window is a dialogue and not just some other child object of KoLmafia, but you get the general idea :)
 
Last edited:

zarqon

Well-known member
I'm with hola on this -- a good script should prompt for (and validate) all necessary user input at the beginning. I haven't seen any case where prompting for user input mid-script is necessary.

I have used all of two user_confirm()'s in all my released scripts. One I used because I thought there was no other way to get information besides asking the user -- I was mistaken, so it's gone. The other I used to let users know they had an outdated version of the script, and ask them if they would like to continue or abort. It was meant to be deliberately annoying, and it was. Users complained their heads off, for a variety of good and not-so-good reasons. I am happy to say that when the next ZLib is released there will be no user_confirm()'s left in any of my scripts.

One suggestion that might help lay this to rest: some means of adding "documentation" to main() functions that have parameters. Something like

Code:
main(string what_to_devour|"Which food item would you like to devour?") {

The documentation string would be shown in the input box for each parameter.
 

Grotfang

Developer
I think zarqon's point (and one that has been echoed by others elsewhere) about being able to add documentation to parameters is spot on.

The only time I can think of when user input is required after main is called is if the script is looping and the initial user input may need to be changed on the second run through. However, running the script a second time is not much more annoying than doing this, so I see little point in introducing it. The harm that could be caused through mis-use in terms of infuriating users is much greater than the harm caused by the lack of this feature in my opinion.

Documentation would improve script clarity, especially as for non-experienced users the variable names presented are not always especially intuitive.
 

mredge73

Member
I like user-confirms and vote in favor of one that can accept a string.

You don't have to use them in your scripts and some scripts may benefit in having them. I have many scripts that I cannot release because if I did they would require a user manual to run them, where if they accepted user input beyond boolean they could be worthy of beta release.
I just don't like having to edit a .txt file every time I run a script. For that reason I have resisted using Z's vars for my item handling scripts. I don't expect people who use my scripts to have a text editor open while running them.

But again, you don't have to use them in your scripts if you oppose them.
 
Last edited:

Veracity

Developer
Staff member
Giving scripts free reign to prompt while you're alt-tabbed is probably asking for trouble.
...
Any solutions, or will we keep getting the same old, "BUT THIS IS HOW I'D USE IT" arguments that I kept getting two years ago?

I like user-confirms and vote in favor of one that can accept a string.
... THIS IS HOW I'D USE IT ...
But again, you don't have to use them in your scripts if you oppose them.

Sigh.

Actually, Catch-22 proposed a technical approach to the technical problem. I can't say if it would work or not. The problem is a Windows thing - and I don't do Windows.
 

zarqon

Well-known member
I just don't like having to edit a .txt file every time I run a script. For that reason I have resisted using Z's vars for my item handling scripts.

Forgive the off-topic post -- just wanted to note that you can edit script settings by calling ZLib directly. You don't need to edit any text files.
 
Top