Problems repeating verbs/commands? (resolved)

graveyardtrash
14 Aug 2017, 20:41Hi. I started using Quest today and I'm having a frustrating/confusing problem with verbs. I'm trying to write some interactions with NPCs and the following action is working just fine:
attack; fight; battle; combat; hit; challenge; kill
If the player types in any of those words it will successfully print a message with the npc's reaction. However the following verb will not work at all:
flirt; flirt with; hit on; compliment; seduce
(I guess Quest would just prefer that there's no romance in my game, haha.) When the player uses a command with one of the above words, it will print the message in game: "You can't flirt; flirt with; hit on; compliment; seduce" or it will print: "You can't hit on; flirt with; flirt." Weirdly, even when I delete the verb altogether, if the player uses a command with one of the above words it will still print the same error. And for some reason when I delete the verb and make a new one, if the new verb has any of the above words it will automatically change it back to the sequence "hit on; flirt with; flirt."
Does anyone have any idea why this is happening or how to resolve it? I'm using the online editor as I have a Mac.
My other question, just out of interest, is whether it's possible to change what a verb does if it's clicked on more than once. So for example choosing to attack an npc would print a message with their reaction, but attacking them again would lead to a message like 'You've already tried that'.
Thanks in advance to anyone who can help me with this.

Doctor Agon
14 Aug 2017, 21:09Hi graveyardtrash. I'll deal with the second question, as that's the one I am more confident in answering.
You set up a flag on the object in question, then when you use the verb, check the flag, if it's inactive ---> run script, else print the message. Here's an example from my game where you lever a tree stump over revealing a hole into a maze. I put the check on, because the tree stump turns up again later in the game.
if (GetBoolean(tree_stump, "over")) {
msg ("You have already done that.")
}
else {
SetObjectFlagOn (tree_stump, "over")
MoveObject (hole1, grassy_knoll)
MoveObject (tree_stump, cliff_face)
MakeExitVisible (ExitMaze1Down)
msg ("You lever the stump of a once mighty oak over the side of the cliff, revealing a hole going {exit:ExitMaze1Down}.")
}
Hope that helps.

Dcoder
14 Aug 2017, 21:23-
In addition to deleting the verb, also delete the verb on every object that uses that verb. This should reset things to the default. Better yet, use commands.
-
Use the "First time" option -- first time, Quest will run certain scripts; then after that it will do another set of scripts.
The Pixie
14 Aug 2017, 21:40Are you using the desktop version? If so delete the verb object which is under the game object on the left.
hegemonkhan
14 Aug 2017, 23:29no idea what's going on with your 'Q1', but there's one mistake I can point out with it (maybe this will fix it for you, but there's likely more going on with it, for why it's not working):
quest has to parse your input (indirect: using/doing the Verb, or, direct: using/doing a Command)
so, this means that you must do the longer sub-pattern first, when you got multiple sub-patterns containing the same initial sequence:
flirt; flirt with; hit on; compliment; seduce // this is wrong: 'flirt with' has to go BEFORE (to the left of) 'flirt'
flirt with; flirt; hit on; compliment; seduce // this is correct
possibly some of these words (flirt; flirt with; hit on; compliment; seduce) are already built-in Verbs/Commands, and so, this can possibly cause issues too...
hegemonkhan
14 Aug 2017, 23:58HK edited:
added in code for using a String Attribute for multiple states (as alternative to an Integer Attribute)
added in quick commentary/note of List/Dictionary being able to do multiple states at the same time
as for your 'Q2', there's a few ways of handling it:
- using the built-in 'firsttime/otherwise' Function (2 states)
<object name="orc">
<attr name="fight" type="script">
// the orc's 2 states:
// the orc is alive: firsttime { /* scripting */ }
// the orc is dead: otherwise { /* scripting */ }
firsttime {
msg ("You fight and kill the orc")
} otherwise {
msg ("The orc is already/still dead, silly.")
}
</attr>
</object>
<verb>
<property>fight</property>
<pattern>fight</pattern>
<defaultexpression>You can't fight that!</defaultexpression>
</verb>
- using a Boolean Attribute (2 states):
<object name="orc">
<attr name="dead" type="boolean">false</attr>
<attr name="fight" type="script">
// the orc's 2 states:
// the orc is alive: orc.dead = false
// the orc is dead: orc.dead = true
if (orc.dead) { // if (TRUE) // in its full long form, it is this: if (orc.dead = true) { // the orc is dead
msg ("The orc is already/still dead, silly.")
} else { // if (FALSE) // the orc is alive
orc.dead = true // you need to actually set/re-set/change/alter the state (orc.dead) of the orc to actually be dead (orc.dead = true) // the orc's state as being 'alive', is: orc.dead = false
msg ("You fight and kill the orc")
}
</attr>
</object>
<verb>
<property>fight</property>
<pattern>fight</pattern>
<defaultexpression>You can't fight that!</defaultexpression>
</verb>
// ------------------------------------
// or, this slightly different logic design might be more preferred:
<object name="orc">
<attr name="dead" type="boolean">false</attr>
<attr name="fight" type="script">
// the orc's 2 states:
// the orc is alive: orc.dead = false
// the orc is dead: orc.dead = true
if (not orc.dead) { // if (not true) // if (FALSE) // in its full long form, it is this: 'if (not orc.dead = true) {' or 'if (orc.dead = false) {' or 'if (orc.dead <> true) :' // the orc is alive
orc.dead = true // you need to actually set/re-set/change/alter the state (orc.dead) of the orc to actually be dead (orc.dead = true) // the orc's state as being 'alive', is: orc.dead = false
msg ("You fight and kill the orc")
} else { // if (TRUE) // if (orc.dead) { // if (orc.dead = true) { // the orc is dead
msg ("The orc is already/still dead, silly.")
}
</attr>
</object>
<verb>
<property>fight</property>
<pattern>fight</pattern>
<defaultexpression>You can't fight that!</defaultexpression>
</verb>
- using an Integer Attribute (for/when having MORE THAN 2 states, and though, while no reason for doing so, you can also use an Integer Attribute for, 1 or 2, states, as well, lol. But, really, you use an Integer Attribute for when it's needed: more than 2 states):
<object name="player">
<attr name="current_experience" type="int">0</attr>
<attr name="current_currency" type="int">0</attr>
</object>
<object name="orc">
<attr name="experience" type="int">25</attr>
<attr name="currency" type="int">75</attr>
<attr name="dead" type="int">0</attr>
<attr name="fight" type="script">
// the orc's 3 states:
// orc is alive: orc.dead = 0
// orc is dead, but NOT looted yet: orc.dead = 1
// orc is dead AND IS looted: orc.dead = 2
if (orc.dead = 0) { // orc is alive
orc.dead = 1 // need to actually set the orc as now being dead-but-not-looted-yet
msg ("You fight and kill the orc")
} else if (orc.dead = 1) { // orc is dead but not yet looted
player.current_experience = player.current_experience + orc.experience // you loot/get the orc's experience
player.current_currency = player.current_curreny + orc.currency // you loot/get the orc's currency
orc.dead = 2 // need to actually set the orc as now being dead-and-looted
msg ("You loot the corpse of the dead orc")
} else { // if (orc.dead = 2) { // orc is dead and looted
msg ("The orc is already/still dead, and it's already been looted too, silly.")
}
</attr>
</object>
<verb>
<property>fight</property>
<pattern>fight</pattern>
<defaultexpression>You can't fight that!</defaultexpression>
</verb>
- using a String Attribute for more than 2 states (again can be used for 1 or 2 states as well, but it's really for more than 2 states):
<object name="player">
<attr name="current_experience" type="int">0</attr>
<attr name="current_currency" type="int">0</attr>
</object>
<object name="orc">
<attr name="experience" type="int">25</attr>
<attr name="currency" type="int">75</attr>
<attr name="dead" type="string">alive</attr>
<attr name="fight" type="script">
// the orc's 3 states:
// orc is alive: orc.dead = "alive"
// orc is dead, but NOT looted yet: orc.dead = "dead_but_not_looted"
// orc is dead AND IS looted: orc.dead = "dead_and_looted"
if (orc.dead = "alive") { // orc is alive
orc.dead = "dead_but_not_looted" // need to actually set the orc as now being dead-but-not-looted-yet
msg ("You fight and kill the orc")
} else if (orc.dead = "dead_but_not_looted") { // orc is dead but not yet looted
player.current_experience = player.current_experience + orc.experience // you loot/get the orc's experience
player.current_currency = player.current_curreny + orc.currency // you loot/get the orc's currency
orc.dead = "dead_and_looted" // need to actually set the orc as now being dead-and-looted
msg ("You loot the corpse of the dead orc")
} else { // if (orc.dead = "dead_and_looted") { // orc is dead and looted
msg ("The orc is already/still dead, and it's already been looted too, silly.")
}
</attr>
</object>
<verb>
<property>fight</property>
<pattern>fight</pattern>
<defaultexpression>You can't fight that!</defaultexpression>
</verb>
- List/Dictionary Attributes:
these enable you to have multiple states at the same time
(too lazy to do some code examples for it though)

Dcoder
15 Aug 2017, 00:27HK is right -- "hit" is a built-in verb.

graveyardtrash
15 Aug 2017, 09:44Thank you everyone. The built in firsttime function helped with my second question - I just wasn't aware that the function was there.
As for the first issue, I think it was the 'hit on' verb causing the problem as Dcoder and hegemonkhan suggested. Might have either clashed with the attack custom verb or a built in verb. Removing 'hit on' from the sequence and adding it as a separate command resolved the issue.
Hooray! Now the player can attempt to seduce some guards to get through an entrance and fail comically!

Dcoder
15 Aug 2017, 10:39Anything for love!
hegemonkhan
17 Aug 2017, 20:04@ graveyardtrash:
some links of some/most of the built-in stuff (Elements and their Attributes, Functions, Scripts / Script Attributes, and other Attributes) you can use:
(all of this stuff is in the GUI/Editor too, but some of it is hard to find within the GUI/Editor... at least for me... easier for me to just code it in directly using these links, lol. I don't use the GUI/Editor for much anymore, now that I've learned to code, hehe)
http://docs.textadventures.co.uk/quest/ (main doc page)
http://docs.textadventures.co.uk/quest/elements/
http://docs.textadventures.co.uk/quest/types/
http://docs.textadventures.co.uk/quest/elements/game.html
http://docs.textadventures.co.uk/quest/elements/object.html
http://docs.textadventures.co.uk/quest/elements/exit.html
http://docs.textadventures.co.uk/quest/scripts/
http://docs.textadventures.co.uk/quest/functions/ (categorical order)
http://docs.textadventures.co.uk/quest/functions/index_allfunctions.html (alpabetical order)
http://docs.textadventures.co.uk/quest/elements/object.html (scroll down to the bottom section, as these are the Object Types / Types for Objects: the container types and other various types)
also:
within the GUI/Editor, in the bottom left corner is:
Filter -> Show library elements -> (toggle this "on" / have the box be checked in) (this is a toggle which hides/reveals the built-in stuff)
which will show/reveal now all the built-in stuff as light grey text in the "tree of stuff" on the left side