ID:2355909
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Forgive me for rambling but I'm going to try to explain both what I want and why I want it, to make sure you understand the request.

Imagine that I've got a need for very flexible approach to parameter entry, where sometimes but not always there will be a number or string in place of what might otherwise be an item in list.

With the command-foo you just re-implemented for me, numbers are very easy. Check if the argument being entered is a number-string, then return that exact number-string that's been entered as a valid argument, and convert it to an actual number in the proc that uses it.

Easy-peasy!

In fact it's easier than that, because I can put "as null|num|anything in listproc()" and it will let you type in a number. I would just do it the other way so I can stop it from accepting numbers when numbers aren't valid.

What I *can't* do, even with the command-foo, is have it conditionally accept strings. Technically I can make it take whatever you're typing for the argument and put that as a string in the list of acceptable arguments, but the command line won't accept spaces for a non-text argument, even if you start it with a quotation mark.

And if you put "as null|num|text|anything in listproc()" as the argument type, it puts " as the first item in the expansion list. Which is *fine* if a text string is always an appropriate argument, but the point of this exercise is it won't always be.

So my ask here is a way to conditionally accept text strings. I've got two possible ways this might be implemented. I'm usually bad at guessing what's a big ask and what's a small one. I have a feeling my preference might be a great big hairy deal but I've got a fallback that might be easier.

Preference: A way to make an argument type conditional. Maybe a value that can be added to a list that, when returned for list_of_valid_targets_proc(), signals to the client that it should take a text string there. If it's the only item in the list then it treats the "as anything in list()" as if it just said "as text", if there are other valid items returned by the proc it treats it the same way that doing "as text|anything in list()" works.

Fallback: Make it so that if the player starts an argument with ", it starts taking input as if it's text. I.e., the player can put a space within the argument and it doesn't try to expand/evaluate unless they've put a closing quote on it.

I have a workaround that lets me fake this for my most obvious and pressing uses for it (basically: verbs with the same name but different arguments and ways of making sure they're mutually exclusive enough that the client is always checking the right one) but there are corner cases and a lot more things I would be able to do if I could.

Just to give you an example, if you can't wrap your head around what I would use this for, say I've got a single verb, cast(), that works for every spell in the game. Some spells are targeted at one mob in a list returned by enemies(). Some are targeted at three mobs of your choice. Some are targeted at random. Some would need numerical parameters, like relative coordinates (-5, 11) or absolute coordinates (112, 117) and a map reference "Town of Hawthorne".

I can have players enter map references (or the true name of a distant mob, or whatever) as commandtextwithoutspaces and it's not a huge deal because it's going to look for the closest match anyway. But what if instead of looking for a name, you're giving a name to a summoned creature or created item? You'd want to be able to type it properly.

In terms of priority: this would be huge for me but it's not time sensitive. The bugs you fixed were basically preventing me from having anyone else even playtest the game because of the number of workarounds needed to do anything in it, but this is more long term planning for stuff I'd *like* to put in.

If it can be worked in somehow within a few versions I would really appreciate it. But I've got a while to go before I'd do anything with it I can't do with the newly fixed parser stuff.
I'm still trying to digest this but if I understand correctly, the main issue is that when you have an argument proc, expansion behaves badly when text strings are in play and you want spaces to be allowed.

I ran some tests myself with null|num|command_text as the type, and found that spaces definitely present a fly in the ointment when there's an argument proc. To make matters worse, I tried this:

proc/listproc()
return list("blue", 5, "that thing over there")
mob/verb/ctext(msg as null|num|command_text in listproc())
world << "Command text :[msg]"

When you try to expand "that thing over there" (no quotes obvously) it expands it with hyphens, but those hyphens get stripped out again when checking for validity--IIRC that's a fallback mechanism, because if you show the argument that the listproc() actually receives it has the hyphens. But I think for obvious reasons you'd want to allow spaces to behave normally in command_text, at least when it's the last argument.
Yeah, command_text doesn't work, especially when there's multiple arguments and the text one *might* not be the last one. As far as I can tell(?), a command_text argument supersedes any subsequent arguments because there's no way to tell the client that the command_text argument has ended.

(And it can happen in reverse if the preceding arguments are optional. The client just can't tell whether the words in the line are individual arguments or if they're all just the command_text one.)

the main issue is that when you have an argument proc, expansion behaves badly when text strings are in play and you want spaces to be allowed.

I mean, sort of, but that's a weird way to phrase it?

What I want is the ability to have conditional argument types, either in a literal straightforward fashion... as in, if my argumentproc() returns a certain value, it treats it as if the argument is "as text"... or "as num", for that matter, though as I said, I have workarounds for numbers.

If that is not feasible, I would like for the client to simply not try to evaluate or expand an argument that starts with " until it encounters a closing ", allowing spaces along the way and then sending the whole thing spaces and all, the same way it does if the argument is typed in the code "as text".

I can do this...ish, by having text as one of the argument types. But then it's *always* an allowed argument type, and the " shows up in the expansion, even if a text entry is not appropriate given the things occupying other arguments.

I'd then have to cue players to put the " in themselves, or have it that when the previous argument is validated in a way that the game expects the next argument to be a string, the game uses winset to add it to the command line. Which is why I'd prefer if we could just make allowed argument types conditional; it seems more seamless. But I could see that being weird and hard to do.

I can give you more use cases for this but I'm not sure that's not just making it more confusing.
I might have an idea for a solution...though, can you provide an example of the multiple args?